Automating infrastructure deployments is crucial for maintaining consistency and enabling rapid iteration. In this post, I'll walk through how I set up CI/CD pipelines using GitHub Actions integrated with Terraform Cloud for my cloud resume project.

The Goal

I wanted to achieve a workflow where pushing code to the main branch would automatically trigger tests, run Terraform plans, and apply infrastructure changes—all without manual intervention.

Why GitHub Actions + Terraform Cloud?

This combination offers several advantages:

Workflow Structure

The pipeline consists of three main jobs:

1. Test Job

For the backend, Python tests run first using pytest with moto to mock AWS services:

- name: Run pytest
  run: |
    cd cloud-resume-backend
    pytest tests/test_handler.py -v
  env:
    TABLE_NAME: 'test-table'

2. Terraform Plan

On pull requests, the workflow uploads the configuration to Terraform Cloud and creates a speculative plan:

- name: Upload Configuration
  uses: hashicorp/tfc-workflows-github/actions/upload-configuration@v1.3.0
  with:
    workspace: ${{ env.TF_WORKSPACE }}
    directory: ${{ env.CONFIG_DIRECTORY }}
    speculative: true

3. Terraform Apply

When code merges to main, the apply job runs automatically, deploying the infrastructure changes:

- name: Apply
  uses: hashicorp/tfc-workflows-github/actions/apply-run@v1.3.0
  with:
    run: ${{ steps.apply-run.outputs.run_id }}

Handling Secrets

The Terraform Cloud API token is stored as a GitHub repository secret and accessed via ${{ secrets.TF_API_TOKEN }}. AWS credentials are configured directly in Terraform Cloud workspace variables.

PR Comments

One nice feature is automatic PR comments showing the Terraform plan output. This gives reviewers visibility into infrastructure changes before approving:

Plan: 2 to add, 1 to change, 0 to destroy.
[View Plan in Terraform Cloud](link)

Lessons Learned

Results

With this setup, deploying changes takes under 3 minutes from push to production. The automation has eliminated manual errors and gives me confidence that every deployment is tested and reproducible.