A production-ready, security-first GitOps template for small teams and companies. Deploy a fully automated infrastructure across 3 AWS regions with built-in security scanning, policy enforcement, and secret management.
Frankfurt (eu-central-1) β Production workloads
Ireland (eu-west-1) β Ephemeral dev environment (destroyed after testing)
Paris (eu-west-3) β Security tools hub
- SonarQube β SAST and code quality
- Harbor β Private container registry
- DefectDojo β Vulnerability management
- Dependency Track β Software composition analysis
- Vault β Secrets management
- Prometheus + Grafana β Monitoring and observability
- Atlantis β Terraform pull request automation
push to dev
β
βΌ
Security Scan (TruffleHog, KICS, Checkov)
β
βΌ
Open PR to main
β
βΌ
PR Checks (fmt, validate, plan, OPA, SonarQube, Trivy)
β
βΌ
Manual approval
β
βΌ
Deploy to Ireland (dev)
β
βΌ
Smoke tests + Manual testing
β
βΌ
Manual approval
β
βΌ
Destroy Ireland β Deploy to Frankfurt (prod)
- Terraform >= 1.0.0
- Terragrunt >= 0.55.0
- AWS CLI configured
- kubectl
- Helm
- Conftest
- GitHub account with Actions enabled
git clone https://github.com/YOUR_ORG/gitops-devsecops-aws
cd gitops-devsecops-awsaws configureCreates S3 backends and DynamoDB lock tables across all 3 regions.
make bootstrapmake up-securitymake up-prod| Secret | Description |
|---|---|
AWS_ROLE_ARN |
IAM role ARN for GitHub Actions OIDC |
DEFECTDOJO_TOKEN |
DefectDojo API token |
DEFECTDOJO_URL |
DefectDojo URL (Paris) |
SONAR_TOKEN |
SonarQube authentication token |
SONAR_HOST_URL |
SonarQube URL (Paris) |
SLACK_WEBHOOK |
Slack webhook for notifications |
| Environment | Purpose |
|---|---|
dev-approval |
Manual approval gate before promoting to prod |
production |
Manual approval gate before deploying to Frankfurt |
Go to Settings β Environments β New environment to create them.
Enable branch protection on main:
- Require pull request reviews
- Require status checks to pass (security-scan, pr-checks)
- Restrict pushes to main
| Resource | Cost |
|---|---|
| EKS control plane Γ 3 | ~$216/month |
| EC2 nodes (spot, t3.medium) Γ 3 | ~$30/month |
| S3 + DynamoDB | ~$5/month |
| Total | ~$250/month |
Tip: Stop EC2 nodes when not in use to reduce costs significantly. For learning purposes, spin up one region at a time.
make help # List all available commands
make bootstrap # Create S3 backends and DynamoDB tables (run once)
make up-all # Deploy all environments
make down-all # Destroy all environments
make up-prod # Deploy Frankfurt (prod)
make up-dev # Deploy Ireland (dev)
make up-security # Deploy Paris (security tools)
make fmt # Format all Terraform files
make validate # Validate all Terraform files
make scan # Run security scans locally
make test-policies # Run OPA policy testsEvery change goes through multiple security gates:
| Gate | Tool | When |
|---|---|---|
| Secrets scan | TruffleHog | Every push to dev |
| IaC scan | KICS | Every push to dev |
| IaC scan | Checkov | Every push to dev |
| Code quality | SonarQube | Every PR |
| Policy enforcement | OPA/Conftest | Every PR |
| Container scan | Trivy | Every PR |
| Vulnerability mgmt | DefectDojo | Aggregates all results |
Policies are enforced on every PR via Conftest:
| Policy | Description |
|---|---|
no_public_s3 |
S3 buckets must have public access blocked |
enforce_imdsv2 |
EC2 instances must use IMDSv2 |
require_encryption |
EBS volumes must be encrypted |
eks_private_endpoint |
EKS clusters must have private endpoint |
no_privileged_containers |
EKS node groups must have launch template |
require_tags |
All resources must have Name and Environment tags |
no_wide_ingress |
SSH must not be open to 0.0.0.0/0 |
eks_secrets_encryption |
EKS clusters must encrypt secrets |
modules/
βββ networking/ # VPC, subnets, IGW, fck-nat, route tables
βββ eks/ # EKS cluster, node groups, IAM roles
βββ eks-addons/ # EBS CSI, CoreDNS, kube-proxy, LBC
βββ security-tools/ # IAM roles for security tools, Harbor S3
βββ prod-services/ # Generic IAM role for production workloads
- Update
modules/prod-services/main.tfwith your application resources - Add required IAM permissions to
aws_iam_role.app - Create Kubernetes manifests in
kubernetes/manifests/prod-services/ - Push to
devbranch and follow the GitOps flow
Default instance sizes are optimised for small teams. To scale:
# environments/security/eks/terragrunt.hcl
inputs = {
instance_types = ["t3.large"] # upgrade from t3.medium
}- Fork the repository
- Create a feature branch from
dev - Make your changes
- Push to your fork and open a PR to
dev - Security scans run automatically
- Once approved, changes flow through the full GitOps pipeline
MIT β free to use, modify, and distribute.