NewGenShield™ now available — AI security scanning for AWS Bedrock agents · Learn more →
GitHub Actions + AWS: The CI/CD Stack That Actually Works at Scale
DevOps

GitHub Actions + AWS: The CI/CD Stack That Actually Works at Scale

G
GenClouds Team
January 14, 2025
GitHub Actions + AWS: The CI/CD Stack That Actually Works at Scale

The Problem With Most CI/CD Setups

Most CI/CD setups start simple and become a liability. What began as three workflow files becomes a sprawl of YAML that nobody fully understands, with shared secrets that never rotate, deployment pipelines that take 45 minutes, and a single broken workflow that blocks the whole team on a Friday afternoon.

Here is how we design GitHub Actions + AWS CI/CD pipelines that stay clean and maintainable as you scale from 5 to 50 engineers.

The Architecture Principles

Before touching a workflow file, we establish three principles:

  1. No long-lived AWS credentials in GitHub Secrets. Use OIDC (OpenID Connect) to generate short-lived credentials per workflow run. This eliminates the credential rotation problem entirely and is the AWS-recommended approach.
  2. Every environment has an explicit promotion gate. Code promotes from dev → staging → production through explicit approval steps. No automatic production deployments unless you have a genuinely mature test suite and are prepared to own the consequences.
  3. Workflows are reusable. Common patterns (build, test, deploy) are extracted into reusable workflows and called from application-level workflows. DRY applies to YAML too.

OIDC: How It Works and Why You Need It

Traditional GitHub Actions AWS deployments use an IAM user with long-lived access keys stored in GitHub Secrets. This is a security liability — keys that are never rotated, scoped to an entire account, and potentially exposed through workflow logs.

OIDC replaces this with a trust relationship between GitHub Actions and AWS IAM. Each workflow run gets a short-lived token (15 minutes by default) with the exact permissions needed for that specific workflow. No stored credentials. No rotation burden. No blast radius if a secret is accidentally logged.

The setup is a one-time IAM configuration: create an OIDC identity provider for GitHub Actions, create a role with the minimum permissions needed, and scope the trust policy to the specific repository and branch.

The Environment Promotion Model

We use three environment tiers with explicit gates:

  • Dev: Auto-deploys on every push to the main branch. Fast feedback loop. Allowed to break.
  • Staging: Auto-deploys after all tests pass on main. Mirrors production configuration. Used for QA and integration testing.
  • Production: Manual approval gate. One or two designated approvers. Deployment only during defined windows unless an emergency override is explicitly triggered.

GitHub Environments enforce this model natively — environment protection rules, required reviewers, and deployment history are all first-class GitHub features.

Pipeline Performance: From 45 Minutes to 8 Minutes

Slow pipelines kill developer velocity. Every minute of CI wait time is a context-switch cost multiplied across the team. Here is where time gets wasted and how we recover it:

  • Dependency caching: Cache node_modules, .pip, Maven, etc. A 3-minute npm install becomes a 15-second cache hit.
  • Parallel jobs: Unit tests, integration tests, security scans, and lint checks run in parallel. The total pipeline time is the slowest job, not the sum of all jobs.
  • Test splitting: For large test suites, split tests across multiple runners using a matrix strategy. 500 tests across 5 runners = 1/5 the time.
  • Conditional execution: Infrastructure jobs only run when Terraform files change. Frontend jobs only run when frontend code changes. Use path filters aggressively.

Security Scanning in the Pipeline

Security gates should be automatic, not manual. We integrate:

  • Checkov — IaC security scanning for Terraform and CloudFormation. Fails the build on HIGH severity findings.
  • Trivy — Container image vulnerability scanning. Blocks deployment of images with known HIGH/CRITICAL CVEs.
  • Semgrep — SAST (static application security testing) for Python, TypeScript, and Go.
  • Secret scanning — GitHub's native secret scanning catches accidentally committed credentials before they hit the main branch.

Security scans add 2-4 minutes to a pipeline and catch issues that would otherwise reach production or, worse, reach a security audit.

Infrastructure Deployment with Terraform

For infrastructure changes, we use a specific pattern:

  • On PR open: terraform plan runs automatically and posts the plan output as a PR comment. Engineers review what will change before approving.
  • On PR merge to main: terraform apply runs automatically for dev environments.
  • For staging and production: terraform apply is a manual workflow dispatch with a required approver.

State is stored in S3 with DynamoDB locking. State files are never in the repository.

The Result

A well-designed CI/CD pipeline is an engineering force multiplier. It gives your team confidence to deploy frequently, catches issues early, and eliminates the "works on my machine" class of production incidents.

If your current CI/CD setup feels like a liability rather than an asset, talk to us. We typically have a new pipeline design ready within a week.

← Back to Blog
Share articleXinlk
Free Consultation

Ready to put this
into practice?

Book a free 30-minute AWS consultation with our certified team. No sales pitch — just answers.