First, we can talk at a high level about the GitHub flow in use. I'll probably write up a different post with more details around this because I find folks with a core operational background haven't used GitHub or understand the "whys" around doing some of the things developers do.
- Create an issue
- Create a branch to work on
- NOTE: Branches are deleted after a successful merge into mainline. Also, in the spirit of continuous delivery, these are not long-lived branches and should be integrated frequently
- Create a pull request
- NOTE: Once the pull request is created, it will (based on our action configuration) run the GitHub Action
- Add someone to for review after successful GitHub Action run
- Squash and merge your commit after code review
To get your GitHub Action setup, the first thing we will need to do is create a self-hosted runner. For this example, I ended up using a small compute instance in Google Cloud Platform. You can pick any cloud provider you want or even a machine in your datacenter if needed. It just needs to have the tools installed to do whatever you're asking your action to run. In our case, all the bits to run Kitchen-Terraform.
Adding a GitHub self-hosted runner has to be the most accessible CI/CD tool "agent-based" install ever, so I don't think we need to go into the details here. I did try to create my own packaged Docker container action for Kitchen-Terraform here, but I wouldn't say I liked how it had to build the image each run.
Once your runner is up and running, you will need to tell GitHub what you want to do and where to do it. We do this using a workflow file. The workflow file is written in YAML and lives inside your GitHub repository in the
.github/workflows directory. You can take a look at the GitHub Actions Cheat Sheet, it describes the contents of a workflow file. Ours is simple, one Job with three steps. First, we tell GitHub the name of the action and when to run it. In our case, on commit to master and pull requests as I talked about earlier. Next, where to run the action:
runs-on has the self-hosted runner labels:
As mentioned in the previous post, we are passing BILLING_ID to terraform as a secret from GitHub. You can set secrets and an organizational level or a repository level.
Next, we define a default shell to use and the steps to run:
The first step is to use the GitHub Checkout Action to checkout the repository on the runner. The second is to use the Google Cloud Platform Setup gcloud Environment Action to configure our Google credentials. This action also allows us to set up Google Application Default Credentials (ADC) by setting
export_default_credentials: true. This is slick because Terraform can use these by default without setting anything up! Finally, we end up at the last step, which runs
bundle exec kitchen test on our self-hosted runner:
There we have it! You have yourself a nice little Terraform module you can continue to improve upon over time in a supportable way just like I quoted in another post about using some of the good practices we've learned in the software world like:
Using source control, adhering to the DRY principle, modularization, maintainability, and using automated testing and deployment.
In the next post, we can talk about putting multiple Terraform modules together with the inspec-gcp-cis-benchmark profile running across all the Google Cloud Platform resources created.