chrisguk
chrisguk

Reputation: 21

Check if a branch exists with terraform

I am trying to check which branch exists before I apply this resource.

  resource "github_repository_file" "git" {
  repository          = github_repository.git.name
  branch              = "develop" != "" ? "develop" : "master"
  file                = ".github/git.yml"

So the logic I am trying to achieve is this:

If the develop branch exists apply it to the develop branch. If it doesn't exist apply it to the master branch.

What am I doing wrong here?

Upvotes: 1

Views: 1471

Answers (2)

Ked Mardemootoo
Ked Mardemootoo

Reputation: 1605

Here's what you could do, use the Terraform external resource object to get the current branch from a script, and then use this to validate your logic.

Here's what the external block would look like:

data "external" "get_current_branch" {
  program = ["../4-shared-scripts/get-current-branch.sh"]
}

And then your script (I'm using a shell script here). We need to construct the output in an acceptable format, hence echoing in JSON because that's what terraform expects to read.

#!/bin/sh

getbranch=`git branch --show-current`

echo "{\"branch\":\"$getbranch\"}"

Then your line below would get the value from the external object and use the conditional to compare, like this:

resource "github_repository_file" "git" {
repository          = github_repository.git.name
branch              = data.external.get_current_branch.result.branch != "" ? "develop" : "master"
file                = ".github/git.yml"

For the above, I'm assuming that you have to check against multiple dev branches that do not have a standard name, hence why the conditional. Else you would only need to grab the current branch's value and parse it, without the conditional.

If you need to go through all existing branches first and then validate where to apply, your script would look like this:

#!/bin/sh

branchlist=`git branch`
check=`echo $branchlist | tr ' ' '\n' | grep develop`

if [[ $check =~ develop ]]; then
    echo "{\"branch\":\"develop\"}"
else
    echo "{\"branch\":\"master\"}"
fi

And your Git resource object would be just this, without needing the conditional:

resource "github_repository_file" "git" {
repository          = github_repository.git.name
branch              = data.external.get_current_branch.result.branch
file                = ".github/git.yml"

Upvotes: 2

Martin Atkins
Martin Atkins

Reputation: 74479

The usual way to solve a problem like this would be to define an input variable to allow the caller of your module to specify which branch to use:

variable "branch_name" {
  type = string
}

Or, if you want to be a bit more prescriptive, you could make it specifically about whether to use the "develop" branch:

variable "use_develop_branch" {
  type    = bool
  default = false
}

You can then use the variable value as part of the resource configuration:

resource "github_repository_file" "git" {
  repository = github_repository.git.name
  branch     = var.branch_name
  file       = ".github/git.yml"
}
resource "github_repository_file" "git" {
  repository = github_repository.git.name
  branch     = var.use_develop_branch ? "develop" : "master"
  file       = ".github/git.yml"
}

One thing I notice about the example you shared is that it includes a reference to github_repository.git.name, which suggests that this module is also responsible for managing (and thus, initially creating) the repository itself. Therefore presumably it's this configuration's job to decide whether there is a develop branch or not, rather than to detect if it exists, because a GitHub repository immediately after creation has no branches at all and thus it would take a separate step to make one exist.

Given that, you may be able to populate this branch argument based on whatever other decision you've made elsewhere in the configuration about which branches to create. For example, if you have a github_branch resource which set up this branch then you could refer to it like this:

resource "github_repository_file" "git" {
  repository = github_repository.git.name
  branch     = github_branch.default.branch
  file       = ".github/git.yml"
}

This would then inherit whatever decision you made to choose a branch in the github_branch.default resource.

Upvotes: 1

Related Questions