From 070dd9f268c0b680b28615d38ca2f4f8454919a8 Mon Sep 17 00:00:00 2001 From: Matti Nannt Date: Fri, 17 Oct 2025 14:58:03 +0200 Subject: [PATCH] chore: remove cloud infrastructure from main repository (#6686) --- .cursor/rules/eks-alb-optimization.mdc | 152 ----- .../workflows/terraform-plan-and-apply.yml | 86 --- .gitignore | 13 - infra/.envrc | 8 - infra/.gitignore | 3 - infra/flake.lock | 61 -- infra/flake.nix | 30 - .../helmfile.yaml.gotmpl | 33 -- .../values-staging.yaml.gotmpl | 91 --- .../formbricks-cloud-helm/values.yaml.gotmpl | 92 --- infra/terraform/.terraform.lock.hcl | 205 ------- infra/terraform/bootstrap.tf | 177 ------ infra/terraform/cloudwatch.tf | 252 --------- infra/terraform/data.tf | 24 - infra/terraform/elasticache.tf | 78 --- infra/terraform/iam.tf | 30 - infra/terraform/main.tf | 533 ------------------ infra/terraform/observability.tf | 136 ----- infra/terraform/provider.tf | 31 - infra/terraform/rds.tf | 79 --- infra/terraform/secrets.tf | 24 - infra/terraform/variables.tf | 1 - infra/terraform/versions.tf | 18 - 23 files changed, 2157 deletions(-) delete mode 100644 .cursor/rules/eks-alb-optimization.mdc delete mode 100644 .github/workflows/terraform-plan-and-apply.yml delete mode 100644 infra/.envrc delete mode 100644 infra/.gitignore delete mode 100644 infra/flake.lock delete mode 100644 infra/flake.nix delete mode 100644 infra/formbricks-cloud-helm/helmfile.yaml.gotmpl delete mode 100644 infra/formbricks-cloud-helm/values-staging.yaml.gotmpl delete mode 100644 infra/formbricks-cloud-helm/values.yaml.gotmpl delete mode 100644 infra/terraform/.terraform.lock.hcl delete mode 100644 infra/terraform/bootstrap.tf delete mode 100644 infra/terraform/cloudwatch.tf delete mode 100644 infra/terraform/data.tf delete mode 100644 infra/terraform/elasticache.tf delete mode 100644 infra/terraform/iam.tf delete mode 100644 infra/terraform/main.tf delete mode 100644 infra/terraform/observability.tf delete mode 100644 infra/terraform/provider.tf delete mode 100644 infra/terraform/rds.tf delete mode 100644 infra/terraform/secrets.tf delete mode 100644 infra/terraform/variables.tf delete mode 100644 infra/terraform/versions.tf diff --git a/.cursor/rules/eks-alb-optimization.mdc b/.cursor/rules/eks-alb-optimization.mdc deleted file mode 100644 index c577e9140c..0000000000 --- a/.cursor/rules/eks-alb-optimization.mdc +++ /dev/null @@ -1,152 +0,0 @@ ---- -description: -globs: -alwaysApply: false ---- -# EKS & ALB Optimization Guide for Error Reduction - -## Infrastructure Overview - -This project uses AWS EKS with Application Load Balancer (ALB) for the Formbricks application. The infrastructure has been optimized to minimize ELB 502/504 errors through careful configuration of connection handling, health checks, and pod lifecycle management. - -## Key Infrastructure Files - -### Terraform Configuration -- **Main Infrastructure**: [infra/terraform/main.tf](mdc:infra/terraform/main.tf) - EKS cluster, VPC, Karpenter, and core AWS resources -- **Monitoring**: [infra/terraform/cloudwatch.tf](mdc:infra/terraform/cloudwatch.tf) - CloudWatch alarms for 502/504 error tracking and alerting -- **Database**: [infra/terraform/rds.tf](mdc:infra/terraform/rds.tf) - Aurora PostgreSQL configuration - -### Helm Configuration -- **Production**: [infra/formbricks-cloud-helm/values.yaml.gotmpl](mdc:infra/formbricks-cloud-helm/values.yaml.gotmpl) - Optimized ALB and pod configurations -- **Staging**: [infra/formbricks-cloud-helm/values-staging.yaml.gotmpl](mdc:infra/formbricks-cloud-helm/values-staging.yaml.gotmpl) - Staging environment with spot instances -- **Deployment**: [infra/formbricks-cloud-helm/helmfile.yaml.gotmpl](mdc:infra/formbricks-cloud-helm/helmfile.yaml.gotmpl) - Multi-environment Helm releases - -## ALB Optimization Patterns - -### Connection Handling Optimizations -```yaml -# Key ALB annotations for reducing 502/504 errors -alb.ingress.kubernetes.io/load-balancer-attributes: | - idle_timeout.timeout_seconds=120, - connection_logs.s3.enabled=false, - access_logs.s3.enabled=false - -alb.ingress.kubernetes.io/target-group-attributes: | - deregistration_delay.timeout_seconds=30, - stickiness.enabled=false, - load_balancing.algorithm.type=least_outstanding_requests, - target_group_health.dns_failover.minimum_healthy_targets.count=1 -``` - -### Health Check Configuration -- **Interval**: 15 seconds for faster detection of unhealthy targets -- **Timeout**: 5 seconds to prevent false positives -- **Thresholds**: 2 healthy, 3 unhealthy for balanced responsiveness -- **Path**: `/health` endpoint optimized for < 100ms response time - -## Pod Lifecycle Management - -### Graceful Shutdown Pattern -```yaml -# PreStop hook to allow connection draining -lifecycle: - preStop: - exec: - command: ["/bin/sh", "-c", "sleep 15"] - -# Termination grace period for complete cleanup -terminationGracePeriodSeconds: 45 -``` - -### Health Probe Strategy -- **Startup Probe**: 5s initial delay, 5s interval, max 60s startup time -- **Readiness Probe**: 10s delay, 10s interval for traffic readiness -- **Liveness Probe**: 30s delay, 30s interval for container health - -### Rolling Update Configuration -```yaml -strategy: - type: RollingUpdate - rollingUpdate: - maxUnavailable: 25% # Maintain capacity during updates - maxSurge: 50% # Allow faster rollouts -``` - -## Karpenter Node Management - -### Node Lifecycle Optimization -- **Startup Taints**: Prevent traffic during node initialization -- **Graceful Shutdown**: 30s grace period for pod eviction -- **Consolidation Delay**: 60s to reduce unnecessary churn -- **Eviction Policies**: Configured for smooth pod migrations - -### Instance Selection -- **Families**: c8g, c7g, m8g, m7g, r8g, r7g (ARM64 Graviton) -- **Sizes**: 2, 4, 8 vCPUs for cost optimization -- **Bottlerocket AMI**: Enhanced security and performance - -## Monitoring & Alerting - -### Critical ALB Metrics -1. **ELB 502 Errors**: Threshold 20 over 5 minutes -2. **ELB 504 Errors**: Threshold 15 over 5 minutes -3. **Target Connection Errors**: Threshold 50 over 5 minutes -4. **4XX Errors**: Threshold 100 over 10 minutes (client issues) - -### Expected Improvements -- **60-80% reduction** in ELB 502 errors -- **Faster recovery** during pod restarts -- **Better connection reuse** efficiency -- **Improved autoscaling** responsiveness - -## Deployment Patterns - -### Infrastructure Updates -1. **Terraform First**: Apply infrastructure changes via [infra/deploy-improvements.sh](mdc:infra/deploy-improvements.sh) -2. **Helm Second**: Deploy application configurations -3. **Verification**: Check pod status, endpoints, and ALB health -4. **Monitoring**: Watch CloudWatch metrics for 24-48 hours - -### Environment-Specific Configurations -- **Production**: On-demand instances, stricter resource limits -- **Staging**: Spot instances, rate limiting disabled, relaxed resources - -## Troubleshooting Patterns - -### 502 Error Investigation -1. Check pod readiness and health probe status -2. Verify ALB target group health -3. Review deregistration timing during deployments -4. Monitor connection pool utilization - -### 504 Error Analysis -1. Check application response times -2. Verify timeout configurations (ALB: 120s, App: aligned) -3. Review database query performance -4. Monitor resource utilization during traffic spikes - -### Connection Error Patterns -1. Verify Karpenter node lifecycle timing -2. Check pod termination grace periods -3. Review ALB connection draining settings -4. Monitor cluster autoscaling events - -## Best Practices - -### When Making Changes -- **Test in staging first** with same configurations -- **Monitor metrics** for 24-48 hours after changes -- **Use gradual rollouts** with proper health checks -- **Maintain ALB timeout alignment** across all layers - -### Performance Optimization -- **Health endpoint** should respond < 100ms consistently -- **Connection pooling** aligned with ALB idle timeouts -- **Resource requests/limits** tuned for consistent performance -- **Graceful shutdown** implemented in application code - -### Monitoring Strategy -- **Real-time alerts** for error rate spikes -- **Trend analysis** for connection patterns -- **Capacity planning** based on LCU usage -- **4XX pattern analysis** for client behavior insights diff --git a/.github/workflows/terraform-plan-and-apply.yml b/.github/workflows/terraform-plan-and-apply.yml deleted file mode 100644 index d805a3cbd6..0000000000 --- a/.github/workflows/terraform-plan-and-apply.yml +++ /dev/null @@ -1,86 +0,0 @@ -name: "Terraform" - -on: - workflow_dispatch: - # TODO: enable it back when migration is completed. - push: - branches: - - main - paths: - - "infra/terraform/**" - pull_request: - branches: - - main - paths: - - "infra/terraform/**" - -permissions: - contents: read - -jobs: - terraform: - runs-on: ubuntu-latest - permissions: - id-token: write - pull-requests: write - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - name: Checkout - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - - name: Tailscale - uses: tailscale/github-action@84a3f23bb4d843bcf4da6cf824ec1be473daf4de # v3.2.3 - with: - oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }} - oauth-secret: ${{ secrets.TS_OAUTH_SECRET }} - tags: tag:github - - - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@f24d7193d98baebaeacc7e2227925dd47cc267f5 # v4.2.0 - with: - role-to-assume: ${{ secrets.AWS_ASSUME_ROLE_ARN }} - aws-region: "eu-central-1" - - - name: Setup Terraform - uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2 - - - name: Terraform Format - id: fmt - run: terraform fmt -check -recursive - continue-on-error: true - working-directory: infra/terraform - - - name: Terraform Init - id: init - run: terraform init - working-directory: infra/terraform - - - name: Terraform Validate - id: validate - run: terraform validate - working-directory: infra/terraform - - - name: Terraform Plan - id: plan - run: terraform plan -out .planfile - working-directory: infra/terraform - - - name: Post PR comment - uses: borchero/terraform-plan-comment@434458316f8f24dd073cd2561c436cce41dc8f34 # v2.4.1 - if: always() && github.ref != 'refs/heads/main' && (steps.plan.outcome == 'success' || steps.plan.outcome == 'failure') - with: - token: ${{ github.token }} - planfile: .planfile - working-directory: "infra/terraform" - - - name: Terraform Apply - id: apply - if: github.ref == 'refs/heads/main' && github.event_name == 'push' - run: terraform apply .planfile - working-directory: "infra/terraform" diff --git a/.gitignore b/.gitignore index 613e0dfeb3..9851c92a52 100644 --- a/.gitignore +++ b/.gitignore @@ -56,19 +56,6 @@ packages/database/migrations branch.json .vercel -# Terraform -infra/terraform/.terraform/ -**/.terraform.lock.hcl -**/terraform.tfstate -**/terraform.tfstate.* -**/crash.log -**/override.tf -**/override.tf.json -**/*.tfvars -**/*.tfvars.json -**/.terraformrc -**/terraform.rc - # IntelliJ IDEA /.idea/ /*.iml diff --git a/infra/.envrc b/infra/.envrc deleted file mode 100644 index 6aebd4a312..0000000000 --- a/infra/.envrc +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash - -# This is a better (faster) alternative to the built-in Nix support -if ! has nix_direnv_version || ! nix_direnv_version 3.0.4; then - source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/3.0.4/direnvrc" "sha256-DzlYZ33mWF/Gs8DDeyjr8mnVmQGx7ASYqA5WlxwvBG4=" -fi - -use flake diff --git a/infra/.gitignore b/infra/.gitignore deleted file mode 100644 index 7a191bc65a..0000000000 --- a/infra/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.terraform/ -builds -/.direnv/ diff --git a/infra/flake.lock b/infra/flake.lock deleted file mode 100644 index 15c04e44d7..0000000000 --- a/infra/flake.lock +++ /dev/null @@ -1,61 +0,0 @@ -{ - "nodes": { - "flake-utils": { - "inputs": { - "systems": "systems" - }, - "locked": { - "lastModified": 1731533236, - "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "nixpkgs": { - "locked": { - "lastModified": 1754767907, - "narHash": "sha256-8OnUzRQZkqtUol9vuUuQC30hzpMreKptNyET2T9lB6g=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "c5f08b62ed75415439d48152c2a784e36909b1bc", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-25.05", - "repo": "nixpkgs", - "type": "github" - } - }, - "root": { - "inputs": { - "flake-utils": "flake-utils", - "nixpkgs": "nixpkgs" - } - }, - "systems": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - } - }, - "root": "root", - "version": 7 -} diff --git a/infra/flake.nix b/infra/flake.nix deleted file mode 100644 index da44fd60d8..0000000000 --- a/infra/flake.nix +++ /dev/null @@ -1,30 +0,0 @@ -{ - inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05"; - flake-utils.url = "github:numtide/flake-utils"; - }; - outputs = - { - self, - nixpkgs, - flake-utils, - }: - flake-utils.lib.eachDefaultSystem ( - system: - let - pkgs = import nixpkgs { - inherit system; - config.allowUnfree = true; - }; - in - with pkgs; - { - devShells.default = mkShell { - buildInputs = [ - awscli - terraform - ]; - }; - } - ); -} diff --git a/infra/formbricks-cloud-helm/helmfile.yaml.gotmpl b/infra/formbricks-cloud-helm/helmfile.yaml.gotmpl deleted file mode 100644 index f89792787b..0000000000 --- a/infra/formbricks-cloud-helm/helmfile.yaml.gotmpl +++ /dev/null @@ -1,33 +0,0 @@ -repositories: - - name: helm-charts - url: ghcr.io/formbricks/helm-charts - oci: true - -releases: - - name: formbricks - namespace: formbricks - chart: helm-charts/formbricks - version: ^3.0.0 - values: - - values.yaml.gotmpl - set: - - name: deployment.image.tag - value: {{ requiredEnv "VERSION" }} - - name: deployment.image.repository - value: {{ requiredEnv "REPOSITORY" }} - labels: - environment: prod - - name: formbricks-stage - namespace: formbricks-stage - chart: helm-charts/formbricks - version: ^3.0.0 - values: - - values-staging.yaml.gotmpl - createNamespace: true - set: - - name: deployment.image.tag - value: {{ requiredEnv "VERSION" }} - - name: deployment.image.repository - value: {{ requiredEnv "REPOSITORY" }} - labels: - environment: stage diff --git a/infra/formbricks-cloud-helm/values-staging.yaml.gotmpl b/infra/formbricks-cloud-helm/values-staging.yaml.gotmpl deleted file mode 100644 index 6b45a19fb3..0000000000 --- a/infra/formbricks-cloud-helm/values-staging.yaml.gotmpl +++ /dev/null @@ -1,91 +0,0 @@ -nameOverride: "formbricks-stage" -## Deployment & Autoscaling -deployment: - image: - pullPolicy: Always - resources: - limits: - cpu: 2 - memory: 2Gi - requests: - cpu: 1 - memory: 1Gi - env: - RATE_LIMITING_DISABLED: - value: "1" - envFrom: - app-env: - nameSuffix: app-env - type: secret - nodeSelector: - karpenter.sh/capacity-type: spot - reloadOnChange: true -autoscaling: - enabled: true - maxReplicas: 95 - minReplicas: 3 - metrics: - - resource: - name: cpu - target: - averageUtilization: 60 - type: Utilization - type: Resource - - resource: - name: memory - target: - averageUtilization: 60 - type: Utilization - type: Resource - -### Secrets -secret: - enabled: false -externalSecret: - enabled: true - files: - app-env: - dataFrom: - key: stage/formbricks/environment - app-secrets: - dataFrom: - key: stage/formbricks/secrets - refreshInterval: 1m - secretStore: - kind: ClusterSecretStore - name: aws-secrets-manager - -## Ingress -ingress: - annotations: - alb.ingress.kubernetes.io/certificate-arn: {{ requiredEnv "FORMBRICKS_INGRESS_CERT_ARN" }} - alb.ingress.kubernetes.io/group.name: internal - alb.ingress.kubernetes.io/healthcheck-path: /health - alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS": 443}]' - alb.ingress.kubernetes.io/ssl-policy: ELBSecurityPolicy-TLS13-1-2-Res-2021-06 - alb.ingress.kubernetes.io/ssl-redirect: "443" - alb.ingress.kubernetes.io/target-type: ip - enabled: true - hosts: - - host: stage.app.formbricks.com - paths: - - path: / - pathType: Prefix - serviceName: formbricks-stage - ingressClassName: alb - -## RBAC -rbac: - enabled: true - serviceAccount: - annotations: - eks.amazonaws.com/role-arn: {{ requiredEnv "FORMBRICKS_ROLE_ARN" }} - additionalLabels: {} - enabled: true - name: formbricks-stage - -## Dependencies -postgresql: - enabled: false -redis: - enabled: false diff --git a/infra/formbricks-cloud-helm/values.yaml.gotmpl b/infra/formbricks-cloud-helm/values.yaml.gotmpl deleted file mode 100644 index 3004f1a749..0000000000 --- a/infra/formbricks-cloud-helm/values.yaml.gotmpl +++ /dev/null @@ -1,92 +0,0 @@ -## Deployment & Autoscaling -deployment: - resources: - limits: - memory: 2Gi - requests: - cpu: 1 - memory: 1Gi - env: {} - envFrom: - app-env: - nameSuffix: app-env - type: secret - nodeSelector: - karpenter.sh/capacity-type: on-demand - reloadOnChange: true -autoscaling: - enabled: true - maxReplicas: 95 - minReplicas: 3 - metrics: - - resource: - name: cpu - target: - averageUtilization: 60 - type: Utilization - type: Resource - - resource: - name: memory - target: - averageUtilization: 60 - type: Utilization - type: Resource - -### Secrets -secret: - enabled: false -externalSecret: - enabled: true - files: - app-env: - dataFrom: - key: prod/formbricks/environment - app-secrets: - dataFrom: - key: prod/formbricks/secrets - refreshInterval: 1m - secretStore: - kind: ClusterSecretStore - name: aws-secrets-manager - -## Ingress -ingress: - annotations: - alb.ingress.kubernetes.io/certificate-arn: {{ requiredEnv "FORMBRICKS_INGRESS_CERT_ARN" }} - alb.ingress.kubernetes.io/group.name: formbricks - alb.ingress.kubernetes.io/healthcheck-path: /health - alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS": 443}]' - alb.ingress.kubernetes.io/scheme: internet-facing - alb.ingress.kubernetes.io/ssl-policy: ELBSecurityPolicy-TLS13-1-2-2021-06 - alb.ingress.kubernetes.io/load-balancer-attributes: idle_timeout.timeout_seconds=600,client_keep_alive.seconds=590 - alb.ingress.kubernetes.io/ssl-redirect: "443" - alb.ingress.kubernetes.io/target-type: ip - enabled: true - hosts: - - host: app.k8s.formbricks.com - paths: - - path: / - pathType: Prefix - serviceName: formbricks - - host: app.formbricks.com - paths: - - path: / - pathType: Prefix - serviceName: formbricks - ingressClassName: alb - -## RBAC -rbac: - enabled: true - serviceAccount: - annotations: - eks.amazonaws.com/role-arn: {{ requiredEnv "FORMBRICKS_ROLE_ARN" }} - additionalLabels: {} - enabled: true - name: formbricks - -## Dependencies -postgresql: - enabled: false -redis: - enabled: false diff --git a/infra/terraform/.terraform.lock.hcl b/infra/terraform/.terraform.lock.hcl deleted file mode 100644 index 4ceb470e16..0000000000 --- a/infra/terraform/.terraform.lock.hcl +++ /dev/null @@ -1,205 +0,0 @@ -# This file is maintained automatically by "terraform init". -# Manual edits may be lost in future updates. - -provider "registry.terraform.io/hashicorp/aws" { - version = "5.100.0" - constraints = ">= 3.29.0, >= 4.0.0, >= 4.8.0, >= 4.33.0, >= 4.36.0, >= 4.47.0, >= 4.63.0, >= 5.0.0, >= 5.46.0, >= 5.73.0, >= 5.79.0, >= 5.81.0, >= 5.83.0, >= 5.86.0, >= 5.95.0, < 6.0.0" - hashes = [ - "h1:Ijt7pOlB7Tr7maGQIqtsLFbl7pSMIj06TVdkoSBcYOw=", - "zh:054b8dd49f0549c9a7cc27d159e45327b7b65cf404da5e5a20da154b90b8a644", - "zh:0b97bf8d5e03d15d83cc40b0530a1f84b459354939ba6f135a0086c20ebbe6b2", - "zh:1589a2266af699cbd5d80737a0fe02e54ec9cf2ca54e7e00ac51c7359056f274", - "zh:6330766f1d85f01ae6ea90d1b214b8b74cc8c1badc4696b165b36ddd4cc15f7b", - "zh:7c8c2e30d8e55291b86fcb64bdf6c25489d538688545eb48fd74ad622e5d3862", - "zh:99b1003bd9bd32ee323544da897148f46a527f622dc3971af63ea3e251596342", - "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", - "zh:9f8b909d3ec50ade83c8062290378b1ec553edef6a447c56dadc01a99f4eaa93", - "zh:aaef921ff9aabaf8b1869a86d692ebd24fbd4e12c21205034bb679b9caf883a2", - "zh:ac882313207aba00dd5a76dbd572a0ddc818bb9cbf5c9d61b28fe30efaec951e", - "zh:bb64e8aff37becab373a1a0cc1080990785304141af42ed6aa3dd4913b000421", - "zh:dfe495f6621df5540d9c92ad40b8067376350b005c637ea6efac5dc15028add4", - "zh:f0ddf0eaf052766cfe09dea8200a946519f653c384ab4336e2a4a64fdd6310e9", - "zh:f1b7e684f4c7ae1eed272b6de7d2049bb87a0275cb04dbb7cda6636f600699c9", - "zh:ff461571e3f233699bf690db319dfe46aec75e58726636a0d97dd9ac6e32fb70", - ] -} - -provider "registry.terraform.io/hashicorp/cloudinit" { - version = "2.3.7" - constraints = ">= 2.0.0" - hashes = [ - "h1:M9TpQxKAE/hyOwytdX9MUNZw30HoD/OXqYIug5fkqH8=", - "zh:06f1c54e919425c3139f8aeb8fcf9bceca7e560d48c9f0c1e3bb0a8ad9d9da1e", - "zh:0e1e4cf6fd98b019e764c28586a386dc136129fef50af8c7165a067e7e4a31d5", - "zh:1871f4337c7c57287d4d67396f633d224b8938708b772abfc664d1f80bd67edd", - "zh:2b9269d91b742a71b2248439d5e9824f0447e6d261bfb86a8a88528609b136d1", - "zh:3d8ae039af21426072c66d6a59a467d51f2d9189b8198616888c1b7fc42addc7", - "zh:3ef4e2db5bcf3e2d915921adced43929214e0946a6fb11793085d9a48995ae01", - "zh:42ae54381147437c83cbb8790cc68935d71b6357728a154109d3220b1beb4dc9", - "zh:4496b362605ae4cbc9ef7995d102351e2fe311897586ffc7a4a262ccca0c782a", - "zh:652a2401257a12706d32842f66dac05a735693abcb3e6517d6b5e2573729ba13", - "zh:7406c30806f5979eaed5f50c548eced2ea18ea121e01801d2f0d4d87a04f6a14", - "zh:7848429fd5a5bcf35f6fee8487df0fb64b09ec071330f3ff240c0343fe2a5224", - "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", - ] -} - -provider "registry.terraform.io/hashicorp/external" { - version = "2.3.5" - constraints = ">= 1.0.0" - hashes = [ - "h1:FnUk98MI5nOh3VJ16cHf8mchQLewLfN1qZG/MqNgPrI=", - "zh:6e89509d056091266532fa64de8c06950010498adf9070bf6ff85bc485a82562", - "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", - "zh:86868aec05b58dc0aa1904646a2c26b9367d69b890c9ad70c33c0d3aa7b1485a", - "zh:a2ce38fda83a62fa5fb5a70e6ca8453b168575feb3459fa39803f6f40bd42154", - "zh:a6c72798f4a9a36d1d1433c0372006cc9b904e8cfd60a2ae03ac5b7d2abd2398", - "zh:a8a3141d2fc71c86bf7f3c13b0b3be8a1b0f0144a47572a15af4dfafc051e28a", - "zh:aa20a1242eb97445ad26ebcfb9babf2cd675bdb81cac5f989268ebefa4ef278c", - "zh:b58a22445fb8804e933dcf835ab06c29a0f33148dce61316814783ee7f4e4332", - "zh:cb5626a661ee761e0576defb2a2d75230a3244799d380864f3089c66e99d0dcc", - "zh:d1acb00d20445f682c4e705c965e5220530209c95609194c2dc39324f3d4fcce", - "zh:d91a254ba77b69a29d8eae8ed0e9367cbf0ea6ac1a85b58e190f8cb096a40871", - "zh:f6592327673c9f85cdb6f20336faef240abae7621b834f189c4a62276ea5db41", - ] -} - -provider "registry.terraform.io/hashicorp/helm" { - version = "2.17.0" - constraints = ">= 2.9.0, ~> 2.17, < 3.0.0" - hashes = [ - "h1:kQMkcPVvHOguOqnxoEU2sm1ND9vCHiT8TvZ2x6v/Rsw=", - "zh:06fb4e9932f0afc1904d2279e6e99353c2ddac0d765305ce90519af410706bd4", - "zh:104eccfc781fc868da3c7fec4385ad14ed183eb985c96331a1a937ac79c2d1a7", - "zh:129345c82359837bb3f0070ce4891ec232697052f7d5ccf61d43d818912cf5f3", - "zh:3956187ec239f4045975b35e8c30741f701aa494c386aaa04ebabffe7749f81c", - "zh:66a9686d92a6b3ec43de3ca3fde60ef3d89fb76259ed3313ca4eb9bb8c13b7dd", - "zh:88644260090aa621e7e8083585c468c8dd5e09a3c01a432fb05da5c4623af940", - "zh:a248f650d174a883b32c5b94f9e725f4057e623b00f171936dcdcc840fad0b3e", - "zh:aa498c1f1ab93be5c8fbf6d48af51dc6ef0f10b2ea88d67bcb9f02d1d80d3930", - "zh:bf01e0f2ec2468c53596e027d376532a2d30feb72b0b5b810334d043109ae32f", - "zh:c46fa84cc8388e5ca87eb575a534ebcf68819c5a5724142998b487cb11246654", - "zh:d0c0f15ffc115c0965cbfe5c81f18c2e114113e7a1e6829f6bfd879ce5744fbb", - "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", - ] -} - -provider "registry.terraform.io/hashicorp/kubernetes" { - version = "2.38.0" - constraints = ">= 2.20.0, ~> 2.36" - hashes = [ - "h1:soK8Lt0SZ6dB+HsypFRDzuX/npqlMU6M0fvyaR1yW0k=", - "zh:0af928d776eb269b192dc0ea0f8a3f0f5ec117224cd644bdacdc682300f84ba0", - "zh:1be998e67206f7cfc4ffe77c01a09ac91ce725de0abaec9030b22c0a832af44f", - "zh:326803fe5946023687d603f6f1bab24de7af3d426b01d20e51d4e6fbe4e7ec1b", - "zh:4a99ec8d91193af961de1abb1f824be73df07489301d62e6141a656b3ebfff12", - "zh:5136e51765d6a0b9e4dbcc3b38821e9736bd2136cf15e9aac11668f22db117d2", - "zh:63fab47349852d7802fb032e4f2b6a101ee1ce34b62557a9ad0f0f0f5b6ecfdc", - "zh:924fb0257e2d03e03e2bfe9c7b99aa73c195b1f19412ca09960001bee3c50d15", - "zh:b63a0be5e233f8f6727c56bed3b61eb9456ca7a8bb29539fba0837f1badf1396", - "zh:d39861aa21077f1bc899bc53e7233262e530ba8a3a2d737449b100daeb303e4d", - "zh:de0805e10ebe4c83ce3b728a67f6b0f9d18be32b25146aa89116634df5145ad4", - "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", - "zh:faf23e45f0090eef8ba28a8aac7ec5d4fdf11a36c40a8d286304567d71c1e7db", - ] -} - -provider "registry.terraform.io/hashicorp/local" { - version = "2.5.3" - constraints = ">= 1.0.0" - hashes = [ - "h1:MCzg+hs1/ZQ32u56VzJMWP9ONRQPAAqAjuHuzbyshvI=", - "zh:284d4b5b572eacd456e605e94372f740f6de27b71b4e1fd49b63745d8ecd4927", - "zh:40d9dfc9c549e406b5aab73c023aa485633c1b6b730c933d7bcc2fa67fd1ae6e", - "zh:6243509bb208656eb9dc17d3c525c89acdd27f08def427a0dce22d5db90a4c8b", - "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", - "zh:885d85869f927853b6fe330e235cd03c337ac3b933b0d9ae827ec32fa1fdcdbf", - "zh:bab66af51039bdfcccf85b25fe562cbba2f54f6b3812202f4873ade834ec201d", - "zh:c505ff1bf9442a889ac7dca3ac05a8ee6f852e0118dd9a61796a2f6ff4837f09", - "zh:d36c0b5770841ddb6eaf0499ba3de48e5d4fc99f4829b6ab66b0fab59b1aaf4f", - "zh:ddb6a407c7f3ec63efb4dad5f948b54f7f4434ee1a2607a49680d494b1776fe1", - "zh:e0dafdd4500bec23d3ff221e3a9b60621c5273e5df867bc59ef6b7e41f5c91f6", - "zh:ece8742fd2882a8fc9d6efd20e2590010d43db386b920b2a9c220cfecc18de47", - "zh:f4c6b3eb8f39105004cf720e202f04f57e3578441cfb76ca27611139bc116a82", - ] -} - -provider "registry.terraform.io/hashicorp/null" { - version = "3.2.4" - constraints = ">= 2.0.0, >= 3.0.0" - hashes = [ - "h1:L5V05xwp/Gto1leRryuesxjMfgZwjb7oool4WS1UEFQ=", - "zh:59f6b52ab4ff35739647f9509ee6d93d7c032985d9f8c6237d1f8a59471bbbe2", - "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", - "zh:795c897119ff082133150121d39ff26cb5f89a730a2c8c26f3a9c1abf81a9c43", - "zh:7b9c7b16f118fbc2b05a983817b8ce2f86df125857966ad356353baf4bff5c0a", - "zh:85e33ab43e0e1726e5f97a874b8e24820b6565ff8076523cc2922ba671492991", - "zh:9d32ac3619cfc93eb3c4f423492a8e0f79db05fec58e449dee9b2d5873d5f69f", - "zh:9e15c3c9dd8e0d1e3731841d44c34571b6c97f5b95e8296a45318b94e5287a6e", - "zh:b4c2ab35d1b7696c30b64bf2c0f3a62329107bd1a9121ce70683dec58af19615", - "zh:c43723e8cc65bcdf5e0c92581dcbbdcbdcf18b8d2037406a5f2033b1e22de442", - "zh:ceb5495d9c31bfb299d246ab333f08c7fb0d67a4f82681fbf47f2a21c3e11ab5", - "zh:e171026b3659305c558d9804062762d168f50ba02b88b231d20ec99578a6233f", - "zh:ed0fe2acdb61330b01841fa790be00ec6beaac91d41f311fb8254f74eb6a711f", - ] -} - -provider "registry.terraform.io/hashicorp/random" { - version = "3.7.2" - constraints = ">= 2.0.0, >= 3.6.0" - hashes = [ - "h1:KG4NuIBl1mRWU0KD/BGfCi1YN/j3F7H4YgeeM7iSdNs=", - "zh:14829603a32e4bc4d05062f059e545a91e27ff033756b48afbae6b3c835f508f", - "zh:1527fb07d9fea400d70e9e6eb4a2b918d5060d604749b6f1c361518e7da546dc", - "zh:1e86bcd7ebec85ba336b423ba1db046aeaa3c0e5f921039b3f1a6fc2f978feab", - "zh:24536dec8bde66753f4b4030b8f3ef43c196d69cccbea1c382d01b222478c7a3", - "zh:29f1786486759fad9b0ce4fdfbbfece9343ad47cd50119045075e05afe49d212", - "zh:4d701e978c2dd8604ba1ce962b047607701e65c078cb22e97171513e9e57491f", - "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", - "zh:7b8434212eef0f8c83f5a90c6d76feaf850f6502b61b53c329e85b3b281cba34", - "zh:ac8a23c212258b7976e1621275e3af7099e7e4a3d4478cf8d5d2a27f3bc3e967", - "zh:b516ca74431f3df4c6cf90ddcdb4042c626e026317a33c53f0b445a3d93b720d", - "zh:dc76e4326aec2490c1600d6871a95e78f9050f9ce427c71707ea412a2f2f1a62", - "zh:eac7b63e86c749c7d48f527671c7aee5b4e26c10be6ad7232d6860167f99dbb0", - ] -} - -provider "registry.terraform.io/hashicorp/time" { - version = "0.13.1" - constraints = ">= 0.9.0" - hashes = [ - "h1:ZT5ppCNIModqk3iOkVt5my8b8yBHmDpl663JtXAIRqM=", - "zh:02cb9aab1002f0f2a94a4f85acec8893297dc75915f7404c165983f720a54b74", - "zh:04429b2b31a492d19e5ecf999b116d396dac0b24bba0d0fb19ecaefe193fdb8f", - "zh:26f8e51bb7c275c404ba6028c1b530312066009194db721a8427a7bc5cdbc83a", - "zh:772ff8dbdbef968651ab3ae76d04afd355c32f8a868d03244db3f8496e462690", - "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", - "zh:898db5d2b6bd6ca5457dccb52eedbc7c5b1a71e4a4658381bcbb38cedbbda328", - "zh:8de913bf09a3fa7bedc29fec18c47c571d0c7a3d0644322c46f3aa648cf30cd8", - "zh:9402102c86a87bdfe7e501ffbb9c685c32bbcefcfcf897fd7d53df414c36877b", - "zh:b18b9bb1726bb8cfbefc0a29cf3657c82578001f514bcf4c079839b6776c47f0", - "zh:b9d31fdc4faecb909d7c5ce41d2479dd0536862a963df434be4b16e8e4edc94d", - "zh:c951e9f39cca3446c060bd63933ebb89cedde9523904813973fbc3d11863ba75", - "zh:e5b773c0d07e962291be0e9b413c7a22c044b8c7b58c76e8aa91d1659990dfb5", - ] -} - -provider "registry.terraform.io/hashicorp/tls" { - version = "4.1.0" - constraints = ">= 3.0.0" - hashes = [ - "h1:zEv9tY1KR5vaLSyp2lkrucNJ+Vq3c+sTFK9GyQGLtFs=", - "zh:14c35d89307988c835a7f8e26f1b83ce771e5f9b41e407f86a644c0152089ac2", - "zh:2fb9fe7a8b5afdbd3e903acb6776ef1be3f2e587fb236a8c60f11a9fa165faa8", - "zh:35808142ef850c0c60dd93dc06b95c747720ed2c40c89031781165f0c2baa2fc", - "zh:35b5dc95bc75f0b3b9c5ce54d4d7600c1ebc96fbb8dfca174536e8bf103c8cdc", - "zh:38aa27c6a6c98f1712aa5cc30011884dc4b128b4073a4a27883374bfa3ec9fac", - "zh:51fb247e3a2e88f0047cb97bb9df7c228254a3b3021c5534e4563b4007e6f882", - "zh:62b981ce491e38d892ba6364d1d0cdaadcee37cc218590e07b310b1dfa34be2d", - "zh:bc8e47efc611924a79f947ce072a9ad698f311d4a60d0b4dfff6758c912b7298", - "zh:c149508bd131765d1bc085c75a870abb314ff5a6d7f5ac1035a8892d686b6297", - "zh:d38d40783503d278b63858978d40e07ac48123a2925e1a6b47e62179c046f87a", - "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", - "zh:fb07f708e3316615f6d218cec198504984c0ce7000b9f1eebff7516e384f4b54", - ] -} diff --git a/infra/terraform/bootstrap.tf b/infra/terraform/bootstrap.tf deleted file mode 100644 index d0ebcb374a..0000000000 --- a/infra/terraform/bootstrap.tf +++ /dev/null @@ -1,177 +0,0 @@ -# ################################################################################ -# # GitOps Bridge: Bootstrap -# ################################################################################ -# locals { -# addons = { -# enable_cert_manager = true -# enable_external_dns = true -# enable_istio = false -# enable_istio_ingress = false -# enable_external_secrets = true -# enable_metrics_server = false -# enable_keda = false -# enable_aws_load_balancer_controller = true -# enable_aws_ebs_csi_resources = false -# enable_velero = false -# enable_observability = false -# enable_karpenter = true -# } -# -# addons_default_versions = { -# cert_manager = "v1.17.1" -# external_dns = "1.15.2" -# karpenter = "1.3.0" -# external_secrets = "0.14.3" -# aws_load_balancer_controller = "1.10.0" -# # keda = "2.16.0" -# # istio = "1.23.3" -# } -# -# addons_metadata = merge( -# # module.addons.gitops_metadata -# { -# aws_cluster_name = module.eks.cluster_name -# aws_region = data.aws_region.selected.name -# aws_account_id = data.aws_caller_identity.current.account_id -# aws_vpc_id = module.vpc.vpc_id -# } -# ) -# -# argocd_apps = { -# eks-addons = { -# project = "default" -# repo_url = var.addons_repo_url -# target_revision = var.addons_target_revision -# addons_repo_revision = var.addons_target_revision -# path = var.addons_repo_path -# values = merge({ -# addons_repo_revision = var.addons_target_revision -# certManager = { -# enabled = local.addons.enable_cert_manager -# iamRoleArn = try(module.addons.gitops_metadata.cert_manager_iam_role_arn, "") -# values = try(yamldecode(join("\n", var.cert_manager_helm_config.values)), {}) -# chartVersion = try(var.cert_manager_helm_config.chart_version, local.addons_default_versions.cert_manager) -# } -# externalDNS = { -# enabled = local.addons.enable_external_dns -# iamRoleArn = try(module.addons.gitops_metadata.external_dns_iam_role_arn, "") -# values = try(yamldecode(join("\n", var.external_dns_helm_config.values)), {}) -# chartVersion = try(var.external_dns_helm_config.chart_version, local.addons_default_versions.external_dns) -# } -# externalSecrets = { -# enabled = local.addons.enable_external_secrets -# iamRoleArn = try(module.addons.gitops_metadata.external_secrets_iam_role_arn, "") -# values = try(yamldecode(join("\n", var.external_secrets_helm_config.values)), {}) -# chartVersion = try(var.external_secrets_helm_config.chart_version, local.addons_default_versions.external_secrets) -# } -# karpenter = { -# enabled = true -# iamRoleArn = try(module.addons.gitops_metadata.karpenter_iam_role_arn, "") -# values = try(yamldecode(join("\n", var.karpenter_helm_config.values)), {}) -# chartVersion = try(var.karpenter_helm_config.chart_version, local.addons_default_versions.karpenter) -# enableCrdWebhookConfig = true -# clusterName = module.eks.cluster_name -# clusterEndpoint = module.eks.cluster_endpoint -# interruptionQueue = try(module.addons.gitops_metadata.karpenter_interruption_queue, null) -# nodeIamRoleName = try(module.addons.gitops_metadata.karpenter_node_iam_role_arn, null) -# } -# loadBalancerController = { -# enabled = local.addons.enable_aws_load_balancer_controller -# iamRoleArn = try(module.addons.gitops_metadata.aws_load_balancer_controller_iam_role_arn, "") -# values = try(yamldecode(join("\n", var.aws_load_balancer_controller_helm_config.values)), {}) -# clusterName = module.eks.cluster_name -# chartVersion = try(var.aws_load_balancer_controller_helm_config.chart_version, local.addons_default_versions.aws_load_balancer_controller) -# vpcId = module.vpc.vpc_id -# } -# }) -# } -# workloads = { -# project = "default" -# repo_url = var.workloads_repo_url -# target_revision = var.workloads_target_revision -# addons_repo_revision = var.workloads_target_revision -# path = var.workloads_repo_path -# values = merge({ -# addons_repo_revision = var.workloads_target_revision -# formbricks = { -# certificateArn = try(module.acm.acm_certificate_arn, "") -# ingressHost = "app.k8s.formbricks.com" -# env = { -# TEST = { -# value = "test " -# } -# } -# } -# }) -# } -# } -# } -# -# variable "enable_gitops_bridge_bootstrap" { -# default = true -# } -# -# module "gitops_bridge_bootstrap" { -# count = var.enable_gitops_bridge_bootstrap ? 1 : 0 -# source = "../modules/argocd-gitops-bridge" -# -# cluster = { -# metadata = local.addons_metadata -# } -# argocd = { -# chart_version = "7.8.7" -# values = [ -# <<-EOT -# global: -# nodeSelector: -# CriticalAddonsOnly: "true" -# tolerations: -# - key: "CriticalAddonsOnly" -# operator: "Exists" -# effect: "NoSchedule" -# configs: -# params: -# server.insecure: true -# EOT -# ] -# } -# apps = local.argocd_apps -# } -# -# ############################################################################### -# # EKS Blueprints Addons -# ############################################################################### -# module "addons" { -# source = "../modules/addons" -# oidc_provider_arn = module.eks.oidc_provider_arn -# aws_region = data.aws_region.selected.name -# aws_account_id = data.aws_caller_identity.current.account_id -# aws_partition = data.aws_partition.current.partition -# cluster_name = module.eks.cluster_name -# cluster_endpoint = module.eks.cluster_endpoint -# cluster_certificate_authority_data = module.eks.cluster_certificate_authority_data -# cluster_token = data.aws_eks_cluster_auth.eks.token -# cluster_version = module.eks.cluster_version -# vpc_id = module.vpc.vpc_id -# node_security_group_id = module.eks.node_security_group_id -# cluster_security_group_id = module.eks.cluster_security_group_id -# -# # Using GitOps Bridge -# create_kubernetes_resources = var.enable_gitops_bridge_bootstrap ? false : true -# -# # Cert Manager -# enable_cert_manager = local.addons.enable_cert_manager -# -# # External DNS -# enable_external_dns = local.addons.enable_external_dns -# -# # Karpenter -# enable_karpenter = local.addons.enable_karpenter -# -# # External Secrets -# enable_external_secrets = local.addons.enable_external_secrets -# -# # Load Balancer Controller -# enable_aws_load_balancer_controller = local.addons.enable_aws_load_balancer_controller -# -# } diff --git a/infra/terraform/cloudwatch.tf b/infra/terraform/cloudwatch.tf deleted file mode 100644 index 7803ebb4c6..0000000000 --- a/infra/terraform/cloudwatch.tf +++ /dev/null @@ -1,252 +0,0 @@ -data "aws_ssm_parameter" "slack_notification_channel" { - name = "/prod/formbricks/slack-webhook-url" - with_decryption = true -} - -resource "aws_cloudwatch_log_group" "cloudwatch_cis_benchmark" { - name = "/aws/cis-benchmark-group" - retention_in_days = 365 -} - -module "notify-slack" { - source = "terraform-aws-modules/notify-slack/aws" - version = "6.6.0" - - slack_channel = "kubernetes" - slack_username = "formbricks-cloudwatch" - slack_webhook_url = data.aws_ssm_parameter.slack_notification_channel.value - sns_topic_name = "cloudwatch-alarms" - create_sns_topic = true -} - -module "cloudwatch_cis-alarms" { - source = "terraform-aws-modules/cloudwatch/aws//modules/cis-alarms" - version = "5.7.1" - log_group_name = aws_cloudwatch_log_group.cloudwatch_cis_benchmark.name - alarm_actions = [module.notify-slack.slack_topic_arn] -} - -locals { - alb_id = "app/k8s-formbricks-21ab9ecd60/342ed65d128ce4cb" - alarms = { - ALB_HTTPCode_Target_5XX_Count = { - alarm_description = "Average API 5XX target group error code count is too high" - comparison_operator = "GreaterThanThreshold" - evaluation_periods = 5 - threshold = 5 - period = 600 - unit = "Count" - namespace = "AWS/ApplicationELB" - metric_name = "HTTPCode_Target_5XX_Count" - statistic = "Sum" - dimensions = { - LoadBalancer = local.alb_id - } - } - ALB_HTTPCode_ELB_5XX_Count = { - alarm_description = "Average API 5XX load balancer error code count is too high" - comparison_operator = "GreaterThanThreshold" - evaluation_periods = 5 - threshold = 10 - period = 600 - unit = "Count" - namespace = "AWS/ApplicationELB" - metric_name = "HTTPCode_ELB_5XX_Count" - statistic = "Sum" - dimensions = { - LoadBalancer = local.alb_id - } - } - ALB_TargetResponseTime = { - alarm_description = format("Average API response time is greater than %s", 5) - comparison_operator = "GreaterThanThreshold" - evaluation_periods = 5 - threshold = 5 - period = 60 - unit = "Seconds" - namespace = "AWS/ApplicationELB" - metric_name = "TargetResponseTime" - statistic = "Average" - dimensions = { - LoadBalancer = local.alb_id - } - } - ALB_UnHealthyHostCount = { - alarm_description = format("Unhealthy host count is greater than %s", 2) - comparison_operator = "GreaterThanThreshold" - evaluation_periods = 5 - threshold = 2 - period = 60 - unit = "Count" - namespace = "AWS/ApplicationELB" - metric_name = "UnHealthyHostCount" - statistic = "Minimum" - dimensions = { - LoadBalancer = local.alb_id - } - } - RDS_CPUUtilization = { - alarm_description = format("Average RDS CPU utilization is greater than %s", 80) - comparison_operator = "GreaterThanThreshold" - evaluation_periods = 5 - threshold = 80 - period = 60 - unit = "Percent" - namespace = "AWS/RDS" - metric_name = "CPUUtilization" - statistic = "Average" - dimensions = { - DBInstanceIdentifier = module.rds-aurora["prod"].cluster_instances["one"].id - } - } - RDS_FreeStorageSpace = { - alarm_description = format("Average RDS free storage space is less than %s", 5) - comparison_operator = "LessThanThreshold" - evaluation_periods = 5 - threshold = 5 - period = 60 - unit = "Gigabytes" - namespace = "AWS/RDS" - metric_name = "FreeStorageSpace" - statistic = "Average" - dimensions = { - DBInstanceIdentifier = module.rds-aurora["prod"].cluster_instances["one"].id - } - } - RDS_FreeableMemory = { - alarm_description = format("Average RDS freeable memory is less than %s", 100) - comparison_operator = "LessThanThreshold" - evaluation_periods = 5 - threshold = 100 - period = 60 - unit = "Megabytes" - namespace = "AWS/RDS" - metric_name = "FreeableMemory" - statistic = "Average" - dimensions = { - DBInstanceIdentifier = module.rds-aurora["prod"].cluster_instances["one"].id - } - } - RDS_DiskQueueDepth = { - alarm_description = format("Average RDS disk queue depth is greater than %s", 1) - comparison_operator = "GreaterThanThreshold" - evaluation_periods = 5 - threshold = 1 - period = 60 - unit = "Count" - namespace = "AWS/RDS" - metric_name = "DiskQueueDepth" - statistic = "Average" - dimensions = { - DBInstanceIdentifier = module.rds-aurora["prod"].cluster_instances["one"].id - } - } - RDS_ReadIOPS = { - alarm_description = format("Average RDS read IOPS is greater than %s", 1000) - comparison_operator = "GreaterThanThreshold" - evaluation_periods = 5 - threshold = 1000 - period = 60 - unit = "Count/Second" - namespace = "AWS/RDS" - metric_name = "ReadIOPS" - statistic = "Average" - dimensions = { - DBInstanceIdentifier = module.rds-aurora["prod"].cluster_instances["one"].id - } - } - RDS_WriteIOPS = { - alarm_description = format("Average RDS write IOPS is greater than %s", 1000) - comparison_operator = "GreaterThanThreshold" - evaluation_periods = 5 - threshold = 1000 - period = 60 - unit = "Count/Second" - namespace = "AWS/RDS" - metric_name = "WriteIOPS" - statistic = "Average" - dimensions = { - DBInstanceIdentifier = module.rds-aurora["prod"].cluster_instances["one"].id - } - } - SQS_ApproximateAgeOfOldestMessage = { - alarm_description = format("Average SQS approximate age of oldest message is greater than %s", 300) - comparison_operator = "GreaterThanThreshold" - evaluation_periods = 5 - threshold = 300 - period = 60 - unit = "Seconds" - namespace = "AWS/SQS" - metric_name = "ApproximateAgeOfOldestMessage" - statistic = "Maximum" - dimensions = { - QueueName = module.karpenter.queue_name - } - } - DynamoDB_ConsumedReadCapacityUnits = { - alarm_description = format("Average DynamoDB consumed read capacity units is greater than %s", 90) - comparison_operator = "GreaterThanThreshold" - evaluation_periods = 5 - threshold = 90 - period = 60 - unit = "Count" - namespace = "AWS/DynamoDB" - metric_name = "ConsumedReadCapacityUnits" - statistic = "Average" - dimensions = { - TableName = "terraform-lock" - } - } - DynamoDB_ConsumedWriteCapacityUnits = { - alarm_description = format("Average DynamoDB consumed write capacity units is greater than %s", 90) - comparison_operator = "GreaterThanThreshold" - evaluation_periods = 5 - threshold = 90 - period = 60 - unit = "Count" - namespace = "AWS/DynamoDB" - metric_name = "ConsumedWriteCapacityUnits" - statistic = "Average" - dimensions = { - TableName = "terraform-lock" - } - } - Lambda_Errors = { - alarm_description = format("Average Lambda errors is greater than %s", 1) - comparison_operator = "GreaterThanThreshold" - evaluation_periods = 5 - threshold = 1 - period = 60 - unit = "Count" - namespace = "AWS/Lambda" - metric_name = "Errors" - statistic = "Sum" - dimensions = { - FunctionName = module.notify-slack.notify_slack_lambda_function_name - } - } - } -} - -module "metric_alarm" { - source = "terraform-aws-modules/cloudwatch/aws//modules/metric-alarm" - version = "5.7.1" - - for_each = local.alarms - alarm_name = each.key - alarm_description = each.value.alarm_description - comparison_operator = each.value.comparison_operator - evaluation_periods = each.value.evaluation_periods - threshold = each.value.threshold - period = each.value.period - unit = each.value.unit - insufficient_data_actions = [] - - namespace = each.value.namespace - metric_name = each.value.metric_name - statistic = each.value.statistic - - dimensions = each.value.dimensions - - alarm_actions = [module.notify-slack.slack_topic_arn] -} diff --git a/infra/terraform/data.tf b/infra/terraform/data.tf deleted file mode 100644 index af2a297762..0000000000 --- a/infra/terraform/data.tf +++ /dev/null @@ -1,24 +0,0 @@ -data "aws_region" "selected" {} -data "aws_caller_identity" "current" {} -data "aws_availability_zones" "available" {} -data "aws_partition" "current" {} - -data "aws_eks_cluster_auth" "eks" { - name = module.eks.cluster_name -} - -data "aws_ecrpublic_authorization_token" "token" { - provider = aws.virginia -} - -data "aws_iam_roles" "administrator" { - name_regex = "AWSReservedSSO_AdministratorAccess" -} - -data "aws_iam_roles" "github" { - name_regex = "formbricks-prod-github" -} - -data "aws_acm_certificate" "formbricks" { - domain = local.domain -} diff --git a/infra/terraform/elasticache.tf b/infra/terraform/elasticache.tf deleted file mode 100644 index 50cd783c85..0000000000 --- a/infra/terraform/elasticache.tf +++ /dev/null @@ -1,78 +0,0 @@ -################################################################################ -# ElastiCache Module -################################################################################ -locals { - valkey_major_version = 8 -} - -moved { - from = random_password.valkey - to = random_password.valkey["prod"] -} - -resource "random_password" "valkey" { - for_each = local.envs - length = 20 - special = false -} - -module "valkey_sg" { - source = "terraform-aws-modules/security-group/aws" - version = "~> 5.0" - - name = "valkey-sg" - description = "Security group for VPC traffic" - vpc_id = module.vpc.vpc_id - - ingress_cidr_blocks = [module.vpc.vpc_cidr_block] - ingress_rules = ["redis-tcp"] - - tags = local.tags -} - -module "elasticache_user_group" { - for_each = local.envs - source = "terraform-aws-modules/elasticache/aws//modules/user-group" - version = "1.4.1" - - user_group_id = "${each.value}-valkey" - create_default_user = false - default_user = { - user_id = each.value - passwords = [random_password.valkey[each.key].result] - } - users = { - "${each.value}" = { - access_string = "on ~* +@all" - passwords = [random_password.valkey[each.key].result] - } - } - engine = "redis" - tags = merge(local.tags, { - terraform-aws-modules = "elasticache" - }) -} - -module "valkey_serverless" { - for_each = local.envs - source = "terraform-aws-modules/elasticache/aws//modules/serverless-cache" - version = "1.4.1" - - engine = "valkey" - cache_name = "${each.value}-valkey-serverless" - major_engine_version = local.valkey_major_version - # cache_usage_limits = { - # data_storage = { - # maximum = 2 - # } - # ecpu_per_second = { - # maximum = 1000 - # } - # } - subnet_ids = module.vpc.database_subnets - - security_group_ids = [ - module.valkey_sg.security_group_id - ] - user_group_id = module.elasticache_user_group[each.key].group_id -} diff --git a/infra/terraform/iam.tf b/infra/terraform/iam.tf deleted file mode 100644 index 27ac846e14..0000000000 --- a/infra/terraform/iam.tf +++ /dev/null @@ -1,30 +0,0 @@ -################################################################################ -# GitHub OIDC Provider -# Note: This is one per AWS account -################################################################################ -module "iam_github_oidc_provider" { - source = "terraform-aws-modules/iam/aws//modules/iam-github-oidc-provider" - version = "5.54.0" - - tags = local.tags -} - -################################################################################ -# GitHub OIDC Role -################################################################################ - -module "iam_github_oidc_role" { - source = "terraform-aws-modules/iam/aws//modules/iam-github-oidc-role" - version = "5.54.0" - - name = "${local.name}-github" - - subjects = [ - "repo:formbricks/*:*", - ] - policies = { - Administrator = "arn:aws:iam::aws:policy/AdministratorAccess" - } - - tags = local.tags -} diff --git a/infra/terraform/main.tf b/infra/terraform/main.tf deleted file mode 100644 index 59e58a0759..0000000000 --- a/infra/terraform/main.tf +++ /dev/null @@ -1,533 +0,0 @@ -locals { - project = "formbricks" - environment = "prod" - name = "${local.project}-${local.environment}" - envs = { - prod = "${local.project}-prod" - stage = "${local.project}-stage" - } - vpc_cidr = "10.0.0.0/16" - azs = slice(data.aws_availability_zones.available.names, 0, 3) - tags = { - Project = local.project - Environment = local.environment - ManagedBy = "Terraform" - Blueprint = local.name - } - tags_map = { - prod = { - Project = local.project - Environment = "prod" - ManagedBy = "Terraform" - Blueprint = "${local.project}-prod" - } - stage = { - Project = local.project - Environment = "stage" - ManagedBy = "Terraform" - Blueprint = "${local.project}-stage" - } - } - domain = "k8s.formbricks.com" - karpetner_helm_version = "1.3.1" - karpenter_namespace = "karpenter" -} - -################################################################################ -# Route53 Hosted Zone -################################################################################ -module "route53_zones" { - source = "terraform-aws-modules/route53/aws//modules/zones" - version = "4.1.0" - - zones = { - "k8s.formbricks.com" = { - comment = "${local.domain} (testing)" - tags = { - Name = local.domain - } - } - } -} - -################################################################################ -# VPC -################################################################################ -module "vpc" { - source = "terraform-aws-modules/vpc/aws" - version = "5.19.0" - - name = "${local.name}-vpc" - cidr = local.vpc_cidr - - azs = local.azs - private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 4, k)] # /20 - public_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 48)] # Public LB /24 - intra_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 52)] # eks interface /24 - database_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 56)] # RDS / Elastic cache /24 - database_subnet_group_name = "${local.name}-subnet-group" - - enable_nat_gateway = true - single_nat_gateway = true - - public_subnet_tags = { - "kubernetes.io/role/elb" = 1 - } - - private_subnet_tags = { - "kubernetes.io/role/internal-elb" = 1 - # Tags subnets for Karpenter auto-discovery - "karpenter.sh/discovery" = "${local.name}-eks" - } - - tags = local.tags -} - -################################################################################ -# VPC Endpoints Module -################################################################################ -module "vpc_vpc-endpoints" { - source = "terraform-aws-modules/vpc/aws//modules/vpc-endpoints" - version = "5.19.0" - - vpc_id = module.vpc.vpc_id - - endpoints = { - "s3" = { - service = "s3" - service_type = "Gateway" - route_table_ids = flatten([ - module.vpc.intra_route_table_ids, - module.vpc.private_route_table_ids, - module.vpc.public_route_table_ids - ]) - tags = { Name = "s3-vpc-endpoint" } - } - } - - tags = local.tags -} - -################################################################################ -# EKS Module -################################################################################ -module "ebs_csi_driver_irsa" { - source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks" - version = "~> 5.52" - - role_name_prefix = "${local.name}-ebs-csi-driver-" - - attach_ebs_csi_policy = true - - oidc_providers = { - main = { - provider_arn = module.eks.oidc_provider_arn - namespace_service_accounts = ["kube-system:ebs-csi-controller-sa"] - } - } - - tags = local.tags -} - -module "eks" { - source = "terraform-aws-modules/eks/aws" - version = "20.37.2" - - cluster_name = "${local.name}-eks" - cluster_version = "1.32" - - enable_cluster_creator_admin_permissions = false - cluster_endpoint_public_access = false - cloudwatch_log_group_retention_in_days = 365 - - cluster_addons = { - coredns = { - most_recent = true - - } - eks-pod-identity-agent = { - most_recent = true - } - aws-ebs-csi-driver = { - addon_version = "v1.46.0-eksbuild.1" - service_account_role_arn = module.ebs_csi_driver_irsa.iam_role_arn - } - kube-proxy = { - most_recent = true - } - vpc-cni = { - most_recent = true - } - } - - cluster_security_group_additional_rules = { - ingress_from_vpc_cidr = { - description = "Allow all traffic from the VPC CIDR" - from_port = 0 - to_port = 0 - protocol = "-1" - type = "ingress" - cidr_blocks = [local.vpc_cidr] - } - } - - kms_key_administrators = [ - tolist(data.aws_iam_roles.github.arns)[0], - tolist(data.aws_iam_roles.administrator.arns)[0] - ] - - kms_key_users = [ - tolist(data.aws_iam_roles.github.arns)[0], - tolist(data.aws_iam_roles.administrator.arns)[0] - ] - - access_entries = { - administrator = { - principal_arn = tolist(data.aws_iam_roles.administrator.arns)[0] - policy_associations = { - Admin = { - policy_arn = "arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy" - access_scope = { - type = "cluster" - } - } - } - } - github = { - principal_arn = tolist(data.aws_iam_roles.github.arns)[0] - policy_associations = { - Admin = { - policy_arn = "arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy" - access_scope = { - type = "cluster" - } - } - } - } - } - - vpc_id = module.vpc.vpc_id - subnet_ids = module.vpc.private_subnets - control_plane_subnet_ids = module.vpc.intra_subnets - - eks_managed_node_group_defaults = { - iam_role_additional_policies = { - AmazonSSMManagedInstanceCore = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore" - } - } - - eks_managed_node_groups = { - system = { - ami_type = "BOTTLEROCKET_ARM_64" - instance_types = ["t4g.small"] - - min_size = 2 - max_size = 3 - desired_size = 2 - - labels = { - CriticalAddonsOnly = "true" - "karpenter.sh/controller" = "true" - } - - taints = { - addons = { - key = "CriticalAddonsOnly" - value = "true" - effect = "NO_SCHEDULE" - }, - } - } - } - - node_security_group_tags = merge(local.tags, { - # NOTE - if creating multiple security groups with this module, only tag the - # security group that Karpenter should utilize with the following tag - # (i.e. - at most, only one security group should have this tag in your account) - "karpenter.sh/discovery" = "${local.name}-eks" - }) - - tags = local.tags - -} - -module "karpenter" { - source = "terraform-aws-modules/eks/aws//modules/karpenter" - version = "20.34.0" - - cluster_name = module.eks.cluster_name - enable_v1_permissions = true - - # Name needs to match role name passed to the EC2NodeClass - node_iam_role_use_name_prefix = false - node_iam_role_name = local.name - create_pod_identity_association = true - namespace = local.karpenter_namespace - - # Used to attach additional IAM policies to the Karpenter node IAM role - node_iam_role_additional_policies = { - AmazonSSMManagedInstanceCore = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore" - } - - tags = local.tags -} - -output "karpenter_node_role" { - value = module.karpenter.node_iam_role_name -} - - - -# resource "helm_release" "karpenter_crds" { -# name = "karpenter-crds" -# repository = "oci://public.ecr.aws/karpenter" -# repository_username = data.aws_ecrpublic_authorization_token.token.user_name -# repository_password = data.aws_ecrpublic_authorization_token.token.password -# chart = "karpenter-crd" -# version = "1.3.1" -# namespace = local.karpenter_namespace -# values = [ -# <<-EOT -# webhook: -# enabled: true -# serviceNamespace: ${local.karpenter_namespace} -# EOT -# ] -# } - -# resource "helm_release" "karpenter" { -# name = "karpenter" -# repository = "oci://public.ecr.aws/karpenter" -# repository_username = data.aws_ecrpublic_authorization_token.token.user_name -# repository_password = data.aws_ecrpublic_authorization_token.token.password -# chart = "karpenter" -# version = "1.3.1" -# namespace = local.karpenter_namespace -# skip_crds = true -# -# values = [ -# <<-EOT -# nodeSelector: -# karpenter.sh/controller: 'true' -# dnsPolicy: Default -# settings: -# clusterName: ${module.eks.cluster_name} -# clusterEndpoint: ${module.eks.cluster_endpoint} -# interruptionQueue: ${module.karpenter.queue_name} -# EOT -# ] -# } -# -# resource "kubernetes_manifest" "ec2_node_class" { -# manifest = { -# apiVersion = "karpenter.k8s.aws/v1" -# kind = "EC2NodeClass" -# metadata = { -# name = "default" -# } -# spec = { -# amiSelectorTerms = [ -# { -# alias = "bottlerocket@latest" -# } -# ] -# role = module.karpenter.node_iam_role_name -# subnetSelectorTerms = [ -# { -# tags = { -# "karpenter.sh/discovery" = "${local.name}-eks" -# } -# } -# ] -# securityGroupSelectorTerms = [ -# { -# tags = { -# "karpenter.sh/discovery" = "${local.name}-eks" -# } -# } -# ] -# tags = { -# "karpenter.sh/discovery" = "${local.name}-eks" -# } -# } -# } -# } - -# resource "kubernetes_manifest" "node_pool" { -# manifest = { -# apiVersion = "karpenter.sh/v1" -# kind = "NodePool" -# metadata = { -# name = "default" -# } -# spec = { -# template = { -# spec = { -# nodeClassRef = { -# group = "karpenter.k8s.aws" -# kind = "EC2NodeClass" -# name = "default" -# } -# requirements = [ -# { -# key = "karpenter.k8s.aws/instance-family" -# operator = "In" -# values = ["c8g", "c7g", "m8g", "m7g", "r8g", "r7g"] -# }, -# { -# key = "karpenter.k8s.aws/instance-cpu" -# operator = "In" -# values = ["2", "4", "8"] -# }, -# { -# key = "karpenter.k8s.aws/instance-hypervisor" -# operator = "In" -# values = ["nitro"] -# } -# ] -# } -# } -# limits = { -# cpu = 1000 -# } -# disruption = { -# consolidationPolicy = "WhenEmptyOrUnderutilized" -# consolidateAfter = "30s" -# } -# } -# } -# } - -module "eks_blueprints_addons" { - source = "aws-ia/eks-blueprints-addons/aws" - version = "~> 1" - - cluster_name = module.eks.cluster_name - cluster_endpoint = module.eks.cluster_endpoint - cluster_version = module.eks.cluster_version - oidc_provider_arn = module.eks.oidc_provider_arn - - enable_metrics_server = true - metrics_server = { - chart_version = "3.12.2" - } - - enable_aws_load_balancer_controller = true - aws_load_balancer_controller = { - chart_version = "1.10.0" - values = [ - <<-EOT - vpcId: ${module.vpc.vpc_id} - EOT - ] - } - enable_external_dns = true - external_dns_route53_zone_arns = [module.route53_zones.route53_zone_zone_arn[local.domain]] - external_dns = { - chart_version = "1.15.2" - } - enable_cert_manager = false - cert_manager = { - chart_version = "v1.17.1" - values = [ - <<-EOT - installCRDs: false - crds: - enabled: true - keep: true - EOT - ] - } - - enable_external_secrets = true - external_secrets = { - chart_version = "0.14.3" - } - - tags = local.tags -} - -### Formbricks App - -moved { - from = module.formbricks_s3_bucket - to = module.formbricks_s3_bucket["prod"] -} - -module "formbricks_s3_bucket" { - for_each = local.envs - source = "terraform-aws-modules/s3-bucket/aws" - version = "4.6.0" - - bucket = each.key == "prod" ? "formbricks-cloud-eks" : "formbricks-cloud-eks-${each.key}" - force_destroy = true - control_object_ownership = true - object_ownership = "BucketOwnerPreferred" - versioning = { - enabled = true - } - cors_rule = [ - { - allowed_methods = ["POST"] - allowed_origins = ["https://*"] - allowed_headers = ["*"] - expose_headers = [] - } - ] -} - -moved { - from = module.formbricks_app_iam_policy - to = module.formbricks_app_iam_policy["prod"] -} - -module "formbricks_app_iam_policy" { - for_each = local.envs - source = "terraform-aws-modules/iam/aws//modules/iam-policy" - version = "5.53.0" - - name_prefix = each.key == "prod" ? "formbricks-" : "formbricks-${each.key}-" - path = "/" - description = "Policy for fombricks app" - - policy = jsonencode({ - Version = "2012-10-17" - Statement = [ - { - Effect = "Allow" - Action = [ - "s3:*", - ] - Resource = [ - module.formbricks_s3_bucket[each.key].s3_bucket_arn, - "${module.formbricks_s3_bucket[each.key].s3_bucket_arn}/*" - ] - } - ] - }) -} - -moved { - from = module.formbricks_app_iam_role - to = module.formbricks_app_iam_role["prod"] -} - -module "formbricks_app_iam_role" { - for_each = local.envs - source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks" - version = "5.53.0" - - role_name_prefix = each.key == "prod" ? "formbricks-" : "formbricks-${each.key}-" - - role_policy_arns = { - "formbricks" = module.formbricks_app_iam_policy[each.key].arn - } - assume_role_condition_test = "StringLike" - - oidc_providers = { - eks = { - provider_arn = module.eks.oidc_provider_arn - namespace_service_accounts = each.key == "prod" ? ["formbricks:*"] : ["formbricks-${each.key}:*"] - } - } -} diff --git a/infra/terraform/observability.tf b/infra/terraform/observability.tf deleted file mode 100644 index 49319392e6..0000000000 --- a/infra/terraform/observability.tf +++ /dev/null @@ -1,136 +0,0 @@ -module "loki_s3_bucket" { - source = "terraform-aws-modules/s3-bucket/aws" - version = "4.6.0" - - bucket_prefix = "loki-" - force_destroy = true - control_object_ownership = true - object_ownership = "BucketOwnerPreferred" -} - -module "observability_loki_iam_policy" { - source = "terraform-aws-modules/iam/aws//modules/iam-policy" - version = "5.53.0" - - name_prefix = "loki-" - path = "/" - description = "Policy for fombricks observability apps" - - policy = jsonencode({ - Version = "2012-10-17" - Statement = [ - { - Effect = "Allow" - Action = [ - "s3:*", - ] - Resource = [ - module.loki_s3_bucket.s3_bucket_arn, - "${module.loki_s3_bucket.s3_bucket_arn}/*" - ] - } - ] - }) -} - - -module "observability_loki_iam_role" { - source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks" - version = "5.53.0" - - role_name_prefix = "loki-" - - role_policy_arns = { - "formbricks" = module.observability_loki_iam_policy.arn - } - assume_role_condition_test = "StringLike" - - oidc_providers = { - eks = { - provider_arn = module.eks.oidc_provider_arn - namespace_service_accounts = ["monitoring:loki"] - } - } -} - -module "observability_grafana_iam_policy" { - source = "terraform-aws-modules/iam/aws//modules/iam-policy" - version = "5.53.0" - - name_prefix = "grafana-" - path = "/" - description = "Policy for Formbricks observability apps - Grafana" - - policy = jsonencode({ - Version = "2012-10-17" - Statement = [ - { - Sid = "AllowReadingMetricsFromCloudWatch" - Effect = "Allow" - Action = [ - "cloudwatch:DescribeAlarmsForMetric", - "cloudwatch:DescribeAlarmHistory", - "cloudwatch:DescribeAlarms", - "cloudwatch:ListMetrics", - "cloudwatch:GetMetricData", - "cloudwatch:GetInsightRuleReport" - ] - Resource = "*" - }, - { - Sid = "AllowReadingResourceMetricsFromPerformanceInsights" - Effect = "Allow" - Action = "pi:GetResourceMetrics" - Resource = "*" - }, - { - Sid = "AllowReadingLogsFromCloudWatch" - Effect = "Allow" - Action = [ - "logs:DescribeLogGroups", - "logs:GetLogGroupFields", - "logs:StartQuery", - "logs:StopQuery", - "logs:GetQueryResults", - "logs:GetLogEvents" - ] - Resource = "*" - }, - { - Sid = "AllowReadingTagsInstancesRegionsFromEC2" - Effect = "Allow" - Action = [ - "ec2:DescribeTags", - "ec2:DescribeInstances", - "ec2:DescribeRegions" - ] - Resource = "*" - }, - { - Sid = "AllowReadingResourcesForTags" - Effect = "Allow" - Action = "tag:GetResources" - Resource = "*" - } - ] - }) -} - -module "observability_grafana_iam_role" { - source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks" - version = "5.53.0" - - role_name_prefix = "grafana-" - - role_policy_arns = { - "formbricks" = module.observability_grafana_iam_policy.arn - } - assume_role_condition_test = "StringLike" - - oidc_providers = { - eks = { - provider_arn = module.eks.oidc_provider_arn - namespace_service_accounts = ["monitoring:grafana"] - } - } -} diff --git a/infra/terraform/provider.tf b/infra/terraform/provider.tf deleted file mode 100644 index efa160e227..0000000000 --- a/infra/terraform/provider.tf +++ /dev/null @@ -1,31 +0,0 @@ -provider "aws" { - region = "eu-central-1" -} - -provider "aws" { - region = "us-east-1" - alias = "virginia" -} - -terraform { - backend "s3" { - bucket = "715841356175-terraform" - key = "terraform.tfstate" - region = "eu-central-1" - dynamodb_table = "terraform-lock" - } -} - -provider "kubernetes" { - host = module.eks.cluster_endpoint - cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data) - token = data.aws_eks_cluster_auth.eks.token -} - -provider "helm" { - kubernetes { - host = module.eks.cluster_endpoint - cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data) - token = data.aws_eks_cluster_auth.eks.token - } -} diff --git a/infra/terraform/rds.tf b/infra/terraform/rds.tf deleted file mode 100644 index 41a4ce27b0..0000000000 --- a/infra/terraform/rds.tf +++ /dev/null @@ -1,79 +0,0 @@ -################################################################################ -# PostgreSQL Serverless v2 -################################################################################ -data "aws_rds_engine_version" "postgresql" { - engine = "aurora-postgresql" - version = "16.6" -} - -moved { - from = random_password.postgres - to = random_password.postgres["prod"] -} - -resource "random_password" "postgres" { - for_each = local.envs - length = 20 - special = false -} - -moved { - from = module.rds-aurora - to = module.rds-aurora["prod"] -} - -module "rds-aurora" { - for_each = local.envs - source = "terraform-aws-modules/rds-aurora/aws" - version = "9.12.0" - - name = "${each.value}-postgres" - engine = data.aws_rds_engine_version.postgresql.engine - engine_mode = "provisioned" - engine_version = data.aws_rds_engine_version.postgresql.version - storage_encrypted = true - master_username = "formbricks" - master_password = random_password.postgres[each.key].result - manage_master_user_password = false - create_db_cluster_parameter_group = true - db_cluster_parameter_group_family = data.aws_rds_engine_version.postgresql.parameter_group_family - db_cluster_parameter_group_parameters = [ - { - name = "shared_preload_libraries" - value = "pglogical" - apply_method = "pending-reboot" - } - ] - - vpc_id = module.vpc.vpc_id - db_subnet_group_name = module.vpc.database_subnet_group_name - security_group_rules = { - vpc_ingress = { - cidr_blocks = [module.vpc.vpc_cidr_block] - } - } - performance_insights_enabled = true - cluster_performance_insights_enabled = true - - backup_retention_period = 7 - apply_immediately = true - skip_final_snapshot = false - - deletion_protection = true - - enable_http_endpoint = true - - serverlessv2_scaling_configuration = { - min_capacity = 0.5 - max_capacity = 50 - } - - instance_class = "db.serverless" - - instances = { - one = {} - } - - tags = local.tags_map[each.key] - -} diff --git a/infra/terraform/secrets.tf b/infra/terraform/secrets.tf deleted file mode 100644 index 16aa40b520..0000000000 --- a/infra/terraform/secrets.tf +++ /dev/null @@ -1,24 +0,0 @@ -# Create the first AWS Secrets Manager secret for environment variables -moved { - from = aws_secretsmanager_secret.formbricks_app_secrets - to = aws_secretsmanager_secret.formbricks_app_secrets["prod"] -} - -resource "aws_secretsmanager_secret" "formbricks_app_secrets" { - for_each = local.envs - name = "${each.key}/formbricks/secrets" -} - -moved { - from = aws_secretsmanager_secret_version.formbricks_app_secrets - to = aws_secretsmanager_secret_version.formbricks_app_secrets["prod"] -} - -resource "aws_secretsmanager_secret_version" "formbricks_app_secrets" { - for_each = local.envs - secret_id = aws_secretsmanager_secret.formbricks_app_secrets[each.key].id - secret_string = jsonencode({ - REDIS_URL = "rediss://${each.value}:${random_password.valkey[each.key].result}@${module.valkey_serverless[each.key].serverless_cache_endpoint[0].address}:6379" - }) -} - diff --git a/infra/terraform/variables.tf b/infra/terraform/variables.tf deleted file mode 100644 index 792d600548..0000000000 --- a/infra/terraform/variables.tf +++ /dev/null @@ -1 +0,0 @@ -# diff --git a/infra/terraform/versions.tf b/infra/terraform/versions.tf deleted file mode 100644 index eceb7f8cf2..0000000000 --- a/infra/terraform/versions.tf +++ /dev/null @@ -1,18 +0,0 @@ -terraform { - required_version = ">= 1.0" - - required_providers { - aws = { - source = "hashicorp/aws" - version = ">= 5.46" - } - kubernetes = { - source = "hashicorp/kubernetes" - version = "~> 2.36" - } - helm = { - source = "hashicorp/helm" - version = "~> 2.17" - } - } -}