Automating the Boring Stuff: Terraform, GitHub Actions, and Peace of Mind

Automating the Boring Stuff: Terraform, GitHub Actions, and Peace of Mind

- 6 mins

I’ve spent a lot of time lately thinking about growth. Not just the personal kind—the kind Russ talks about when he mentions the “independent hustle”—but the technical kind. In my world, growth usually means more servers, more configurations, and unfortunately, more manual tasks that eat up the day.

If you’ve followed my journey from passion to paycheck, or from Linux enthusiast to Platform Engineer, you know I’m a fan of building things. But I have learned over the years, there’s a difference between building from scratch and doing the same task twice. If I have to click through the AWS console to spin up an EC2 instance more than once, I’ll drive to a data center and shoot up a few server racks myself.

This week, I decided to sit down and clean up my infrastructure workflow. I wanted to showcase my move away from the “manual” and move toward “automated excellence.” I built a pipeline that combines Terraform, GitHub Actions, and Discord to handle the heavy lifting while I focus on the bigger picture. Like Thanos, I’m trying to get to that point where I can finally rest and watch the sunrise on a grateful (and fully automated) universe. Let me break this down and, with the help of AI, write it out in a blog to share with other engineers.

The Stack: Infrastructure as Code

For those who havent listed to Juicy by NOTORIOUS BIG, Terraform is a tool that lets you write code to define your hardware. Instead of pointing and clicking in an AWS dashboard, I write a few lines in a .tf file, and AWS makes it happen.

In this project, I targeted a simple Ubuntu 20.04 server. But I didn’t want to just “hardcode” the settings. I wanted a setup that felt professional—something that handles versioning and security right out of the box.

Managing Versions with tfenv

I’m a stickler for consistency in the dev space and I’ve seen too many projects break because one dev is on Terraform v1.5 and another is on v1.14. So I wrote a setup.sh script that leverages tfenv. It checks your system, installs the tool if it’s missing, and locks the project to a specific version.

This creates a .terraform-version file in the repo. Now anyone, and my GitHub runner. knows exactly which version of Terraform to use. No more “it works on my machine” excuses when sharing the repo link.

The Magic with GitHub Actions

The real magic happens when you stop running commands from your laptop and let the cloud manage itself. I configured a GitHub Actions workflow to handle my CI/CD (Continuous Integration/Continuous Deployment).

The workflow does a few key things: Quality First: Before a single Before a single server is built, the pipeline runs TFLint. While the standard Terraform validator checks if your code is “legal,” TFLint checks if it is “good.” It acts like a senior engineer performing a code review on every commit, catching non-optimal configurations—like using an outdated instance type or missing recommended tags—that a basic syntax check would miss.

Security-on-Demand: It’s essential for catching those quirky provider-specific errors and ensuring a “clean-code” mindset is baked into the pipeline from the start.

While the pipeline focuses on linting by default, I’ve included a commented-out block for a Focused Trivy Scan.

Since this is a general-purpose template, not every project—like a local test lab or a simple static site—requires high-level security audits that might fail a build over a minor disk encryption warning. However, for anything destined for production, this is a “nice-to-have” that acts like a pre-flight security officer.

To enable it, you simply uncomment the following block in your workflow:

 - name: Run Focused Trivy Scan
         id: security_scan
         uses: aquasecurity/[email protected]
         with:
           scan-type: 'config'
           scan-ref: '.'
           severity: 'CRITICAL,HIGH' 
           limit-to-misconfigurations: true  
           exit-code: '1'

Manual Control: I added a workflow_dispatch trigger. This gives me a “Run Workflow” button in GitHub where I can choose to plan, apply, or destroy my infrastructure manually. Sometimes you want that “big red button” feel. This helps keep costs low and prevents the apply to stick around overnight and have me write out a new blog about how I owe AWS my savings acount because I forgot to turn something off.

Environment Secrets: Using the GitHub CLI (gh), I automated the process of pushing my AWS keys and Terraform variables into GitHub “Environments.” This keeps sensitive data off my hard drive and safely tucked away in GitHub’s encrypted vault.

Keeping the State in S3

One thing that used to trip me up back in 2018 was the concept of “State.” Terraform needs to remember what it built. If you run it on a GitHub runner, that runner disappears as soon as the job is done. If you don’t save that memory (the state file) somewhere, Terraform will think it has to start from scratch every time.

I moved my state to an S3 Bucket. Now, the state is persistent and shared. Whether I’m running a command from my terminal or GitHub is running it from a data center in Virginia, we’re all looking at the same map.

Staying Connected with Discord

I’m a fan of proper “alerts” I didn’t want to keep refreshing a browser tab to see if my deployment finished. I want to be notified with a problem when it happens and not have to deal with a “hey, you got a second” ping. Give me the hard details!

I set up a Discord Webhook that sends a formatted “Embed” message to my server. It uses color-coded bars—Green for success, Red for a failure. It tells me the branch, the author, and how long the job took. It’s a small touch, but it adds a level of calmness to the chaos of deployment. Discord was used because this is part of my own personal project. Don’t need pay for teams or slack when discord is my current computer chat app of choice.

Final Thoughts

I often think about my twin brother when I finish a project like this. He wasn’t into Linux or Automation, but he understood the hustle. He understood what it meant to take a raw idea and turn it into something tangible. Every time I hit “Apply” and see those green checkmarks, I kinda feel that connection.

The work is never done. The tech field is a moving target, and the only constant is change. But by automating these workflows, I’m carving out more time to reflect, more time to listen to music that keeps me grounded, and more time to get to whatever is next.

If you’re looking to grab the code and set up your own automated AWS environment, you can check out the repo here.

Keep getting to it.

Reflection

The Lesson

Automation isn’t about being lazy; it’s about being efficient so you can focus on the things that actually require your humanity.

The Tech

Terraform + GitHub Actions + S3 + Discord = A production-ready pipeline that fits in your pocket.

The Vibe

Stay calm, keep building, and let the code handle the noise.