Terraform: interpolation does not wait for resources to complete creation?

Created on 12 Jul 2017  ยท  5Comments  ยท  Source: hashicorp/terraform

Terraform Version

v0.9.11

Terraform Configuration Files

provider "aws" {
  region     = "eu-central-1"
  #access and secret key is in ~/.aws/credentials
}

resource "aws_ecr_repository" "ecr_repo" {
  name = "ecr-repo"
}
data "aws_iam_policy_document" "ecr_pull_policy_doc" {
  statement {
    sid = "InstancePull"
    effect = "Allow"
    principals {
      type        = "AWS"
      identifiers = ["${aws_iam_role.instance_role.arn}"]
    }
    actions = [
      "ecr:GetDownloadUrlForLayer",
      "ecr:BatchGetImage",
      "ecr:BatchCheckLayerAvailability"
    ]
  }
}
resource "aws_ecr_repository_policy" "ecr_policy_instance_pull" {
  repository = "${aws_ecr_repository.ecr_repo.name}"
  policy = "${data.aws_iam_policy_document.ecr_pull_policy_doc.json}"
}

resource "aws_iam_role" "instance_role" {
    name = "instance-role"
    assume_role_policy = "${file("../aws_policies/AssumeRolePolicy.json")}"
}

AssumeRolePolicy.json for IAM role

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

Expected Behavior

Every resource should be created properly.

Actual Behavior

If I call plan, it looks good. When I apply that plan, it also seems like the dependencies are right, It wants to create the ECR repository policy with the right json (correct instance role ARN is in place in output). But AWS sends back InvalidParameterException: Invalid parameter at 'PolicyText' failed to satisfy constraint: 'Invalid repository policy provided' . The interesting part is, if I call another plan + apply now, it creates the remaining resource (only the ECR policy, also listing the right ARN in place) correctly. and in AWS console I see the wanted results.

This does not happen if I hardcode an existing role ARN, so I think the interpolation does not wait for the referenced resource to be created. Maybe a dependency issue. Or I use something wrong, in this case please help me with a workaround. (if I add explicit dependency to the ECR policy resource with depends_on = ["aws_iam_role.instance_role"] the issue is still there...)

Steps to Reproduce

  1. terraform plan -out plan.tfplan
  2. terraform apply plan.tfplan
  3. AWS rejection happens, don't change anything
  4. terraform plan -out plan.tfplan
  5. terraform apply plan.tfplan
  6. It works just fine... ?!

References

I first thought it was a template rendering issue (at first I was trying with that) but when converted to IAM policy document, the issue remained. Maybe it has much deeper roots, Or I use something terribly wrong.

  • terraform-providers/terraform-provider-template#14
bug core

Most helpful comment

@Briansbum FYI the fix is here: https://github.com/terraform-providers/terraform-provider-aws/pull/1165
It looks like I'll have some time on the weekend. So, I might look into your issue; just for fun. Given that I can reproduce. :)

All 5 comments

After some additional digging, I found this old, closed issue: #2869 and I think the same situation happens with me, can you verify this? Am I missing something important?

Thanks,
elodani

I'm having a similar issue with aws_kms_ciphertext.

If I try to use the datasource anywhere then the plan will look okay but nothing can use it when applied.

In my case it looks like this:

provider "aws" {
  region     = "eu-west-1"
  #access and secret key is in ~/.aws/credentials
}

data "aws_kms_ciphertext" "cipher" {
  key_id    = "${aws_kms_alias.kms_alias.arn}"
  plaintext = "this is being encrypted"
}

resource "aws_lambda_function" "lambda_function" {
  filename         = "deploymentPackage.zip"
  function_name    = "${var.lambda_name}"
  role             = "${module.resolve-submodules.lambda_role_arn}"
  handler          = "index.lambda_handler"
  source_code_hash = "${base64sha256(file("deploymentPackage.zip"))}"
  runtime          = "python3.6"
  publish          = "true"

  environment {
    variables = {
      HOOK_URL = "${module.resolve-submodules.hook_url_cipher}"
    }
  }

  tags {
    LastUpdated = "${var.timestamp}-${var.iamuser}-Terraform"
  }
}

If I set the ciphertext as an output it will come out after apply is run but terraform apply will fail saying that it's unable to use the ciphertext.

Same as above, using depends_on doesn't resolve the issue.

The retry logic implemented by @frncmx solved my issue, I am closing this. Thank you.

@Briansbum FYI the fix is here: https://github.com/terraform-providers/terraform-provider-aws/pull/1165
It looks like I'll have some time on the weekend. So, I might look into your issue; just for fun. Given that I can reproduce. :)

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.

Was this page helpful?
0 / 5 - 0 ratings