Currently to add environment variables to a CodeBuild project, they need to be defined like so:
environment {
[...]
environment_variable {
"name" = "SOME_KEY1"
"value" = "SOME_VALUE1"
}
environment_variable {
"name" = "SOME_KEY2"
"value" = "SOME_VALUE2"
}
}
This means that multiple environment variables can't be passed in from tfvars.
Preferably, environment variables could be passed in like:
environment {
[...]
environment_variables = [
{
"name" = "SOME_KEY1"
"value" = "SOME_VALUE1"
},
{
"name" = "SOME_KEY2"
"value" = "SOME_VALUE2"
}
]
}
This would then allow the variables to be passed in as a list:
environment {
[...]
environment_variables = "${var.envars}"
}
A specific use case for this is where 3rd party modules are being used, such as https://github.com/squidfunk/terraform-aws-github-ci
Currently environment variables can't be passed through, as each environment variable needs to be defined within the resource
https://www.terraform.io/docs/providers/aws/r/codebuild_project.html
https://github.com/squidfunk/terraform-aws-github-ci
Hi @Stretch96 ๐ It might not be explicitly documented throughout the Terraform documentation, but the syntax you are trying to use does actually work, at least in Terraform 0.11.8.
For example, this is a working configuration:
terraform {
required_version = "0.11.8"
}
provider "aws" {
region = "us-east-1"
version = "1.32.0"
}
variable "environment_variables" {
type = "list"
default = [
{
name = "DEFAULT_KEY1"
value = "DEFAULT_VALUE1"
},
{
name = "DEFAULT_KEY2"
value = "DEFAULT_VALUE2"
},
]
}
resource "aws_iam_role" "test" {
name = "issue-5563-testing"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "codebuild.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
}
resource "aws_iam_role_policy" "test" {
role = "${aws_iam_role.test.name}"
policy = <<POLICY
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Resource": [
"*"
],
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
]
},
{
"Effect": "Allow",
"Action": [
"ec2:CreateNetworkInterface",
"ec2:DescribeDhcpOptions",
"ec2:DescribeNetworkInterfaces",
"ec2:DeleteNetworkInterface",
"ec2:DescribeSubnets",
"ec2:DescribeSecurityGroups",
"ec2:DescribeVpcs"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": "*"
}
]
}
POLICY
}
resource "aws_codebuild_project" "test" {
name = "issue-5563-testing"
service_role = "${aws_iam_role.test.arn}"
artifacts {
type = "NO_ARTIFACTS"
}
environment {
compute_type = "BUILD_GENERAL1_SMALL"
image = "2"
type = "LINUX_CONTAINER"
environment_variable = "${var.environment_variables}"
}
source {
location = "https://github.com/hashibot-test/aws-test.git"
type = "GITHUB"
}
}
If I also define a terraform.tfvars file like the below and run terraform apply:
environment_variables = [
{
name = "OVERRIDE_KEY1"
value = "OVERRIDE_VALUE1"
},
{
name = "OVERRIDE_KEY2"
value = "OVERRIDE_VALUE2"
},
]
We get the expected values saved in the resource and into the Terraform state:
$ terraform state show aws_codebuild_project.test
...
environment.1401055302.environment_variable.# = 2
environment.1401055302.environment_variable.0.name = OVERRIDE_KEY1
environment.1401055302.environment_variable.0.type = PLAINTEXT
environment.1401055302.environment_variable.0.value = OVERRIDE_VALUE1
environment.1401055302.environment_variable.1.name = OVERRIDE_KEY2
environment.1401055302.environment_variable.1.type = PLAINTEXT
environment.1401055302.environment_variable.1.value = OVERRIDE_VALUE2
There are some important notes about this functionality though:
for expressions.Does this help answer what you are looking for?
Ah yep, that does help, I'll give it a go ๐
Does that apply to all resource properties that allow multiples? I don't think that is documented (It's not documented on the codebuild_project page).
@Stretch96 that's correct, it should apply to any schema.TypeList and schema.TypeSet attributes in any Terraform resource. We would prefer to _not_ document this on individual resources since its generic, but if you feel some of the https://www.terraform.io documentation could be improved, I think its worth submitting something upstream in Terraform core: https://github.com/hashicorp/terraform
I'm going to close this out since the specific use case is supported, but feel free to reach out if I'm missing something. ๐
This may still be an issue. I have a couple of vars that I'd like to put in as data. For example:
variable environment_variables {
type = "list",
default= [
{
"name" = "BUCKET_NAME"
"value" = "${var.bucket_name}"
}
]
}
But it won't work. Clearly I cant use default. But what do I use?
@automaticgiant If you want to be able to use a set of defaults, and also allow adding in custom environment variables, you can do something like this:
variables.tf:
variable "bucket_name" {
type . = "string"
default = ""
}
variable "environment_variables" {
type = "list"
default = []
}
aws_codebuild_project resource:
environment {
[...]
environment_variable = [
{
"name" = "BUCKET_NAME",
"value" = "${var.bucket_name}"
},
"${var.environment_variables}"
]
[...]
For terraform 0.12.x I had to change to something like the following:
variable "environment_variables" {
type = list(string)
default = [
{
name = "DEFAULT_KEY1"
value = "DEFAULT_VALUE1"
},
{
name = "DEFAULT_KEY2"
value = "DEFAULT_VALUE2"
},
]
}
resource "aws_codebuild_project" "codebuild" {
name = var.name
description = var.codebuild_project_description
service_role = aws_iam_role.codebuild.arn
artifacts {
type = "CODEPIPELINE"
}
environment {
compute_type = var.codebuild_compute_type
image = var.codebuild_image
type = var.codebuild_type
dynamic "environment_variable" {
for_each = [for v in var.environment_variables: {
name = v.name
value = v.value
}]
content {
name = environment_variable.value.name
value = environment_variable.value.value
}
}
}
source {
type = "CODEPIPELINE"
}
}
I'm going to lock this issue because it has been closed for _30 days_ โณ. This helps our maintainers find and focus on the active issues.
If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. Thanks!
Most helpful comment
Hi @Stretch96 ๐ It might not be explicitly documented throughout the Terraform documentation, but the syntax you are trying to use does actually work, at least in Terraform 0.11.8.
For example, this is a working configuration:
If I also define a
terraform.tfvarsfile like the below and runterraform apply:We get the expected values saved in the resource and into the Terraform state:
There are some important notes about this functionality though:
forexpressions.Does this help answer what you are looking for?