CI/CD Pipelines
GitHub Actions workflows for building, testing, and deploying TerraGuard services to AWS ECR and Server B.
Overview
Each TerraGuard service has its own GitHub Actions workflow that follows a consistent pattern: push to main triggers a Docker image build, pushes the image to AWS ECR, and deploys to the target environment via AWS SSM Run Command.
Pipeline Pattern
All service pipelines share this structure:
1. Trigger
Workflows trigger on pushes to main that modify files in the service's directory. This prevents unnecessary builds when unrelated code changes.
on:
push:
branches: [main]
paths:
- 'tg-search-api/**'
- '.github/workflows/deploy-search.yml'2. Build
Docker images are built for the linux/arm64 platform to match Server B's Graviton3 processor. Multi-stage Dockerfiles keep final images small.
- name: Build Docker image
run: |
docker buildx build \
--platform linux/arm64 \
--tag $ECR_REGISTRY/$ECR_REPOSITORY:latest \
--tag $ECR_REGISTRY/$ECR_REPOSITORY:${{ github.sha }} \
--push \
./tg-search-api3. Push to ECR
Images are pushed to AWS ECR repositories under the terra-guard/ namespace:
| Service | ECR Repository |
|---|---|
| tg-web-search | terra-guard/tg-web-search |
| tg-web-crawler | terra-guard/tg-web-crawler |
| tg-geo-pop | terra-guard/tg-geo-pop |
| tg-backend-api | terra-guard/tg-backend-api |
| tg-event-processor | terra-guard/tg-event-processor |
Each image is tagged with both latest and the commit SHA for traceability.
4. Deploy
Deployment uses AWS SSM Run Command to execute a shell script on Server B. This avoids opening SSH ports and provides audit logging through SSM.
- name: Deploy to Server B
run: |
aws ssm send-command \
--instance-ids ${{ secrets.SERVER_B_INSTANCE_ID }} \
--document-name "AWS-RunShellScript" \
--parameters 'commands=[
"cd /opt/terraguard",
"aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin ${{ secrets.ECR_REGISTRY }}",
"docker compose pull $SERVICE_NAME",
"docker compose up -d $SERVICE_NAME"
]' \
--region us-east-1Service Workflows
tg-web-search
| Property | Value |
|---|---|
| Workflow file | .github/workflows/deploy-search.yml |
| Trigger path | tg-search-api/** |
| ECR repository | terra-guard/tg-web-search |
| Deploy target | Server B |
tg-web-crawler
| Property | Value |
|---|---|
| Workflow file | .github/workflows/deploy-crawler.yml |
| Trigger path | tg-web-crawler-api/** |
| ECR repository | terra-guard/tg-web-crawler |
| Deploy target | Server B |
tg-geo-pop
| Property | Value |
|---|---|
| Workflow file | .github/workflows/deploy-geopop.yml |
| Trigger path | geopop-api/** |
| ECR repository | terra-guard/tg-geo-pop |
| Deploy target | Server B |
tg-backend-api
| Property | Value |
|---|---|
| Workflow file | .github/workflows/deploy-backend.yml |
| Trigger path | tg-backend-api/** |
| ECR repository | terra-guard/tg-backend-api |
| Deploy target | App Runner (auto-deploys on ECR push) |
The backend API differs from the Server B services -- App Runner is configured to auto-deploy when a new image is pushed to its ECR repository, so no SSM step is needed.
Required Secrets
The following GitHub Actions secrets must be configured in each repository:
| Secret | Description |
|---|---|
AWS_ACCESS_KEY_ID | IAM user access key with ECR and SSM permissions |
AWS_SECRET_ACCESS_KEY | IAM user secret key |
ECR_REGISTRY | ECR registry URL (e.g., 123456789.dkr.ecr.us-east-1.amazonaws.com) |
SERVER_B_INSTANCE_ID | EC2 instance ID for Server B (i-05033852181296c97) |
SSH Key
The terraguard-search-vps SSH key is used for direct access to Server B when debugging is needed. It is stored in the repository secrets and should only be used as a last resort -- prefer SSM for all remote operations.
Monitoring Deployments
Check Workflow Status
# List recent workflow runs
gh run list --repo TerraGuard/tg-web-search --limit 5
# View a specific run
gh run view <run-id> --repo TerraGuard/tg-web-search --logVerify Deployment
After a deployment completes, verify the service is running with the expected version:
# Check the deployed image SHA
aws ssm send-command \
--profile tg \
--instance-ids i-05033852181296c97 \
--document-name "AWS-RunShellScript" \
--parameters 'commands=["docker inspect --format={{.Image}} tg-search-api"]'Rollback
To roll back to a previous version, deploy a specific image tag:
aws ssm send-command \
--profile tg \
--instance-ids i-05033852181296c97 \
--document-name "AWS-RunShellScript" \
--parameters 'commands=[
"cd /opt/terraguard",
"docker compose pull tg-search-api:abc123def",
"docker compose up -d tg-search-api"
]'Replace abc123def with the commit SHA of the version you want to restore.
Server B Deployment
Deployment architecture for Server B, the EC2 instance hosting TerraGuard's crawler and geocoding services with Caddy reverse proxy and automated CI/CD.
Backend API Reference
Complete REST API reference for the TerraGuard backend, covering event management, news, knowledge base, reports, notifications, and ingestion endpoints.