How to standardize and supercharge your CI/CD pipelines across projects
When your teams manage multiple projects with similar deployment patterns, repeating the same GitHub Actions steps over and over can become tedious, error-prone, and hard to maintain
Thankfully, GitHub Actions offers two powerful solutions to help standardize, reuse, and scale your CI/CD pipelines: Composite Actions and Reusable Workflows. When used together, they form a clean, modular, and DRY (donβt repeat yourself) CI/CD strategy
π Composite Actions vs Reusable Workflows
π§± Composite Actions
Composite Actions allow you to group steps (like docker build
, terraform plan
, or trivy scan
) into a reusable component. Think of it like a function.
Best for:
- Reusing logic (e.g., build and push images)
- Hiding complex logic from the main workflow
- Keeping workflows minimal and maintainable
Use it with:
uses: ./.github/actions/your-action
π Reusable Workflows
Reusable Workflows are full workflows that can be invoked with inputs and secrets.
Best for:
- High-level CI/CD orchestration (build, test, scan, deploy)
- Enforcing common practices across repositories
- Abstracting full pipelines
Use it with:
uses: org/repo/.github/workflows/your-workflow.yml@ref
π³ Example: Docker Build and Scan with Trivy
Here is an example of a composite action to build and push a Docker image to Azure Container Registry (ACR) and scan it using Trivy.
.github/actions/build-and-scan/action.yml
name: Docker Build and Push inputs: dockerfile: default: Dockerfile context: default: . image_name: required: true tag: required: true build_args: default: "" report_name: default: trivy-report runs: using: "composite" steps: - uses: azure/login@v2 with: creds: ${{ env.AZURE_CREDENTIALS }} - uses: azure/docker-login@v2 with: login-server: ${{ env.CONTAINER_REGISTRY }} username: ${{ env.ACR_USERNAME }} password: ${{ env.ACR_PASSWORD }} - name: Build and Push Image shell: bash run: | docker build ${{ inputs.build_args }} \ -t ${{ env.CONTAINER_REGISTRY }}/${{ inputs.image_name }}:${{ inputs.tag }} \ -f "${{ inputs.dockerfile }}" "${{ inputs.context }}" docker push ${{ env.CONTAINER_REGISTRY }}/${{ inputs.image_name }}:${{ inputs.tag }} - name: Scan with Trivy uses: aquasecurity/trivy-action@0.32.0 with: image-ref: '${{ env.CONTAINER_REGISTRY }}/${{ inputs.image_name }}:${{ inputs.tag }}' format: 'sarif' output: 'trivy-results.sarif' exit-code: 0 - name: Upload SARIF to GitHub Security tab uses: github/codeql-action/upload-sarif@v3 with: sarif_file: 'trivy-results.sarif' category: trivy
Usage in Workflow
- name: Build and Scan uses: ./.github/actions/build-and-scan with: image_name: my-app tag: ${{ github.sha }}
π Example: Terraform/Terragrunt Validation with Checkov
Now letβs see a reusable workflow to validate Terraform code and scan for misconfigurations using Checkov.
.github/workflows/infra-check.yml
name: Infra Validation Workflow on: workflow_call: inputs: working_dir: required: true type: string jobs: validate: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Install Terragrunt and OpenTofu run: | curl -s https://raw.githubusercontent.com/opentofu/opentofu/main/scripts/install.sh | bash curl -L https://github.com/gruntwork-io/terragrunt/releases/latest/download/terragrunt_linux_amd64 -o terragrunt chmod +x terragrunt sudo mv terragrunt /usr/local/bin/ - name: Validate HCL Syntax run: | terragrunt hclfmt --terragrunt-check --terragrunt-diff --recursive working-directory: ${{ inputs.working_dir }} - name: Check Misconfigurations with Checkov uses: bridgecrewio/checkov-action@v12 with: directory: ${{ inputs.working_dir }} quiet: true
Usage in Project Workflow
jobs: call-validation: uses: your-org/your-repo/.github/workflows/infra-check.yml@main with: working_dir: infrastructure/staging/eu-west-1
βοΈ Best Practices
β
Keep composite actions in .github/actions
β
Keep reusable workflows in .github/workflows
β
Abstract frequently repeated patterns
β
Use inputs, outputs, and env vars to increase flexibility
β
Use workflow_call
and workflow_dispatch
to structure triggers
β
Defer secrets to the calling workflow
π‘ Conclusion
Using composite actions and reusable workflows together can transform your CI/CD processes into clean, repeatable, and secure pipelines. Whether you're building containers, provisioning infrastructure, or scanning for vulnerabilities, this modular approach will scale with your teams and your systems.
Enjoy building better pipelines !
Top comments (0)