02 — Pipeline Setup¶
Scope: Per-client. Create the Terraform state bucket, GitHub Environment, deploy branch, and populate all secrets and variables.
Time: ~15 minutes
Prerequisites¶
- All API keys from Step 01
- SSL decision confirmed with client: CampusCore-managed SSL (recommended) or self-managed SSL
2a. Create TF State Bucket (Our Admin Account)¶
Time: ~5 minutes
Create an S3 bucket in our admin AWS account (not the client's account) for the client's Terraform state:
# Authenticate to the ADMIN account
export AWS_PROFILE=campuscore-admin
# Create the state bucket
./scripts/create-new-client-tf-state-bucket.sh howard
This creates campuscore-tfstate-howard with:
- Versioning enabled
- Server-side encryption (AES256)
- Public access blocked
One bucket per client, not per environment. If a client has multiple environments (e.g.,
howard-testandhoward-prod), they all share the same state bucket. Terraform isolates environments using separate state key paths (tfstate/howard-test,tfstate/howard-prod) and workspaces within the bucket.
2b. Create the GitHub Environment¶
- Go to the CampusCore GitHub repo > Settings > Environments
- Click New environment
- Name it to match the client identifier (e.g.,
howard)
Multi-Environment Clients¶
If a client needs multiple environments (e.g., test and prod), create a separate GitHub Environment for each:
howard-testhoward-prod
Each environment gets its own set of secrets and variables. Most values are identical across environments (API keys, TF_STATE_BUCKET), but some will differ (e.g., CUSTOM_DOMAIN_WITH_PROTOCOL, DB_PASSWORD).
2c. Generate Deployment Secrets¶
./scripts/generate-secrets.sh howard # single environment
./scripts/generate-secrets.sh howard-prod # multi-environment
The script will:
1. Auto-generate DB_PASSWORD, DJANGO_SECRET_KEY, and APP_FERNET_KEY
2. Ask if you want to upload them directly to the GitHub Environment via gh secret set
3. If uploading, optionally prompt for client-provided secrets (API keys) one by one
4. If not uploading, display all gh secret set commands for copy-paste
2d. Set Environment Variables¶
Note:
AWS_ROLE_ARNis not set here — the client needs to deploy their IAM role first. You will set it in Step 03 before triggering the deployment.
Single Environment¶
# Terraform state bucket
gh variable set TF_STATE_BUCKET --env howard --body "campuscore-tfstate-howard"
# AWS region (optional, defaults to us-east-1)
gh variable set AWS_REGION --env howard --body "us-east-1"
# Custom domain with SSL — provisions {env}.campuscoreai.com subdomain + HTTPS
gh variable set ENABLE_CUSTOM_DOMAIN_WITH_SSL --env howard --body "true"
Multiple Environments¶
Set the same variables on each GitHub Environment:
# --- howard-test ---
gh variable set TF_STATE_BUCKET --env howard-test --body "campuscore-tfstate-howard"
gh variable set AWS_REGION --env howard-test --body "us-east-1"
gh variable set ENABLE_CUSTOM_DOMAIN_WITH_SSL --env howard-test --body "true"
# --- howard-prod ---
gh variable set TF_STATE_BUCKET --env howard-prod --body "campuscore-tfstate-howard"
gh variable set AWS_REGION --env howard-prod --body "us-east-1"
gh variable set ENABLE_CUSTOM_DOMAIN_WITH_SSL --env howard-prod --body "true"
2e. Set Environment Secrets¶
Generated by Us (from generate-secrets.sh output)¶
gh secret set DB_USERNAME --env howard --body "campuscore_admin"
gh secret set DB_PASSWORD --env howard --body "<generated>"
gh secret set DJANGO_SECRET_KEY --env howard --body "<generated>"
gh secret set APP_FERNET_KEY --env howard --body "<generated>"
Provided by Client¶
gh secret set OPENAI_API_KEY --env howard --body "<from-client>"
gh secret set GEMINI_API_KEY --env howard --body "<from-client>"
gh secret set COHERE_API_KEY --env howard --body "<from-client>"
2f. Custom Domain with SSL¶
Set ENABLE_CUSTOM_DOMAIN_WITH_SSL=true (recommended for all deployments). The pipeline auto-provisions {env}.campuscoreai.com with an ACM certificate and HTTPS on the ALB.
What the client needs to do (after deployment):
- Create a CNAME record: ai.university.edu -> {env}.campuscoreai.com
- If using Cloudflare, set SSL mode to "Full" or "Full (strict)" since CampusCore serves HTTPS
Resulting env variables:
| Variable | Value |
|----------|-------|
| ENABLE_CUSTOM_DOMAIN_WITH_SSL | true |
| CUSTOM_DOMAIN_WITH_PROTOCOL | (auto-computed as https://{env}.campuscoreai.com) |
When set to false (or omitted), no subdomain, certificate, or HTTPS listener is provisioned. The ALB serves HTTP only and the custom domain settings UI is hidden.
Note:
CAMPUSCORE_HOSTED_ZONE_IDis a repo-level variable (already configured — see Repo & Pipeline Setup), not per-environment.
2g. Deploy Branch¶
Deployments are triggered by pushing to a deploy/{client} branch. The branch name determines which GitHub Environment the pipeline uses.
# Single environment — branch name matches the GitHub Environment name
# deploy/howard → uses the "howard" GitHub Environment
git push origin main:deploy/howard
# Multi-environment
# deploy/howard-test → uses "howard-test" GitHub Environment
# deploy/howard-prod → uses "howard-prod" GitHub Environment
You don't need to create these branches ahead of time — the first git push creates them. But be aware of the naming convention: the branch suffix after deploy/ must match the GitHub Environment name exactly.
2h. Verify¶
# List environment variables
gh variable list --env howard
# List environment secrets (names only — values are write-only)
gh secret list --env howard
Confirm all variables and secrets are set except AWS_ROLE_ARN (set in the next step).
See GitHub Environment Variables Reference for the complete specification.
Next: 03 — Deployment