Production-ready multi-cloud Infrastructure as Code demonstrating enterprise DevOps practices with Terraform, Docker, AWS, GCP, and Azure.
Learn more: salutron.lisekarimi.com
Multi-environment (dev/test/prod) infrastructure with automated CI/CD pipelines, demonstrating:
- Single-command deployment/teardown across AWS, GCP, and Azure
- OIDC/Workload Identity Federation for secure GitHub Actions
- Remote state management with workspace isolation
- Docker containerization with optimized builds
Required:
- Docker, Terraform β₯1.0, AWS CLI v2, gcloud CLI, Azure CLI, Python 3.11+, Make
- AWS account with IAM user configured
- GCP project with billing enabled
- Azure subscription with resource group
- GitHub repository with Actions enabled
Skills:
- Terraform, Docker, Bash scripting, CI/CD concepts
| Component | AWS | GCP | Azure |
|---|---|---|---|
| Compute | App Runner | Cloud Run | Container Apps |
| Registry | ECR | Artifact Registry | ACR |
| Storage | S3 | Cloud Storage | Blob Storage |
| Auth | IAM + OIDC | Service Accounts + Workload Identity | Service Principal + Workload Identity |
| State | S3 + DynamoDB | Cloud Storage | Blob Storage |
1οΈβ£ Create IAM User
Create terraform_user with these policies:
AmazonEC2ContainerRegistryFullAccessIAMFullAccessAWSAppRunnerFullAccessAmazonS3FullAccessAmazonSNSFullAccessCloudWatchFullAccessAmazonDynamoDBFullAccess
2οΈβ£ Configure AWS CLI
aws configure
# Enter terraform_user credentials3οΈβ£ Setup Remote State Backend (One-Time)
make aws-setup-backend4οΈβ£ Update Terraform Variables
β οΈ IMPORTANT: Before deploying, updateterraform/aws/terraform.tfvarsand environment-specific files (e.g.,prod.tfvars) with your own data (project name, region, custom domain, etc.).
5οΈβ£ Deploy to Environment
make aws-deploy-dev # Development
make aws-deploy-test # Testing
make aws-deploy-prod # Production6οΈβ£ Destroy Environment
make aws-destroy-dev
β οΈ IMPORTANT: Before proceeding, make sure to adjust the repository name interraform/ci-setup/aws/github-oidc.tf(variablegithub_repository) to match your own repository in the formatowner/repo.
1οΈβ£ Setup OIDC Authentication
make aws-setup-github-oidc
# Save the output: github_actions_role_arn2οΈβ£ Add GitHub Secrets Go to GitHub repo β Settings β Secrets and variables β Actions:
AWS_ROLE_ARN:arn:aws:iam::YOUR_ACCOUNT:role/github-actions-salutron-deployDEFAULT_AWS_REGION:us-east-1AWS_ACCOUNT_ID: Your 12-digit AWS account IDOPENAI_API_KEY: Your OpenAI API key
3οΈβ£ Deploy via GitHub Actions
- Go to Actions tab β "Deploy Salutron"
- Click "Run workflow"
- Select environment (dev/test/prod)
π Why OIDC Instead of Access Keys?
Traditional Access Keys β OIDC (Recommended) β
ββ Permanent credentials ββ Temporary tokens (~1 hour)
ββ Manual rotation needed ββ Auto-rotates each run
ββ Security risk if leaked ββ No credentials stored
ββ Hard to audit ββ Full audit trail
π How OIDC Works:
βββββββββββββββ βββββββββββββββ
β GitHub β 1. JWT token β AWS β
β Actions βββββββββββββββββββ>β verifies β
β β 2. Temp creds β identity β
β β<βββββββββββββββββββ€ β
βββββββββββββββ βββββββββββββββ
1οΈβ£ Initial GCP Setup
make gcp-setup
# Authenticates and enables required APIs2οΈβ£ Setup Remote State Backend (One-Time)
make gcp-setup-backend3οΈβ£ Update Terraform Variables
β οΈ IMPORTANT: Before deploying, updateterraform/gcp/terraform.tfvarsand environment-specific files with your own data (project ID, project name, region, etc.).
4οΈβ£ Deploy to Environment
make gcp-deploy-dev # Development
make gcp-deploy-test # Testing
make gcp-deploy-prod # Production4οΈβ£ Destroy Environment
make gcp-destroy-dev
β οΈ IMPORTANT: Before proceeding, make sure to adjust the repository name interraform/ci-setup/gcp/github-workload-identity.tf(variablegithub_repository) to match your own repository in the formatowner/repo.
1οΈβ£ Setup Workload Identity Federation
make gcp-setup-workload-identity
# Save both outputs:
# - workload_identity_provider
# - service_account_email2οΈβ£ Add GitHub Secrets Go to GitHub repo β Settings β Secrets and variables β Actions:
GCP_PROJECT_ID:salutronGCP_WORKLOAD_IDENTITY_PROVIDER:projects/280220662544/locations/global/...GCP_SERVICE_ACCOUNT:github-actions-sa@salutron.iam.gserviceaccount.comGCP_REGION:us-central1OPENAI_API_KEY: Your OpenAI API key
3οΈβ£ Deploy via GitHub Actions
- Go to Actions tab β "Deploy Salutron to GCP"
- Click "Run workflow"
- Select environment (dev/test/prod)
π‘ GCP Workload Identity = AWS OIDC Same concept, different name. No long-lived service account keys needed!
1οΈβ£ Install Azure CLI
az --version
az login2οΈβ£ Initial Azure Setup
make azure-setup
# Registers required resource providers3οΈβ£ Setup Remote State Backend (One-Time)
make azure-setup-backend4οΈβ£ Update Terraform Variables
β οΈ IMPORTANT: Before deploying, updateterraform/azure/terraform.tfvarsand environment-specific files with your own data (project name, region, resource group name, etc.).
5οΈβ£ Deploy to Environment
make azure-deploy-dev # Development
make azure-deploy-test # Testing
make azure-deploy-prod # Production6οΈβ£ Destroy Environment
make azure-destroy-dev
β οΈ IMPORTANT: Before proceeding, make sure to adjust the repository name interraform/ci-setup/azure/github-workload-identity.tf(variablegithub_repository) to match your own repository in the formatowner/repo.
1οΈβ£ Setup Workload Identity Federation
make azure-setup-workload-identity
# Save the outputs: client_id, tenant_id, subscription_id2οΈβ£ Add GitHub Secrets
AZURE_CLIENT_ID: Service principal client IDAZURE_TENANT_ID: Azure tenant IDAZURE_SUBSCRIPTION_ID: Azure subscription IDAZURE_RESOURCE_GROUP:salutron-rgAZURE_REGION:francecentralOPENAI_API_KEY: Your OpenAI API key
3οΈβ£ Deploy via GitHub Actions
- Actions β "Deploy Salutron to Azure"
- Click "Run workflow"
- Select environment
| Feature | AWS | GCP | Azure |
|---|---|---|---|
| Container Service | App Runner | Cloud Run | Container Apps |
| Container Registry | ECR | Artifact Registry | ACR (Azure Container Registry) |
| Object Storage | S3 | Cloud Storage | Blob Storage |
| Authentication | IAM Roles | Service Accounts | Service Principals |
| CI/CD Auth | OIDC | Workload Identity | Workload Identity Federation |
| State Storage | S3 + DynamoDB | Cloud Storage (built-in locking) | Blob Storage + Container |
| Min Instances | 1 | 0 (scale to zero) | 1 (with ingress) |
| Scenario | Use | Why |
|---|---|---|
| Learning/Testing | Local | Fast iterations, immediate feedback |
| Portfolio Projects | Both | Shows CI/CD skills + practical knowledge |
| Team Projects | GitHub Actions | Consistent deployments, no "works on my machine" |
| Production | GitHub Actions | Audit trail, approvals, automated |
This Project: Implements both methods to demonstrate enterprise deployment strategies.
Hybrid Pattern:
Local: Dev testing (make aws-deploy-dev)
GitHub Actions: Test/Prod (automated + protected)
MIT License - feel free to use this project for learning!
Lise Karimi
- Portfolio: lisekarimi.com
- GitHub: @lisekarimi
Built with β€οΈ while learning DevOps
β Star this repo if it helped you learn Terraform and AWS/GCP/Azure!
