GitHub Actions for Kitchen-Terraform Testing
Tags: github, terraform, devops, googlecloud
Published: 2020-09-19 18:07:29

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/nu76ifdpv6t49cw36vvu.png)

In the last [post](https://dev.to/brettcurtis/gcp-cis-benchmark-terraform-module-testing-with-chef-inspec-kitchen-terraform-github-actions-1227), we worked on [Kitchen-Terraform](https://github.com/newcontext-oss/kitchen-terraform) running locally, and now we want to run it from [GitHub Actions](https://github.com/features/actions). 

![GitHub Action](https://dev-to-uploads.s3.amazonaws.com/i/wpk2l5my9areo8twe6i6.png)

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](https://github.com/lzysh/terraform-google-project/issues/1) 
- 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](https://github.com/lzysh/terraform-google-project/pull/2)
 - *NOTE: Once the pull request is created, it will (based on our action configuration) run the [GitHub Action](https://github.com/lzysh/terraform-google-project/runs/1121079032#step:4:212)*
- Add someone to for review after successful GitHub Action run
- Squash and merge your [commit](https://github.com/lzysh/terraform-google-project/commit/ce6eb7b48f2df32d50930ce363a5fed84ffd9f8e) after code review

To get your GitHub Action setup, the first thing we will need to do is create a [self-hosted runner](https://docs.github.com/en/actions/hosting-your-own-runners/about-self-hosted-runners). 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](https://docs.github.com/en/actions/creating-actions/creating-a-docker-container-action) for Kitchen-Terraform [here](https://github.com/lzysh/github-kitchen-terraform-action), 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](https://github.com/lzysh/terraform-google-project/blob/master/.github/workflows/main.yml). 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](https://resources.github.com/whitepapers/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:

![GitHub Action Workflow File Job](https://dev-to-uploads.s3.amazonaws.com/i/vm546x4gllaewitgt0db.png)

The `runs-on` has the self-hosted runner labels:

![Self Hosted Runner Labels](https://dev-to-uploads.s3.amazonaws.com/i/l9q8576cwifrtw79q7d3.png)

As mentioned in the previous post, we are passing BILLING_ID to terraform as a [secret](https://docs.github.com/en/actions/reference/encrypted-secrets) from GitHub. You can set secrets and an organizational level or a repository level.

![GitHub Secrets](https://dev-to-uploads.s3.amazonaws.com/i/hija7a3qbpivrzhznb02.png)

Next, we define a default shell to use and the steps to run:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/iea66xolz1388yixxxo5.png)

The first step is to use the [GitHub Checkout Action](https://github.com/marketplace/actions/checkout) to checkout the repository on the runner. The second is to use the [Google Cloud Platform Setup gcloud Environment Action](https://github.com/marketplace/actions/setup-gcloud-environment) to configure our Google credentials. This action also allows us to set up [Google Application Default Credentials (ADC)](https://cloud.google.com/docs/authentication/production) 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:

![GitHub Actions Run Terraform-Kitchen Tests](https://dev-to-uploads.s3.amazonaws.com/i/ikkmffxylrh7av5adbow.png)

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](https://dev.to/brettcurtis/infrastructure-as-code-iac-5cbg) 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](https://github.com/GoogleCloudPlatform/inspec-gcp-cis-benchmark) profile running across all the Google Cloud Platform resources created.