Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

conditional in module output #12475

Closed
PurrBiscuit opened this issue Mar 6, 2017 · 10 comments
Closed

conditional in module output #12475

PurrBiscuit opened this issue Mar 6, 2017 · 10 comments

Comments

@PurrBiscuit
Copy link
Contributor

Having trouble setting conditionals in a module's output to ignore resource output interpolation if the resource isn't being created due to a count conditional.

Terraform Version

0.8.7

Affected Resource(s)

all resources but in this case specifically trying to work with

  • aws_iam_role
  • aws_iam_instance_profile

Terraform Configuration Files

resource "aws_iam_instance_profile" "profile" {
  count = "${var.aws_region == "us-east-1" ? 1 : 0}"

  name  = "packer-builder"
  roles = ["${aws_iam_role.role.name}"]
}

resource "aws_iam_role" "role" {
  count = "${var.aws_region == "us-east-1" ? 1 : 0}"

  name = "packer-builder"
  assume_role_policy = "${file("roles/assume_ec2.json")}"
}

output "role_arn" {
  value = "${var.aws_region == "us-east-1" ? aws_iam_role.role.arn : "no_role"}"
}

output "profile_name" {
  value = "${var.aws_region == "us-east-1" ? aws_iam_instance_profile.profile.name : "no_profile"}"
}

Expected Behavior

Ignore the resource attribute outputs in the output resources if those resources aren't being created in a region. Right now we only want our us-east-1 terraform state to manage out IAM roles in AWS (since they are global per account.) The conditional in the output resource is still trying to evaluate the aws_iam_instance_profile.profile.name resource output even when the region is eu-central-1.

Actual Behavior

Since terraform isn't creating these resources in that region, due to the count conditional being used on them it's failing terraform plans in that region with:

will not be persisted to local or remote state storage.

data.terraform_remote_state.core: Refreshing state...

Error running plan: 1 error(s) occurred:

* Resource 'aws_iam_role.role' not found for variable 'aws_iam_role.role.arn'
exit status 1

Steps to Reproduce

Please list the steps required to reproduce the issue, for example:

  1. terraform plan
@tszym
Copy link

tszym commented Mar 8, 2017

Seems due to hashicorp/hil#50

@gstlt
Copy link

gstlt commented Mar 13, 2017

Terraform version: 0.8.8

I think have a similar case:

data "template_file" "s3_ro" {
  template = "s3-iam-deployment/s3-deployment-ro.json.tpl"
  vars {
    bucket_name= "${var.deployment_bucket}"
  }
}

data "template_file" "s3_principal" {
  template = "s3-iam-deployment/s3-principal.json.tpl"
}

resource "aws_iam_role" "s3_deployment" {
  name = "${var.name}-deployment"
  path = "/"
  assume_role_policy = "${data.template_file.s3_principal.rendered}"
}

resource "aws_iam_role_policy" "s3_ro" {
  name = "${var.name}-s3-ro"
  role = "${aws_iam_role.s3_deployment.unique_id}"
  policy = "${data.template_file.s3_ro.rendered}"
}

JSON files for reference:
s3-principal.json.tpl

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "sts:AssumeRole"
      ],
      "Principal": {
        "Service": "s3.amazonaws.com"
      }
    }
  ]
}

s3-deployment-ro.json.tpl

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:ListObjects",
        "s3:ListBucket",
        "s3:ListAllMyBuckets"
      ],
      "Resource": [
        "arn:aws:s3:::${bucket_name}",
        "arn:aws:s3:::${bucket_name}/*"
      ]
    }
  ]
}

Error after invoking terraform plan:

Error running plan: 1 error(s) occurred:

* Resource 'aws_iam_role.s3_deployment' not found for variable 'aws_iam_role.s3_deployment.unique_id'

Documentation is not specific on which role argument for aws_iam_role_policy, but I assume I used it right. If not, please point my error.

Hope that helps on debugging it. Cheers!

EDIT2:
More detailed information as I'm trying to get to the bottom of this:
Commenting aws_iam_role_policy resulted in following:

Error running plan: 1 error(s) occurred:

* module.frontend.aws_iam_role.s3_deployment: "assume_role_policy" contains an invalid JSON: invalid character 's' looking for beginning of value

@PurrBiscuit
Copy link
Contributor Author

@gstlt try changing it to "${aws_iam_role.s3_deployment.id}" vs "${aws_iam_role.s3_deployment.unique_id}" in your resource "aws_iam_role_policy" "s3_ro" { block

@gstlt
Copy link

gstlt commented Mar 13, 2017

@PurrBiscuit Tried with an id and with arn, same result. Thanks.

But when putting JSON file inline (like below) it suddenly works perfectly. I'm guessing rendering is screwing up with JSON syntax somehow....


resource "aws_iam_role" "s3_deployment" {
  name = "${var.name}-deployment"
  path = "/"
  # assume_role_policy = "${data.template_file.s3_principal.rendered}"
  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "sts:AssumeRole"
      ],
      "Principal": {
        "Service": "s3.amazonaws.com"
      }
    }
  ]
}
EOF
}

Note: Terraform version 0.8.8

@gstlt
Copy link

gstlt commented Mar 13, 2017

A solution: Since the policy is not a "real" template, I could (or should) use file() instead template in this case (see below). I decided on template to have my options open in case I need some variables there. I guess using it this way shouldn't screw up with JSON.


resource "aws_iam_role" "s3_deployment" {
  name = "${var.name}-deployment"
  path = "/"
  assume_role_policy = "${file("${path.module}/files/s3-principal.json.tpl")}"
}

EDIT: I'd say it's not the same issue after all, but will leave comments for a reference :) Sorry for spamming.

@apparentlymart
Copy link
Contributor

Hi all! Sorry things aren't working as expected here.

This looks like the same issue as #11566, with a dash of #9080. Since we already have an issue tracking this, I'm going to close this one to consolidate discussion over there. Note that there is a workaround document in the comments there, of using the splat syntax to refer to the zero or one resources in a conditional set.

Thanks for reporting this!

@jdimatteo
Copy link

jdimatteo commented Dec 30, 2017

To save you some clicking, here is an example work around if count is always either zero or 1:

output "foo" {
  value = "${ join(" ", aws_route53_record.bar.*.name) }"
}

hashicorp/hil#50 (comment)

@rbngzlv
Copy link
Contributor

rbngzlv commented Mar 22, 2018

This is my workaround. I hope it helps someone.

resource "aws_subnet" "public_a" {
  vpc_id            = "${aws_vpc.main.id}"
  cidr_block        = "10.0.0.0/24"
  availability_zone = "eu-west-1a"

  tags {
    Name = "Public Subnet A"
  }
}

# ... b, c

resource "aws_subnet" "private_a" {
  count = "${var.create_private_subnet == true ? 1 : 0}"

  vpc_id            = "${aws_vpc.main.id}"
  cidr_block        = "10.0.100.0/24"
  availability_zone = "eu-west-1a"

  tags {
    Name = "Private Subnet A"
  }
}

# ... b, c

output "database_subnet_ids" {
  value = [
    "${coalesce(join("", aws_subnet.private_a.*.id), join("", aws_subnet.public_a.*.id))}",
    "${coalesce(join("", aws_subnet.private_b.*.id), join("", aws_subnet.public_b.*.id))}",
    "${coalesce(join("", aws_subnet.private_c.*.id), join("", aws_subnet.public_c.*.id))}"
  ]
}

@st4nson
Copy link

st4nson commented Sep 6, 2018

EDIT: Nah after further testing, it's not working too good. terraform apply must be rerun to apply that...

Ternary operator works for me. My use case is a bit ugly though ;)

Terraform version v0.11.5

output "connection_ips_ceph" {
  value = "${var.count_ceph != 0 ? "\n ssh ${var.login_user}@${join("\n ssh ${var.login_user}@",  openstack_networking_floatingip_v2.fip_ceph.*.address)}" : ""}"
}

@ghost
Copy link

ghost commented Apr 2, 2020

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 have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@ghost ghost locked and limited conversation to collaborators Apr 2, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

8 participants