Last month I wrote a blog post about how to run terraform init on codefresh. Sadly Codefresh are changing their pricing which makes it alot more expenive per developer. For this reason, we're migrating our pipelines at work to GitHub actions.

Pricing & Plans | Codefresh
Sign up for Codefresh today and get a 14-day trial of our Enterprise plan. Flexible pricing plans for every project and budget.

tl;dr: It's going from $34 pcm for 10 devs on a small runner to ~$50+ per dev per month.


The issue we have

At work, all our terraform modules are store in Git Hub. Also, all our modules use git::ssh:// as the method of pulling them.

Module Sources | Terraform | HashiCorp Developer
The source argument tells Terraform where to find child modules’s configurations in locations like GitHub, the Terraform Registry, Bitbucket, Git, Mercurial, S3, and GCS.

I've tried to follow blog posts like the below, which did not work.

When I say this, I mean I could not for the life of me get it work, regardless of what permissions I gave the pipeline.

Github Actions with a private Terraform module
Terraform makes it easy to manage infrastructure at scale; you might want to share code between modules, and that’s where it becomes tricky. In this post, I try to give some clues on how to use terraform across private Github repos.

I was still getting the issue

Cloning into 'terraform-module-google-dns'...
remote: Repository not found.
fatal: repository 'https://github.com/<>/terraform-module-google-dns.git/' not found

Despite the repo very much being there

Solution

The solution was pretty much the same as the Codefresh solution: Install SSH Keys on the pipeline, so when terraform runs git clone on the module, it has the keys.

Create the keys

You need to create specific keys for the modules. I recommend creating ones called githubactions-terraform

ssh-keygen -t ed25519

When it asks what you want to name it, supply the full path to your .ssh directory, and append githubactions-terraform

Now we have the keys created, we can upload them to the GitHub repo that the pipeline needs to pull them from

Adding the keys to the relevant GitHub repos

Navigate to your repo of choice, in this example I will use my Codefresh IP module

Click on Settings

Then click on Deploy Keys down the left hand side

Open your terminal and copy the public key to the clipboard

cat githubactions-terraform.pub | pbcopy

Click Add Deploy Key and paste it in

Next step is to add the private SSH keys to the repo with the GitHub actions enaled

SSH Keys on the actions repo

Open Terminal and copy the private keys to clipboard

cat githubacionts-terraform | pbcopy

Navigate to the repo with the actions in, click settings, then click Security > Actions

Click New repository secret

Give it a name, for example I am calling this SSH_KEY_GITHUB_ACTIONS

Paste the Private SSH key in.

Read the below page if you are worried about secrets being leaked

Encrypted secrets - GitHub Docs
Encrypted secrets allow you to store sensitive information in your organization, repository, or repository environments.

The GitHub actions part

So, we have the SSH keys setup, now we need to actually use them!

I have created the below GitHub actions that:

  • Installs terraform on the runner
  • Adds the SSH keys
  • Runs terraform init
name: DNS

on:
  push:
    branches:
      - main

jobs:
  terraform:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Install Terraform
        uses: hashicorp/setup-terraform@v2
        with:
          terraform_version: 1.3.9

      - name: Terraform Init
        working-directory: ${{ env.DIR }}
        run: |
          eval `ssh-agent -s`
          ssh-add - <<< '${{ secrets.SSH_KEY_GITHUB_ACTIONS }}'
          terraform init

You are then free to continue with what ever other terraform steps you need to do in your pipeline.