mirror of
https://github.com/formbricks/formbricks.git
synced 2025-12-16 19:07:16 -06:00
chore: remove cloud infrastructure from main repository (#6686)
This commit is contained in:
@@ -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
|
||||
86
.github/workflows/terraform-plan-and-apply.yml
vendored
86
.github/workflows/terraform-plan-and-apply.yml
vendored
@@ -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"
|
||||
13
.gitignore
vendored
13
.gitignore
vendored
@@ -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
|
||||
|
||||
@@ -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
|
||||
3
infra/.gitignore
vendored
3
infra/.gitignore
vendored
@@ -1,3 +0,0 @@
|
||||
.terraform/
|
||||
builds
|
||||
/.direnv/
|
||||
61
infra/flake.lock
generated
61
infra/flake.lock
generated
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
];
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
205
infra/terraform/.terraform.lock.hcl
generated
205
infra/terraform/.terraform.lock.hcl
generated
@@ -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",
|
||||
]
|
||||
}
|
||||
@@ -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
|
||||
#
|
||||
# }
|
||||
@@ -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]
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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}:*"]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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"]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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]
|
||||
|
||||
}
|
||||
@@ -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"
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
#
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user