Skip to content

feat: CodeBuild+Terraform runtime for EKS repo creation #17

Merged
merged 14 commits into from
Apr 21, 2026
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 113 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# GitHub Copilot Instructions — terraform-eks-deployment

## Project Context

This is the **Terraform workspace** that creates EKS cluster GitHub repositories as part of the
EKS Cluster Automation (ECA) system. It is run by a CodeBuild project (`eks-terragrunt-repo-creator`)
triggered at runtime by the `eks-terragrunt-repo-gen-template-automation` Lambda function.

---

## Architecture: Lambda → CodeBuild → Terraform

EKS cluster repos are created via this chain:

```
SC Console → CFN Stack → Custom::GitHubRepository
→ Lambda (eks-terragrunt-repo-gen-template-automation)
→ CodeBuild project (eks-terragrunt-repo-creator) ← this repo runs here
→ git clone terraform-eks-deployment (REPO_BRANCH)
→ terraform init (providers from registry.terraform.io via Census proxy)
→ terraform apply -auto-approve
→ CSVD/terraform-github-repo module:
→ Creates GHE repo from template-eks-cluster
→ Writes 8 rendered Terragrunt HCL files via managed_extra_files
→ Opens pull request (repo-init → main)
→ Lambda polls build → fetches PR URL → cfn-response SUCCESS
```

### CodeBuild environment

CodeBuild runs on `aws/codebuild/amazonlinux2-x86_64-standard:3.0` (Amazon Linux 2).
Key env vars injected by the Lambda at build-start time:

| Variable | Source | Purpose |
|----------|--------|---------|
| `GITHUB_TOKEN` | Secrets Manager `ghe-runner/github-token` (PAT, `ghp_`) | Terraform GitHub provider auth; git clone |
| `TF_VAR_name` | CFN input `project_name` | Repo name |
| `TF_VAR_environment` | CFN input `environment` | e.g. `dev` |
| `TF_VAR_region` | CFN input `aws_region` | e.g. `us-gov-west-1` |
| `TF_VAR_cluster_config` | JSON-encoded EKS fields | `vpc_name`, `vpc_domain_name`, `cluster_name`, etc. |
| `TF_VAR_finops` | JSON-encoded FinOps fields | project name/number |
| `GITHUB_OWNER` | `SCT-Engineering` | GitHub org for provider |
| `GITHUB_BASE_URL` | `https://github.e.it.census.gov` | GHE API base URL |

The buildspec is inlined from this repo's `buildspec.yml` into the
`aws_codebuild_project.eks_repo_creator` resource in `lambda-template-repo-generator/deploy/main.tf`.
After editing `buildspec.yml`, run `tf apply` in `lambda-template-repo-generator/deploy/` to update.

---

## Key Files

| File | Purpose |
|------|--------|
| `buildspec.yml` | CodeBuild build steps: install Terraform + Census CA cert, clone repo, tf init + apply |
| `main.tf` | Module call to `CSVD/terraform-github-repo`; `managed_extra_files` with rendered HCL |
| `providers.tf` | GitHub provider config (`>= 6.11.0`, `insecure = true`) + AWS provider |
| `variables.tf` | All TF_VAR_* inputs from CodeBuild env (name, environment, region, cluster_config, finops) |
| `locals.tf` | Decodes `cluster_config` JSON; resolves HCL template content |
| `defaults.tf` | Default values for template repo org, template name, org name |
| `callnotes.md` | Session notes and fix log |

---

## SC Product Deployment Methods

See `lambda-template-repo-generator/.github/copilot-instructions.md` for full details.
Both methods use the same CFN product template; they must stay in sync.

- **Method 1** (testing): `cd lambda-template-repo-generator/deploy && tf apply`
- **Method 2** (production): `cd terraform-service-catalog-census/non-prod/csvd-dev/west/service-catalog && tf apply`

Always verify Method 1 works first when debugging a census deployment issue.

---

## Key Resources

| Resource | Location | Purpose |
|----------|----------|---------|
| Lambda | `eks-terragrunt-repo-gen-template-automation` (us-gov-west-1, 229685449397) | CFN Custom Resource handler; starts CodeBuild |
| CodeBuild (repo creation) | `eks-terragrunt-repo-creator` | Runs this workspace via tf apply |
| CodeBuild (image build) | `eks-terragrunt-repo-generator-builder` | Builds Lambda container via packer |
| S3 assets bucket | `csvd-packer-pipeline-assets` | Terraform binary, Census CA cert, Packer binary |
| GitHub token (Terraform) | Secrets Manager `ghe-runner/github-token` | PAT (`ghp_`) for Terraform GitHub provider |
| GitHub token (Lambda) | Secrets Manager `/eks-cluster-deployment/github_token` | App token (`ghs_`) for Lambda Python API calls |
| CSVD TF module | `https://github.e.it.census.gov/CSVD/terraform-github-repo` | Creates repo + files + PR |
| Census SC product template | `terraform-service-catalog-census/templates/products/eks-terragrunt-repo/2-0-0.yaml` | Live SC product CFN template |
| Canonical SC product template | `lambda-template-repo-generator/service-catalog/product-template.yaml` | Reference/source of truth |

---

## Important Runtime Notes

- **Terraform binary** is installed from `s3://csvd-packer-pipeline-assets/terraform/terraform_1.9.1_linux_amd64.zip` in the INSTALL phase — `releases.hashicorp.com` is blocked on the Census network
- **Census CA cert** is installed from `s3://csvd-packer-pipeline-assets/certs/census-ca.pem` via `update-ca-trust` — required for TLS to `github.e.it.census.gov`
- **Census proxy** `http://proxy.tco.census.gov:3128` must be set as `HTTPS_PROXY`/`HTTP_PROXY` — required for `registry.terraform.io` provider downloads
- **`github.e.it.census.gov`** must be in `NO_PROXY` — direct connection (not via proxy)
- **GitHub provider version** must be `>= 6.11.0` — required by `CSVD/terraform-github-repo` module's `~> 6.11` constraint
- **`provider "github" { insecure = true }`** in `providers.tf` — belt-and-suspenders for TLS
- Pass `vpc_name` (string) — **not** `vpc_id` — or `is_eks_deployment` in the Lambda returns `False`

---

## What NOT to Do

- ❌ Do not switch back to a Lambda-Python-only repo creation approach — all repo creation must run through CodeBuild + this Terraform workspace (single maintenance point)
- ❌ Do not use `HappyPathway/terraform-github-repo` **public** module — pins `github ~> 6.0`, conflicts with `>= 6.6.0` requirement
- ✅ DO use `CSVD/terraform-github-repo` (https://github.e.it.census.gov/CSVD/terraform-github-repo) — internal, supports `template_repo` + `managed_extra_files`
- ❌ Do not use SSH-based remote module sources (`git::ssh://`) — Census proxy blocks SSH host key exchange; use HTTPS
- ❌ Do not add `vpc_id` as a parameter to SC product templates — use `vpc_name`
- ❌ Do not write temp files or command output to `/tmp` — use `~/tmp` (i.e. `/home/a/arnol377/tmp`) instead
- ❌ Do not use the `terraform` command directly — always use the `tf` alias (e.g. `tf plan`, `tf apply`, `tf init`)
85 changes: 85 additions & 0 deletions buildspec.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
version: 0.2
# buildspec.yml — terraform-eks-deployment / eks-terragrunt-repo-creator
#
# This buildspec is used by the CodeBuild project that is triggered by the
# Lambda function (eks-terragrunt-repo-gen-template-automation) to create an
# EKS cluster GitHub repository.
#
# Required environment variables (injected by the Lambda as overrides):
# TF_VAR_name — cluster / repo name
# TF_VAR_environment — environment (dev / nonprod / prod)
# TF_VAR_region — AWS region (e.g. us-gov-west-1)
# TF_VAR_cluster_config — JSON object with account_name, aws_account_id, etc.
# TF_VAR_finops — JSON object with finops project_name / project_number
# GITHUB_TOKEN — GitHub PAT (passed from Lambda's Secrets Manager read)
# GITHUB_OWNER — GitHub org (default: SCT-Engineering)
# GITHUB_BASE_URL — GHE base URL (e.g. https://github.e.it.census.gov)

env:
variables:
TF_VERSION: "1.9.1"
ASSETS_BUCKET: "csvd-packer-pipeline-assets"
REPO_HOST: "github.e.it.census.gov"
REPO_ORG: "SCT-Engineering"
REPO_NAME: "terraform-eks-deployment"
REPO_BRANCH: "fix/eca-copilot-instructions-and-callnotes" # update to main once merged
# Disable TLS verification for Census GHE (Census CA cert not trusted by default)
GIT_SSL_NO_VERIFY: "true"
TF_CLI_ARGS: "-no-color"
# Census proxy — required for registry.terraform.io provider downloads
HTTPS_PROXY: "http://proxy.tco.census.gov:3128"
HTTP_PROXY: "http://proxy.tco.census.gov:3128"
# Exclude AWS-internal endpoints and Census GHE from the proxy
NO_PROXY: "169.254.169.254,169.254.170.2,s3.us-gov-west-1.amazonaws.com,s3.amazonaws.com,.amazonaws.com,.us-gov-west-1.amazonaws.com,github.e.it.census.gov"

phases:
install:
commands:
# ── Install Census Bureau CA certificate ──────────────────────────────
# The Census GHE TLS cert is issued by the Census Bureau CA which is not
# trusted by the CodeBuild Amazon Linux 2 trust store by default.
- |
aws s3 cp "s3://${ASSETS_BUCKET}/certs/census-ca.pem" \
/etc/pki/ca-trust/source/anchors/census-ca.pem 2>/dev/null \
&& update-ca-trust \
&& echo "Census CA cert installed" \
|| echo "WARNING: could not install Census CA cert (continuing anyway)"
# ── Install Terraform ─────────────────────────────────────────────────
- |
if ! command -v terraform &>/dev/null; then
TF_ZIP="terraform_${TF_VERSION}_linux_amd64.zip"
echo "Installing Terraform ${TF_VERSION}..."
aws s3 cp "s3://${ASSETS_BUCKET}/terraform/${TF_ZIP}" /tmp/${TF_ZIP} 2>/dev/null \
|| curl -fsSL "https://releases.hashicorp.com/terraform/${TF_VERSION}/${TF_ZIP}" -o /tmp/${TF_ZIP}
unzip -oq /tmp/${TF_ZIP} -d /usr/local/bin/
chmod +x /usr/local/bin/terraform
rm /tmp/${TF_ZIP}
fi
- terraform version

# ── Clone terraform-eks-deployment ───────────────────────────────────
- |
git config --global credential.helper \
"!f() { echo username=x-access-token; echo password=${GITHUB_TOKEN}; }; f"
git clone --depth 1 --branch "${REPO_BRANCH}" \
"https://${REPO_HOST}/${REPO_ORG}/${REPO_NAME}.git" \
/tmp/eks-deploy
- echo "Cloned ${REPO_ORG}/${REPO_NAME} @ $(git -C /tmp/eks-deploy rev-parse --short HEAD)"

build:
commands:
- cd /tmp/eks-deploy
- echo "=== terraform init ==="
- terraform init -no-color
- echo "=== terraform apply ==="
- terraform apply -auto-approve -no-color

post_build:
commands:
- |
if [ "${CODEBUILD_BUILD_SUCCEEDING}" = "0" ]; then
echo "Build FAILED — check logs above"
else
echo "Build SUCCEEDED — repository created"
fi
Loading
Loading