GitHub Copilot Instructions for Infrastructure (infra) Folder
Overview
This folder contains Terraform infrastructure-as-code (IaC) for managing the Reports application infrastructure.
infra/ itself is the Spacelift root (Cloudflare, CloudFront, S3, IAM, ACM, Firebase, Datadog, the GitHub repository). The application environments are separate roots — production/, staging/ and reviews/ — applied by deploy.yml against the shared S3 backend. Everything below describes the Spacelift root unless it says otherwise.
Technology Stack
- Terraform: >= 1.5.7
- Providers:
- GitHub (~> 6.0) - Repository and organization management
- AWS (>= 6.0) - Cloud infrastructure (S3, ACM, IAM, CloudFront)
- Cloudflare - DNS
- Datadog (~> 4.0) - Monitors and Error Tracking
- Google Beta (~> 7.0) - Firebase projects
- SOPS (~> 0.5) - Secrets management
Setup Instructions
Prerequisites
- Install Terraform (>= 1.5.7):
# Using tfenv (recommended)
tfenv install 1.5.7
tfenv use 1.5.7
# Or download from https://www.terraform.io/downloads
- Install and configure required CLI tools:
# GitHub CLI (for authentication)
gh auth login
# AWS CLI (for AWS resources)
aws configure
# SOPS (for secrets management)
# Install from https://github.com/mozilla/sops
Initialize Terraform
cd infra
# Initialize Terraform and download providers
terraform init
# Validate configuration
terraform validate
# Plan changes (dry-run)
terraform plan
# Apply changes (with approval)
terraform apply
File Structure
- main.tf - Provider configurations and version requirements
- github.tf - GitHub repository and organization resources
- iam.tf - AWS IAM roles and policies
- s3.tf - AWS S3 buckets and configurations
- acm.tf - AWS Certificate Manager (SSL certificates)
- cloudflare.tf - DNS records
- cloudfront.tf - CloudFront distributions
- datadog.tf - Monitors and Error Tracking rules
- firebase.tf - Firebase projects
- production/, staging/, reviews/ - Cluster roots, one per environment
- modules/app - Shared app module the cluster roots instantiate
- *.env, *.json - SOPS-encrypted files with secrets
- .sops.yaml - SOPS configuration for encryption
- .terraform.lock.hcl - Terraform provider version lock file
Secrets Management
Sensitive data is encrypted using SOPS and stored in encrypted .env files:
- ci_secrets.env - CI/CD secrets
- ga-reports-common.env - Secrets shared by every environment
- ga-reports.env - Production-only secrets
- ga-reports-staging.env - Secrets for staging and the review apps
- firebase-service-account-*.json - Firebase service accounts
Working with Encrypted Files
# Edit encrypted file
sops ga-reports.env
# View encrypted file
sops -d ga-reports.env
# Encrypt a new file
sops -e file.env > encrypted.env
Coding Standards & Best Practices
Terraform Style
- Formatting: Always format code with
terraform fmt
terraform fmt -recursive
- Validation: Validate configuration before committing
terraform validate
-
Code Organization:
- Group resources by service/provider in separate files
- Use descriptive resource names that indicate their purpose
- Add comments for complex configurations
- Use variables for repeated values
-
State Management:
- Never commit
.tfstatefiles - Use remote state backend for team collaboration
- Always run
terraform planbeforeapply
- Never commit
-
Security:
- Never commit plain-text secrets
- Always use SOPS for sensitive data
- Use least-privilege IAM policies
- Enable resource encryption where applicable
Resource Naming Conventions
- Use lowercase with hyphens:
reports-staging-app - Include environment:
reports-production-bucket - Be descriptive:
github-actions-deploy-key
Common Tasks
Adding a New AWS Resource
- Create or edit the appropriate
.tffile (e.g.,s3.tffor S3 buckets) - Define the resource with appropriate configuration
- Format and validate:
terraform fmt
terraform validate
- Plan and review changes:
terraform plan
- Apply if changes look correct:
terraform apply
Updating an Application Environment
- Edit the root under
production/,staging/orreviews/, or the shared module undermodules/ - Open a pull request —
deploy.ymlruns the plan - Merge. Staging applies it straight away (
staging.ymlalso runs on the infra paths the staging root reads). Production applies it with the next release, or earlier by dispatchingdeploy.ymlfrommainwith the current release tag: see "Apply infra changes without a release, or roll back" ininfra/production/README.md
Managing GitHub Resources
- Edit
github.tf - Add/modify repository settings, secrets, or webhooks
- Authenticate with GitHub CLI:
gh auth status - Apply changes with terraform
Rotating Secrets
- Update the secret in the appropriate service
- Update the encrypted
.envfile:
sops ga-reports.env
# Edit the value
# Save and exit
- Run
terraform planto verify changes - Apply with
terraform apply
Development Workflow
Before Making Changes
- Ensure you're on the latest code:
git pull origin main
- Initialize/update Terraform:
terraform init -upgrade
- Verify current state:
terraform plan
Making Changes
- Edit the appropriate
.tffiles - Format your code:
terraform fmt
- Validate syntax:
terraform validate
- Review planned changes:
terraform plan
- Test in staging environment if possible
- Apply changes:
terraform apply
After Changes
- Commit changes including
.terraform.lock.hclif providers updated - Document significant infrastructure changes
- Update this documentation if adding new patterns
CI/CD Integration
The GitHub Actions workflow .github/workflows/copilot-setup-steps.yml should include terraform setup for infrastructure validation:
- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: 1.5.7
- name: Terraform Init
run: |
cd infra
terraform init
Troubleshooting
Common Issues
-
Provider Authentication Failures
- Verify CLI authentication:
gh auth status,aws sts get-caller-identity - Check environment variables for API tokens
- Ensure SOPS can decrypt files
- Verify CLI authentication:
-
State Lock Issues
- Wait for other operations to complete
- Use
terraform force-unlockonly if necessary
-
Plan Shows Unexpected Changes
- Check if manual changes were made outside Terraform
- Review recent commits for configuration drift
- Consider importing resources with
terraform import
-
SOPS Decryption Errors
- Verify you have the correct decryption keys
- Check
.sops.yamlconfiguration - Ensure age or PGP keys are properly configured
Important Notes
- State Files: Never commit
.tfstatefiles - they contain sensitive information - Provider Versions: Keep provider versions pinned to avoid unexpected changes
- Testing: Always run
terraform planbeforeapply - Backup: Keep backups of state files if using local state
- Documentation: Update this file when adding new infrastructure patterns
Security Considerations
- Use SOPS for all secrets - never commit plain-text credentials
- Enable encryption at rest for S3 buckets and databases
- Use least-privilege IAM policies
- Regularly rotate access keys and tokens
- Enable MFA for production infrastructure access
- Review and audit infrastructure changes regularly
Getting Help
- Terraform Documentation: https://www.terraform.io/docs
- AWS Provider Docs: https://registry.terraform.io/providers/hashicorp/aws/latest/docs
- GitHub Provider Docs: https://registry.terraform.io/providers/integrations/github/latest/docs
- SOPS Documentation: https://github.com/mozilla/sops
When Working with Infrastructure Code
- Always Plan First: Run
terraform planbefore any apply - Small Changes: Make incremental changes and test frequently
- Documentation: Document complex configurations inline
- State Awareness: Be aware of state management and locking
- Security First: Never compromise on security for convenience
- Validate: Use
terraform validateandterraform fmtbefore committing - Review: Carefully review plan output before applying
- Backup: Ensure state files are backed up (if not using remote state)