Hassan Syyid
Hassan Syyid

Reputation: 1581

Terraform 0.12: Provider produced inconsistent final plan

I have a Terraform configuration which creates an aws_api_gateway_usage_plan resource, using a computed value during the apply stage from a local_file resource.

resource "aws_api_gateway_usage_plan" "api_plan" {
  name         = var.usage_plan_name

  api_stages {
    api_id = jsondecode(file("dev.json")).resources[1].rest_api_id
    stage  = "api"
  }

  # Have to wait for the API to be created before we can create the usage plan
  depends_on = [local_file.chalice_config]
}

As you can see, I read dev.json to determine the api_id Terraform needs. The problem is that when I run terraform apply, the new safety checks described here notice that the previous value that api_id evaluated to has changed!

Provider produced inconsistent final plan: When expanding the plan for aws_api_gateway_usage_plan.api_plan
to include new values learned so far during apply, provider "aws" produced an invalid new value 
for .api_stages[0].api_id: was cty.StringVal("****"), but now cty.StringVal("****").

As that documentation describes, the correct way to solve this error is to specify that during the plan phase this api_id actually has yet to be computed. The problem is I'm not sure how to do this through a Terraform config - the documentation I've referenced is for the writers of the actual Terraform providers.

Looking at issues on GitHub, it seems like setting the initial value to null isn't a reasonable way to do this.

Any ideas? I am considering downgrading to Terraform 0.11 to get around this new safety check, but I was hoping this would be possible in 0.12.

Thanks in advance!

Upvotes: 4

Views: 7516

Answers (3)

Md. Shohag Mia
Md. Shohag Mia

Reputation: 354

I was facing the same issue while creating lambda event source mapping. I overcome from it running terraform plan and then terraform apply

Upvotes: 1

Rotem jackoby
Rotem jackoby

Reputation: 22068

I've got the same error when encoded my user_data scripts (with filebase64 or base64encode) in places where I add to just simply use file or templatefile :

  user_data = file("${path.module}/provisioning_scripts/init_script.sh")

  user_data = templatefile("${path.module}/provisioning_scripts/init_script.tpl", {
    USER  = "my-user"
    GROUP = "my-group"
  })

(*) I can't 100% reproduce it but I'm adding this solution as another possible reason for receiving the mentioned error.


Read also in here.

Upvotes: 0

Hassan Syyid
Hassan Syyid

Reputation: 1581

Okay, after thinking for a while I came up with a silly workaround that enabled me to "trick" Terraform into believing that the value for the api_id was to be computed during the apply phase, thereby disregarding the safety check.

What I did was replace the api_id expression with the following:

api_id = replace("=${aws_security_group.sg.vpc_id}=${jsondecode(file("files/handler/.chalice/deployed/dev.json")).resources[1].rest_api_id}", "=${aws_security_group.sg.vpc_id}=", "")

Essentially what I am doing is saying that the api_id's value depends on a computed variable - namely, the vpc_id of a aws_security_group I create named sg. In doing so, Terraform recognizes this value is to be computed later, so the safety check is ignored.

Obviously, I don't actually want to have the vpc_id in here, so I used Terraform's string functions to remove it from the final expression.

This is a pretty hacky workaround, and I'm open to a better solution - just thought I'd share what I have now in case someone else runs into the same issue.

Thanks!

Upvotes: 3

Related Questions