I'm looking to create the following statement in my IAM policy through the terraform module:
{
"Effect": "Allow",
"Action": [
"ec2:CreateNetworkInterfacePermission"
],
"Resource": "arn:aws:ec2:us-east-1:<acc-id>:network-interface/*",
"Condition": {
"StringEquals": {
"ec2:Subnet": [
"subnet-id1",
"subnet-id2"
],
"ec2:AuthorizedService": "codebuild.amazonaws.com"
}
}
}
The problem I'm facing is that I'm unable to figure out which interpolation will get me [ "subnet1", "subnet2" ].
Here's a little background. I'm created subnets with TF module (pubic_subnets) and output code is this:
output "subnet_ids" { value = "${join(",", aws_subnet.public.*.id)}" }
which results in a string like "subnet-1,subnet-2,subnet-3". This is where I get my subnet ids from and I want to pass them to another module.
I have another module for the IAM policy (code below). I'm trying to take subnet_ids from above and pass them to the iam-policy module, so they can be placed into my statement, however, I can't figure out how to use any of the interpolations from TF. I tried about a dozen different interpolations but no luck. The only way I'm able to pass subnet ids to my IAM policy is by extracting items from the string (0, 1) and passing them as a separate variable. This is not perfect because I would like to include all subnet ids and there are times when I will have 3 subnets or more.
Has anyone been successful in doing such magic? How can I update my code so all subnet ids are passed in format ["subnet1", "subnet2", "subnet3"] ?
Here's my code for the iam-policy module in 2 files:
- main.tf
data "template_file" "policy" {
template = "${file("${var.policy_document}")}"
vars = {
account_id = "${var.account_id}"
role_name = "${var.role_name}"
log_group = "${var.log_group}"
repository_arn = "${var.repository_arn}"
website_s3_bucket = "${var.website_s3_bucket}"
pipeline_s3_bucket = "${var.pipeline_s3_bucket}"
subnet1 = "${var.subnet1}"
subnet2 = "${var.subnet1}"
}
}
resource "aws_iam_policy" "policy" {
name = "${var.policy_name}"
description = "${var.description}"
path = "${var.path}"
policy = "${data.template_file.policy.rendered}"
}
- variables.tf
variable "policy_name" { default = "" }
variable "description" { }
variable "path" { default = "" }
variable "policy_document" {
type = "string"
default = ""
}
# variables for policy
variable "log_group" { }
variable "account_id" { }
variable "role_name" { }
variable "repository_arn" { }
variable "website_s3_bucket" { }
variable "pipeline_s3_bucket" { }
variable "subnet1" { }
variable "subnet2" { }
In my project file (project.tf) I have:
module "iam_policy_for_codebuild_service_role" {
source = "../aws-policy.local"
policy_name = "${var.name}CodeBuildServiceRolePolicy1${lookup(var.environment, var.region)}"
description = "Policy for codebuild service role."
path = "/"
policy_document = "./policies/policy1.json"
account_id = "${module.account_id.id}"
log_group = "${var.name}Build${lookup(var.environment, var.region)}logGroup"
role_name = "${var.name}CodeBuildServiceRole${lookup(var.environment, var.region)}"
repository_arn = "${aws_codecommit_repository.ce_repo.arn}"
website_s3_bucket = "${aws_s3_bucket.website_bucket.arn}"
pipeline_s3_bucket = "${aws_s3_bucket.codepipeline_bucket.arn}"
subnet1 = "${element(split(",", module.public_subnet.subnet_ids), 0)}"
subnet2 = "${element(split(",", module.public_subnet.subnet_ids), 1)}"
}
Here's what I have in my ./policies/policy1.json:
{
"Effect": "Allow",
"Action": [
"ec2:CreateNetworkInterfacePermission"
],
"Resource": "arn:aws:ec2:us-east-1:${account_id}:network-interface/*",
"Condition": {
"StringEquals": {
"ec2:Subnet": ["${subnet1}", "${subnet2}"],
"ec2:AuthorizedService": "codebuild.amazonaws.com"
}
}
}
I begin to think this is not possible because IAM policy must have [] after "ec2:Subnet".
If there's a Wizard out there who can perform such sorcery, please share the ingredients to making this spell work in Terraform version 11x. :)
Thank you