Skip to content

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-test and howard-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

  1. Go to the CampusCore GitHub repo > Settings > Environments
  2. Click New environment
  3. 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-test
  • howard-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_ARN is 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_ID is 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