DevSecOps AWS Pipeline

A GitHub Actions delivery pipeline with source, container, infrastructure, and policy checks.

By Himan MandujaSource reviewed Reviewed commit bf71c43 ↗

On this page
  1. Several different security questions
  2. Policy against the planned infrastructure
  3. The application network
  4. Approval and deployment
  5. Enforcement and evidence
  6. Source files

A pipeline is only a security control when its findings change what can be released. This project combines source, image, infrastructure, and policy checks in GitHub Actions, then deploys a split frontend/backend application to AWS ECS.

The interesting work is not the number of scanner logos. It is the relationship between inputs, blocking behavior, the Terraform plan, AWS identity, and the approval boundary. Reading those details also exposes places where the implementation is more permissive than its README description.

Several different security questions

The workflow starts with secret scanning and change detection, runs relevant application lint/build jobs, and publishes SHA-tagged images to GHCR. Trivy scans container images for high and critical findings with a failing exit code configured.

Infrastructure goes through Terraform format and validation plus Checkov. These tools answer different questions: a valid Terraform configuration can still contain an unsafe security group, and an image that builds can still contain vulnerable packages. Keeping the checks visible makes that distinction easier to audit.

Security gates and the AWS runtime boundaryPlan/apply is separate from the runtime request path. Production reviewer requirements must be configured in GitHub Environment settings. Components: GitHub event, Source + image checks; Security checks, Trivy · Checkov · OPA; Terraform plan, Saved deployment plan; Production gate, Environment reviewers; Terraform apply, OIDC role; Public ALB, Internet entry; Frontend ECS, Next.js proxy; Internal ALB, Private API entry; Backend ECS, Private Fargate tasks.PRIVATE SUBNETS / TWO AZsGitHub eventSource + image checksSecurity checksTrivy · Checkov · OPATerraform planSaved deployment planProduction gateEnvironment reviewersTerraform applyOIDC rolePublic ALBInternet entryFrontend ECSNext.js proxyInternal ALBPrivate API entryBackend ECSPrivate Fargate tasks
Architecture reconstructed from the linked implementation.Swipe to inspect →
Plan/apply is separate from the runtime request path. Production reviewer requirements must be configured in GitHub Environment settings.
GitHub Actions Trivy container scan output for the backend image
The captured Trivy job reports zero HIGH and CRITICAL findings for the scanned backend image. This is one image scan, not a guarantee about later builds. Repository source ↗

Policy against the planned infrastructure

Conftest/OPA evaluates the Terraform plan’s JSON representation. The repository’s Rego policies cover public backend exposure, broadly open administrative or database ports, and required project/environment/management tags.

Checking the plan rather than only searching source text provides a policy boundary around the resources Terraform intends to create or change. The policies are still a defined subset of security requirements. Passing them does not prove that every IAM permission, runtime route, or application behavior is safe.

GitHub Actions OPA policy job showing fourteen passing tests
The OPA job records 14 tests and 14 passes against a Terraform plan. The selected policies define the scope of that result. Repository source ↗

The application network

Terraform creates public and private subnets across two availability zones, with a NAT Gateway in each zone. A public ALB routes to frontend Fargate tasks in private subnets. The frontend’s Next.js server proxies API requests through an internal ALB to backend tasks.

The security-group chain follows that topology: frontend ingress comes from the public load balancer, the internal load balancer accepts the frontend group, and backend ingress comes from that internal load balancer. The checked task settings allocate 512 CPU units and 1024 MiB, with a desired count of two. CPU target tracking is configured at 70%, and the capacity-provider strategy includes Fargate Spot.

This architecture trades extra NAT and load-balancer resources for separate network entry points and per-zone egress. Spot capacity also means interruption handling belongs in the operational discussion. The configuration alone is not an interruption-recovery test.

Approval and deployment

AWS authentication uses GitHub OIDC with a repository-specific trust condition. The apply job references the GitHub production environment and applies a saved Terraform plan. Required human reviewers must be configured on that environment outside the workflow file; the environment name alone does not create that reviewer policy.

The workflow also contains post-apply drift detection, policy evaluation, and documentation/image-tag update stages. Infrastructure planning and applying are gated to qualifying main-branch push or manual paths in the checked workflow, so this article does not describe every pull request as receiving an apply-ready plan.

GitHub Actions production deployment approval dialog while the workflow waits
The run is waiting for a production deployment review, with the approval dialog open. This captures the gate, not a completed apply. Repository source ↗

Enforcement and evidence

One concrete discrepancy is npm audit --audit-level=high || true: it reports findings but explicitly suppresses failure. That differs from a blocking audit gate. Checkov also has learning-project exclusions, and the AWS role includes broad service permissions with wildcard resources. OIDC removes long-lived credentials, but does not by itself make that role least-privilege.

HTTPS is optional and disabled by default in the checked configuration. Existing AWS and approval screenshots document an earlier exercise, while the README’s deployment output is dated December 2025. A documentation-site deployment proves publication of the project page, not current operation of the AWS stack.

The useful next step is to tighten the connection between stated policy and actual enforcement: decide which findings must block, constrain the deployment role, configure required reviewers, and validate the conditional job graph for both application and infrastructure-only changes.

Source files