|
| 1 | +# GitHub Actions Workflows |
| 2 | + |
| 3 | +This directory contains automated workflows for infrastructure and site deployment. |
| 4 | + |
| 5 | +## Workflows |
| 6 | + |
| 7 | +### 1. Terragrunt Plan (`terragrunt-plan.yml`) |
| 8 | + |
| 9 | +**Triggers:** |
| 10 | +- Pull requests to `main` branch that modify `terragrunt/**` files |
| 11 | +- Manual dispatch |
| 12 | + |
| 13 | +**Purpose:** |
| 14 | +- Plans infrastructure changes across all Terragrunt modules |
| 15 | +- Posts plan results as PR comments for review |
| 16 | +- Validates Terraform syntax and dependencies |
| 17 | + |
| 18 | +**What it does:** |
| 19 | +1. Checks out code |
| 20 | +2. Sets up Terraform and Terragrunt |
| 21 | +3. Authenticates with AWS using OIDC |
| 22 | +4. Runs `terragrunt run --all init` |
| 23 | +5. Runs `terragrunt run --all plan` |
| 24 | +6. Comments plan output on PR |
| 25 | + |
| 26 | +### 2. Terragrunt Apply (`terragrunt-apply.yml`) |
| 27 | + |
| 28 | +**Triggers:** |
| 29 | +- Pushes to `main` branch that modify `terragrunt/**` files |
| 30 | +- Manual dispatch |
| 31 | + |
| 32 | +**Purpose:** |
| 33 | +- Deploys infrastructure changes to AWS |
| 34 | +- Creates/updates: Route53, ACM certificates, CloudFront, S3 bucket |
| 35 | + |
| 36 | +**What it does:** |
| 37 | +1. Checks out code |
| 38 | +2. Sets up Terraform and Terragrunt |
| 39 | +3. Authenticates with AWS using OIDC |
| 40 | +4. Runs `terragrunt run --all init` |
| 41 | +5. Runs `terragrunt run --all apply -auto-approve` |
| 42 | +6. Outputs Route53 nameservers for domain registration |
| 43 | + |
| 44 | +**Important:** After first run, manually update your domain registrar with the Route53 nameservers shown in the workflow output. |
| 45 | + |
| 46 | +### 3. Deploy Jekyll Site (`deploy-site.yml`) |
| 47 | + |
| 48 | +**Triggers:** |
| 49 | +- Pushes to `main` branch that modify site content (pages, posts, assets, config) |
| 50 | +- Manual dispatch |
| 51 | + |
| 52 | +**Purpose:** |
| 53 | +- Builds Jekyll site for production |
| 54 | +- Deploys to S3 bucket |
| 55 | +- Invalidates CloudFront cache for immediate updates |
| 56 | + |
| 57 | +**What it does:** |
| 58 | +1. Checks out code |
| 59 | +2. Sets up Ruby and installs dependencies |
| 60 | +3. Builds Jekyll site with `JEKYLL_ENV=production` |
| 61 | +4. Authenticates with AWS using OIDC |
| 62 | +5. Syncs `_site/` to S3 with appropriate cache headers: |
| 63 | + - Static assets: 1 hour cache |
| 64 | + - HTML files: 5 minute cache |
| 65 | + - Manifest: no cache |
| 66 | +6. Finds CloudFront distribution |
| 67 | +7. Creates cache invalidation for immediate updates |
| 68 | +8. Reports deployment status |
| 69 | + |
| 70 | +**Cache Strategy:** |
| 71 | +- **Assets (CSS, JS, images):** 1 hour (`max-age=3600`) |
| 72 | + - Balance between CDN efficiency and update speed |
| 73 | +- **HTML files:** 5 minutes (`max-age=300`) |
| 74 | + - Quick content updates while still leveraging cache |
| 75 | +- **manifest.json:** No cache |
| 76 | + - Always gets latest version |
| 77 | + |
| 78 | +## Workflow Order |
| 79 | + |
| 80 | +For initial setup: |
| 81 | + |
| 82 | +1. **First:** Run `terragrunt-apply` to create infrastructure |
| 83 | + - Creates S3 bucket, CloudFront distribution, ACM certificate, Route53 zone |
| 84 | + - Note the Route53 nameservers output |
| 85 | + |
| 86 | +2. **Second:** Update domain nameservers at your registrar |
| 87 | + - Use nameservers from previous step |
| 88 | + - Wait for DNS propagation (can take 24-48 hours) |
| 89 | + |
| 90 | +3. **Third:** Run `deploy-site` to upload website |
| 91 | + - Builds and deploys Jekyll site to S3 |
| 92 | + - Configures CloudFront for global distribution |
| 93 | + |
| 94 | +For ongoing development: |
| 95 | + |
| 96 | +- **Content changes** (posts, pages) → triggers `deploy-site` only |
| 97 | +- **Infrastructure changes** (terragrunt configs) → triggers `terragrunt-plan` on PRs, `terragrunt-apply` on merge |
| 98 | + |
| 99 | +## Required Secrets |
| 100 | + |
| 101 | +Set these in GitHub repository settings (`Settings` → `Secrets and variables` → `Actions`): |
| 102 | + |
| 103 | +- `AWS_ACCOUNT_ID` - Your 12-digit AWS account ID |
| 104 | + |
| 105 | +## IAM Role Setup |
| 106 | + |
| 107 | +The workflows use AWS OIDC authentication (no access keys stored in GitHub). |
| 108 | + |
| 109 | +**One-time setup required:** |
| 110 | + |
| 111 | +```bash |
| 112 | +cd terragrunt/bootstrap |
| 113 | +terraform init |
| 114 | +terraform apply |
| 115 | +``` |
| 116 | + |
| 117 | +This creates: |
| 118 | +- GitHub OIDC provider |
| 119 | +- `github-actions-terragrunt-role` IAM role |
| 120 | +- Necessary permissions for S3, CloudFront, Route53, ACM |
| 121 | + |
| 122 | +See [terragrunt/bootstrap/README.md](../terragrunt/bootstrap/README.md) for details. |
| 123 | + |
| 124 | +## Manual Workflow Dispatch |
| 125 | + |
| 126 | +All workflows can be triggered manually: |
| 127 | + |
| 128 | +1. Go to `Actions` tab in GitHub |
| 129 | +2. Select workflow from left sidebar |
| 130 | +3. Click `Run workflow` button |
| 131 | +4. Select branch (usually `main`) |
| 132 | +5. Click green `Run workflow` button |
| 133 | + |
| 134 | +## Monitoring |
| 135 | + |
| 136 | +- **Plan/Apply progress:** Check `Actions` tab for real-time logs |
| 137 | +- **Infrastructure state:** Stored in S3 bucket `gcharest-terraform-state-{account-id}` |
| 138 | +- **Website:** https://www.gcharest.ca/ |
| 139 | +- **CloudFront:** View distribution in AWS Console |
| 140 | + |
| 141 | +## Troubleshooting |
| 142 | + |
| 143 | +### "403 Forbidden" errors |
| 144 | +- IAM role not set up or lacks permissions |
| 145 | +- Run bootstrap terraform (see above) |
| 146 | +- Verify `AWS_ACCOUNT_ID` secret is set correctly |
| 147 | + |
| 148 | +### CloudFront cache not invalidating |
| 149 | +- Check CloudFront distribution exists |
| 150 | +- Workflow queries by comment: "Blog distribution for gcharest" |
| 151 | +- Verify distribution was created by terragrunt-apply |
| 152 | + |
| 153 | +### Jekyll build failures |
| 154 | +- Check Ruby version in `deploy-site.yml` matches local development |
| 155 | +- Verify Gemfile.lock is committed |
| 156 | +- Review build logs in Actions tab |
| 157 | + |
| 158 | +### DNS not resolving |
| 159 | +- Nameservers updated at domain registrar? |
| 160 | +- DNS propagation can take 24-48 hours |
| 161 | +- Use `dig gcharest.ca NS` to check current nameservers |
0 commit comments