I was at a recent conference when people were discussing their usage of terraform
.If you don’t know, terraform has become the defacto standard for declaring cloud infrastructures in a consistent and repeatable fashion. This is nothing new, andI’ve used it to declare GCP, AWS, and even IBM Cloud. What caught my interest was using terraform to declare GitHub resources like repositories and team memberships.
GitHub Terraform
Someone said it was possible and they had played with it. I decided to give it a shot with my GitHub organization asgharlabs. All in all the basics of it was straight forward:
# This is just an example public repository terraform owns from the get-go.
resource "github_repository" "terraform_public_repository" {
name = "terraform_public_repository"
description = "My example repository controlled by terraform public, and archived"
private = false
has_issues = true
has_projects = true
has_wiki = false
default_branch = "master"
archived = true
}
The above would create a repository like this, and the actual configuration was pretty easy:
# Configure the GitHub Provider
provider "github" {
token = "${var.github_token}"
organization = "${var.github_organization}"
}
variable "github_token" {
default = ""
}
variable "github_organization" {
default = "asgharlabs"
}
I had to create some ENV
(environment variables) like this, so I could use the var.github_token
.
export TF_VAR_github_token=ca8eb690ec656MY_FAKE_TOKEN!!201a9b866e750
export TF_VAR_github_organization=asgharlabs
All in all, it wasn’t too exciting, but the next part was where the real money is.
GitHub Actions
Ok, let me paint a little picture here. My theory was this: I make a Pull Request to my asgharlabsrepository, say add a repository for the organization, and GitHub Actions runs it through some validation. I check the terraform plan
and if I agree that it’ll do what expect, I can click the green merge button, and it merges into master completing the workflow with a terraform apply
.
I’ve always been a fan of travisci, but with GitHub Actions, and the flexibility it has this was a great opportunity for me to learn how to do this. These are the steps and gotchas I found to figure this out.
Enabling GitHub Actions
The first thing I noticed was that I didn’t have GitHub Actions enabled on my account, believe it or not, but it was surprisingly hard to figure out how to sign up for that beta. This won’t be forever, but if you're doing it early like me, there’s the link. :)
Discovering there are two different styles of Actions
I don’t know where or when they announced a different way of doing Actions, but it seems as of writing this post (2019-11-05) they are in a migration from some { }
declarative style to a yaml
based with no GUIinvolved. Honestly, it feels closer to what most people are used to, but if you look at some of the documentation a lot of it still references the { }
style and it’s very confusing. Keep this in mind on your journey, and look find examples (the few that are out there, minus here) that are yaml
.
Structure of the .github/workflows/
directory
This bit me a couple of times, unlike in Travis, where you can have some branching logic in your .travis.yml
, each .yaml
file in your workflows/
directory is one “path.” So for my case, I had to have one file dedicated to my Pull Request, and one file for when something is merged into master from the Pull Request. You can take a look here to see the two files I created, deploy.yml
and pull_request.yml
.
Check on Pull Request
Ok, the meat of the learning here was when something happened with Pull Request was submitted/created. The following is the “Do this when the Pull Request is created.”
name: 'Terraform Pull Request Workflow'
on:
pull_request:
jobs:
validate_terraform:
name: 'Terraform Validate Actions'
runs-on: ubuntu-latest
steps:
- name: 'Checkout'
uses: actions/checkout@master
This has a unique name:
, on:
the pull_request:
and runs-on: ubuntu-latest
. If you want something different,GitHub claims, Linux, Windows and MacOS, you can check the documentation. After all of this then the steps:
is where theactual magic happens. If you take a look at the direct file, the most interesting step
is thisone:
- name: 'Terraform Plan'
uses: hashicorp/terraform-github-actions@master
with:
tf_actions_version: 0.12.13
tf_actions_subcommand: 'plan'
tf_actions_working_dir: '.'
tf_actions_comment: true
env:
GITHUB_TOKEN: REMOVED
TF_VAR_github_token: REMOVED
This one required me to create a secret, in the repository settings called TF_VAR_github_token
, so the terraform plan
can work. It will also comment on the Pull Request, such as here if it passes so you can look in one location.
Run apply
on Merge
The next step was to get my terraform apply
to happen. If you want to see exactly what I did, look here, andI’ll explain the important parts here. I learned that there isn’t a Pull Request “state” for merged
. This seemed odd, and it is a more specific state called pushed to master
. This also triggers if someone pushes directly to master, which in its self could be bad, but that’s a different blog post. In this “perfect” world I only plan to use Pull Requests and when I hit the green button that’s only when terraform apply
should happen.
name: 'Deploy Terraform Workflow'
on:
push:
branches:
- master
jobs:
deploy_terraform:
name: 'Terraform Deploy Actions'
runs-on: ubuntu-latest
As you can see, it’s just a specific tree of logic, for the on:
, which you could change to whatever your workflow is. As soon as I figured it out, it wasn’t so hard to understand what needed to get done, the only other major difference was the apply
:
- name: 'Terraform Apply'
uses: hashicorp/terraform-github-actions@master
with:
tf_actions_version: 0.12.13
tf_actions_subcommand: 'apply'
tf_actions_working_dir: '.'
tf_actions_comment: true
env:
GITHUB_TOKEN: REMOVED
TF_VAR_github_token: REMOVED
Just like above, it pulls in the same TF_VAR_github_token
from the secrets store, and that’s…really it.
So all in all, this was a fun couple of hours playing around with this workflow. Now I can run terraform
from my GitHub repository, and in turn, make changes to my GitHub Organization. All in all gotta say it’s pretty neat.
Top comments (0)