TerraGuard

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.

Loading diagram...

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-api

3. Push to ECR

Images are pushed to AWS ECR repositories under the terra-guard/ namespace:

ServiceECR Repository
tg-web-searchterra-guard/tg-web-search
tg-web-crawlerterra-guard/tg-web-crawler
tg-geo-popterra-guard/tg-geo-pop
tg-backend-apiterra-guard/tg-backend-api
tg-event-processorterra-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-1

Service Workflows

PropertyValue
Workflow file.github/workflows/deploy-search.yml
Trigger pathtg-search-api/**
ECR repositoryterra-guard/tg-web-search
Deploy targetServer B

tg-web-crawler

PropertyValue
Workflow file.github/workflows/deploy-crawler.yml
Trigger pathtg-web-crawler-api/**
ECR repositoryterra-guard/tg-web-crawler
Deploy targetServer B

tg-geo-pop

PropertyValue
Workflow file.github/workflows/deploy-geopop.yml
Trigger pathgeopop-api/**
ECR repositoryterra-guard/tg-geo-pop
Deploy targetServer B

tg-backend-api

PropertyValue
Workflow file.github/workflows/deploy-backend.yml
Trigger pathtg-backend-api/**
ECR repositoryterra-guard/tg-backend-api
Deploy targetApp 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:

SecretDescription
AWS_ACCESS_KEY_IDIAM user access key with ECR and SSM permissions
AWS_SECRET_ACCESS_KEYIAM user secret key
ECR_REGISTRYECR registry URL (e.g., 123456789.dkr.ecr.us-east-1.amazonaws.com)
SERVER_B_INSTANCE_IDEC2 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 --log

Verify 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.

On this page