How can we change provider settings during terraform apply with plan files?

Hi, I’m facing an issue when running terraform apply using plan files.

What I want to do is:

  • Run terraform apply using a plan file
  • Manage AWS resources of multiple AWS accounts using the official AWS Provider
  • Use different IAM Roles in terraform plan and apply

To manage AWS resources of multiple AWS accounts, I need to assume different IAM Roles by AWS Account.
So I need to define multiple provider blocks and define attributes such as assume_role and assume_role_with_web_identity.

https://registry.terraform.io/providers/hashicorp/aws/latest/docs#argument-reference

These settings are hardcoded in plan files and I can’t change them while running terraform apply.
If I try to change these settings by input variables for terraform apply, it fails.

$ terraform apply -var foo=foo plan.out
╷
│ Error: Can't set variables when applying a saved plan
│ 
│ The -var and -var-file options cannot be used when applying a saved plan file, because a saved plan includes the variable
│ values that were set when it was created.
╵

So I can’t change IAM Roles during terraform apply.
How can I resolve this issue?
I think this problem can occur with other providers such as google provider too.

1 Like

Hi @suzuki-shunsuke,

There’s two ways you can do this now:

  • You could avoid hardcoding the provider configuration and set the credentials externally via the standard AWS environment variables, or via the stored credentials for the provider.
  • You can use an ephemeral variable, which can change between plan and apply.

Thank you for your answer.

  • You could avoid hardcoding the provider configuration and set the credentials externally via the standard AWS environment variables, or via the stored credentials for the provider.

I can’t do this because I need to assume multiple IAM Roles.

To manage AWS resources of multiple AWS accounts, I need to assume different IAM Roles by AWS Account.
So I need to define multiple provider blocks and define attributes such as assume_role and assume_role_with_web_identity.

How can I change ephemeral variable between plan and apply?

You must re-supply any ephemeral variables during apply, which means you use the same method you used during plan, so the -var flag, a variable file, or TF_VAR_ environment variables. (if it’s an ephemeral input to a child module, that also then includes new ephemeral resources as well, but that is not typically going to be used for provider configuration)

1 Like

I think we can’t pass input variables when we run terraform apply with a plan file.

$ terraform apply -var foo=foo plan.out
╷
│ Error: Can't set variables when applying a saved plan
│ 
│ The -var and -var-file options cannot be used when applying a saved plan file, because a saved plan includes the variable
│ values that were set when it was created.
╵

Oh, I see. Maybe I misunderstood.
Can we pass input variables if they are ephemeral?
I’ll try it.

I’ve confirmed I could pass ephemeral variables when I ran terraform apply with a plan file.

variable "name" {
  type      = string
  ephemeral = true
}

resource "null_resource" "foo" {}
$ terraform plan -var name=foo -out plan.out
$ terraform apply -var name=yoo plan.out   
null_resource.foo: Creating...
null_resource.foo: Creation complete after 0s [id=1081784674738314124]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

It looks good.
I’ll try to change IAM Roles by ephemeral variables.

Thank you.

According to the document, seems like we can’t pass ephemeral values to provider blocks.

You can only reference ephemeral variables in specific contexts or Terraform throws an error. The following are valid contexts for referencing ephemeral variables:

If another expression references an ephemeral variable, that expression implicitly becomes ephemeral.

But I’ve confirmed I could pass an ephemeral value to provider’s region attribute.
I’m not sure if this is a bug or not.

$ terraform version
Terraform v1.10.2
on darwin_arm64
+ provider registry.terraform.io/hashicorp/aws v3.71.0
variable "region" {
  type      = string
  ephemeral = true
}

provider "aws" {
  region = var.region
}
terraform plan -var region=ap-northeast-1 # Succeeded
1 Like

Using it in a provider is perfectly fine, providers are one of the only current endpoints for ephemeral values! Looks like something was lost through the documentation writing process.

Thanks!

2 Likes