Access Terraform Private Modules in GitHub Actions
Because the cloud moves so fast, this post may be out of date. Please reach out to me if you this content needs an update.
In a recent project we used GitHub Actions to deploy our Terraform code. While not the best way to deploy Terraform, we had it working nicely.
One of the biggest challenges we encountered was how to download the private Terraform modules we had created. In a GitHub Actions workflow you can specify the permissions that the runner should be granted. However, these permissions are scoped to the repository that the Action is running on, and it is not possible to add additonal repos to the permission set.
So how do we solve this problem? With a GitHub Application of course! We register a GitHub application and grant it Content Read access on Repositories. We then install this application to the organisation which hosts our Terraform Modules.
Now that we have an application with the required permissions, we need to use this in our Actions workflow. First, we create Actions variables and secrets to hold the Application ID, Installation ID, and Private Key. The main challenge here is that we can’t use the Private Key directly to authenticate - we need to turn it into a JWT. While we could do this ourselves, we found a small action which will fetch a JWT for us, and make it available. We can then use this token to configure our Git client to use this token for authentication. To do this, we add two steps to our Terraform action:
- name: Get Checkout Token
id: checkout-token
uses: jamestrousdale/github-app-jwt-token@<version>
with:
app-id: ${{ vars.CHECKOUT_APP_ID }}
app-installation-id: ${{ vars.CHECKOUT_APP_INSTALLATION_ID }}
private-key: ${{ secrets.CHECKOUT_APP_PEM_FILE }}
- name: Configure Git
run: |
git config --global url."https://actions:${{ steps.checkout-token.outputs.access-token }}@github.com".insteadOf https://github.com
And just like that, we are able to download any private repository in the organisation.