Reputation: 67
Using the Terraform (v0.9.6) GitHub Provider, how can one separately assign multiple distinct issue labels to a list of GitHub repositories while using one resource?
With another language I'd probably write something along the lines of:
for i in repos {
for j in tags[i] {
make tag j on repo i
}
}
In this example below I am adding multiple tags to a single repository. The map
keys are the repos, and the values are a list of strings.:
variable "issue-labels" {
type = "map"
default = {
"repo_0" = "tag1, tag2, tag3"
"repo_1" = "tag4"
"repo_2" = "tag5, tag6"
}
}
resource "github_issue_label" "issue_labels" {
count = "${length(split(", ", join(", ", lookup(issue-labels, "my-repo"))))}"
repository = "my-repo"
name = "${element(split(", ", join(", ", lookup(issue-labels, "my-repo"))), count.index)}"
color = "FFFFFF"
}
Currently seeking an answer to what feels like an inner loop in terraform. Either finding some way to iterate through the repositories and make multiple resource counts for each, or a workaround involving interpolation to assign the right repo when we iterate through the total number of labels.
Upvotes: 2
Views: 3686
Reputation: 74109
Using list variables and other complex structures to "abstract away" resources is not idiomatic and tends to lead to configuration that is hard to read and maintain.
The idiomatic style is to manage repetitive constructs using multiple instances of a child module.
For example, one can make a subdirectory called repository
that contains a repository.tf
file such as the following:
variable "name" {
}
variable "labels" {
type = "list"
}
# can instead use github_team_repository here if appropriate
resource "github_repository" "this" {
name = "${var.name}"
# ...
}
resource "github_issue_label" "all" {
count = "${length(var.labels)}"
repository = "${var.name}"
name = "${var.labels[count.index]}"
color = "FFFFFF"
}
Now in the root module, rather than using variables to define the set of repositories, one can instead instantiate this resource once for each repository:
module "foo_repo" {
source = "./repository"
name = "foo"
labels = ["tag1", "tag2", "tag3"]
}
module "bar_repo" {
source = "./repository"
name = "bar"
labels = ["tag4"]
}
module "baz_repo" {
source = "./repository"
name = "baz"
labels = ["tag5", "tag6"]
}
With this style, the settings for each repository are kept together in a single module block each, thus making them easy to read and update. Adding a new repository is done by adding a new module
block.
This style also allows removing a single repository without disturbing all of the ones after it, since the module states are stored by the module name rather than by index into a a list.
The general recommendation here is that count
should be used sparingly, and that it's usually better to write config explicitly rather than generate it via variables. The result is often easier to read and maintain, and easier to adapt over time as requirements change.
Upvotes: 3