Infrastructure CI/CD for Data Engineering
Skill by ara.so — Data Skills collection
This project demonstrates practical CI/CD patterns for deploying data infrastructure changes using GitHub Actions, Terraform, and AWS. It uses OpenID Connect (OIDC) for secure, keyless authentication between GitHub Actions and AWS, eliminating the need for long-lived AWS credentials.
What This Project Does
- Bootstraps infrastructure: Creates S3 backend for Terraform state and OIDC provider for GitHub Actions
- Automates deployments: Uses GitHub Actions workflows to plan and apply Terraform changes
- Enforces reviews: Requires manual approval before production deployments
- Validates code: Runs Terraform formatting and validation checks on PRs
Project Structure
Prerequisites
- AWS Account with appropriate permissions
- Terraform installed locally (v1.0+)
- GitHub Account and repository access
- AWS CLI configured with credentials
Bootstrap Setup
Step 1: Create S3 Backend and OIDC Provider
The bootstrap process creates:
- S3 bucket for Terraform state storage
- DynamoDB table for state locking
- IAM OIDC provider for GitHub Actions
- IAM role that GitHub Actions will assume
Expected output:
Step 2: Configure GitHub Repository Secrets
Create a repository secret named AWS_ROLE_ARN:
- Navigate to:
Settings → Secrets and variables → Actions → New repository secret - Name:
AWS_ROLE_ARN - Value: The ARN output from bootstrap (without quotes)
Step 3: Create GitHub Environment
Set up a production environment with manual approval:
- Navigate to:
Settings → Environments → New environment - Name:
production - Configure protection rules:
- ✅ Required reviewers (minimum 1)
- Add yourself or team members as reviewers
Bootstrap Terraform Configuration
terraform/bootstrap/main.tf (simplified example):
terraform/bootstrap/variables.tf:
Main Infrastructure Configuration
terraform/main/main.tf (example data infrastructure):
GitHub Actions Workflows
CI Workflow: Format and Validation
.github/workflows/ci.yml:
Deploy Workflow: Plan and Apply
.github/workflows/deploy.yml:
Common Workflows
Adding New Infrastructure
- Create/modify Terraform files in
terraform/main/:
- Format Terraform files:
- Validate locally (optional but recommended):
-
Create a pull request:
- CI workflow runs format check and validation
- Review the checks before merging
-
Merge to main:
- Deploy workflow runs
terraform plan - Manual approval required in GitHub UI
- After approval,
terraform applyexecutes
- Deploy workflow runs
Checking Deployment Status
Testing Changes Locally
Environment Variables and Configuration
Required GitHub Secrets
Terraform Variables
Create terraform/main/terraform.tfvars:
Using Environment-Specific Configurations
terraform/main/environments/dev.tfvars:
terraform/main/environments/prod.tfvars:
Modify workflow to use environment-specific variables:
Advanced Patterns
Matrix Deployments for Multiple Environments
Drift Detection Scheduled Job
.github/workflows/drift-detection.yml:
Cost Estimation with Infracost
Add to .github/workflows/ci.yml:
Troubleshooting
"Error: configuring Terraform AWS Provider: failed to get shared config profile"
Solution: Ensure AWS credentials are properly configured in GitHub Actions:
"Error: Error acquiring the state lock"
Cause: Another Terraform operation is running or a previous operation failed to release the lock.
Solution:
"Error: InvalidClientTokenId: The security token included in the request is invalid"
Cause: OIDC provider not configured correctly or role ARN is incorrect.
Solution:
- Verify the
AWS_ROLE_ARNsecret matches bootstrap output - Check OIDC provider trust policy includes your repository
- Ensure GitHub Actions has
id-token: writepermission
Format Check Failing
Error: Terraform files not properly formatted.
Solution:
State Backend Not Found
Error: "Error: Failed to get existing workspaces: S3 bucket does not exist"
Cause: Backend configuration references a bucket that doesn't exist.
Solution:
- Verify bootstrap was applied:
terraform -chdir=terraform/bootstrap output - Update backend configuration in
terraform/main/main.tfwith correct bucket name - Re-run
terraform init
Manual Approval Not Showing
Cause: Production environment not configured or reviewers not set.
Solution:
- Go to
Settings → Environments → production - Enable "Required reviewers"
- Add at least one reviewer
- Re-run the workflow
Cleanup
Destroy all resources:
tear-down.sh example:
Best Practices
- Always run
terraform fmtbefore committing - Use meaningful commit messages that describe infrastructure changes
- Review plans carefully before approving deployments
- Enable branch protection on main branch
- Use separate AWS accounts for dev/staging/production
- Monitor state file changes for unauthorized modifications
- Implement drift detection to catch manual changes
- Version your Terraform providers to ensure consistency
- Use workspaces or separate backends for different environments
- Document custom modules and complex configurations


