-
Notifications
You must be signed in to change notification settings - Fork 9.4k
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
Instantiating Multiple Providers with a loop #19932
Comments
With a more generic formulation, it would be great to have a |
Has anyone ever found any kind of workaround for this kind of scenario? We have multiple AWS accounts and would like to be able to deploy modules across all accounts without having to have repeatable code for each account. |
@jaken551 Have you tried this with Terraform 0.12 ? Did you make any progress? I ask because I'm looking for the same functionality. |
We are using terraform To summarize, the ask here is to allow
@hhh0505 Our current workaround is for our main terraform pipeline to create:
At this point, the individual workspaces act as the pipelines to their child accounts. As for the boilerplate code, they can be updated in the main pipeline's repo and will propagate to the downstream repos whenever the main terraform runs. |
@jaken551 @kuwas - I'd also like to see provider blocks support for_each. My use case being creating aws_ses_domain_identity resources in multiple regions. These regions being defined by a list variable i.e.
|
One workaround is, you need to maintain separate directory for each account and call the same terraform module by passing correct values to the modules / keep some default values. to run plan / apply in all directory use wrapper such as terragrunt. |
I'm an enterprise user and doing a for_each over the vault provider would reduce a lot of code if you could just do:
instead of copy pasting the same piece for each namespace. |
Terraform deployment environment protection using separated Cloud Providers accounts is a great method to reduce configuration/deployment error Blast Radius. E.g. different AWS accounts can be used to make deployment environments of any kind (devel, stage, prod, sandbox), with potentially a lot of account with same "common configuration". Without a solution like for_each in provider block lot of identical code must be replicated, raising a lot the risk of typing errors on addition of each new account/environment.
Based on account info like:
for_each in provider allow to achieve a common configuration using DRY code blocks, looping on accounts as base key for many decoupled resources:
|
+1 on this. We would like to use Terraform to deploy/manage IAM Roles in a list of AWS Accounts -- assuming a known role in each account for access. Below is an example implementation that would work for us with Terraform >v0.13 and the existing ## Just some data... a list(map())
locals {
aws_accounts = [
{ "aws_account_id": "123456789012", "foo_value": "foo", "bar_value": "bar" },
{ "aws_account_id": "987654321098", "foo_value": "foofoo", "bar_value": "barbar" },
]
}
## Here's the proposed magic... `provider.for_each`
provider "aws" {
for_each = local.aws_accounts
alias = each.value.aws_account_id
assume_role {
role_arn = "arn:aws:iam::${each.value.aws_account_id}:role/TerraformAccessRole"
}
}
## Modules reference the provider dynamically using `each.value.aws_account_id`
module "foo" {
source = "./foo"
for_each = local.aws_accounts
providers = {
aws = "aws.${each.value.aws_account_id}"
}
foo = each.value.foo_value
}
module "bar" {
source = "./bar"
for_each = local.aws_accounts
providers = {
aws = "aws.${each.value.aws_account_id}"
}
bar = each.value.bar_value
} As a workaround for not having |
Allowing alias as a variable in the provider config would also make for cleaner code:
In this case, the module |
@DonBower AFAIK, alias is allowed in the providers config for modules |
It is. but not as a variable....
original comment updated.... |
@ajbouh @DonBower I recall reading a comment from @apparentlymart on the reasoning around this current limitation. Example 1: this does not work
Example 2: this also does not work
Example 3: this does work
|
I've literally tried to this exact same thing and have been unable.
I'm actually pretty upset that I cant do it, as with peering each "peer" would need to go into another subscription! Sigh. |
Any updates if this is on the roadmap? |
Hi, Passing a provider as variable would be very useful, is it doable ? |
Any updates? Also depends from this ... provider "aws" {
alias = "euwestprovider"
region = "eu-west-1"
...
}
provider "aws" {
alias = "eucentralprovider"
region = "eu-central-1"
...
}
resource "aws_instance" "ec2-eu-west"{
provider = "aws.euwestprovider"
ami = "ami-030dbca661d402413"
instance_type = "t2.nano"
}
resource "aws_instance" "ec2-eu-central" {
provider = "aws.eucentralprovider"
ami = "ami-0ebe657bc328d4e82"
instance_type = "t2.nano"
}
|
Any updates from the team? |
+1 on the topic. |
In my humble but perhaps irrelevant opinion, Terraform 1.0 shouldn't be released until this feature is implemented. |
Hey all 👋 - I found a An example using two S3 buckets in different regions:
in ./s3s:
This solution was inspired by this Stack Overflow answer. |
Big +1 to get this fixed please. Just dealing with the available regions is hard; I can't imagine having to deal with this for multiple AWS accounts. |
Hello, With which version will this be possible again? |
@vierkean this should probably be opened as question on the hashicorp developer forums. However, providers within modules can be defined using the There is a notable exception to the legacy passing providers by alias which is that now all providers defined in the |
For anyone looking for a workaround, there's really only one that made sense to me: Multiple invocations of the same plan with different inputs for each provider. I run my configuration in a CI/CD job matrix, each with different provider credentials/configs for the terraform command's environment. IMO, completely feasible for most use-cases. And I think in cases where it isn't, there's probably a code smell somewhere which could be taken care of with a little refactoring. |
@deepbrook I'm likely missing something here ... but does that mean you are maintaining a single deployment (plan/apply/state file) per distinct provider instance in your environment? |
@kahawai-sre I don't use a job matrix like @deepbrook mentioned but I basically took the same approach. Yes, for me I have a separate deployment/state per provider instance (different regions). We haven't had any issues so far as we scale. For handling resource dependencies I use Terragrunt. I use it for other stuff too but it makes it really easy to handle the inter-deployment dependency piece. |
@kahawai-sre, that's exactly what that means, yes :) My deployments do not run at a big scale, to be fair. As for approvals, I do not have those - I deploy infrastructure to preprod and run tests to ensure all features required are reachable/configured correctly, and then deploy them. I do have some dependencies between the deployments; since my infrastructure isn't managed in a single repository, but several ones (basic platform infra like networking and IAM roles in one, k8s cluster and database in another one each, etc) It's only matter of triggering down-stream pipelines (I like pipelines :P ). @Mike-Nahmias approach using terragrunt sounds like a good alternative if you're a mono repo kinda person. :) |
Same issue - New day... I have a load of terraform deploying resources to several environments, each requiring their own provider alias I want to dedupe this lovely collection of n00dles to a single resource block with a for_each loop that iterates over a local or var that provides the required provider alias for each resource I don't want to have to use modules for this as I feel it's an ugly way of doing this and will make things far harder and more complicated than the how I'm doing it now (separating each resource block, and any associated resources, out into it's own file), which makes it very easy to deploy new resources of the same type (ctrl-C, Ctrl-V - change the names of the guilty, and et viola! there you are) What I want is to be able to have something like this resource "resource_type" "resource_name" { Without being told that "each" is an invalid provider reference This is a major hole, and an old hole - one that should've been backfilled in years ago Can we please get some action on this? and save me from having to go down the ugly bunny hole of modules? TIA |
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
700 upvotes on this makes me think that it's something we should at least get some sort've update / explanation on why this isn't possible. A ton of the Terraform configurations just "work" with this type of syntax, why not providers as well? |
This comment was marked as off-topic.
This comment was marked as off-topic.
There's another request like this, but the developer stated that providers are loaded on init and it would have to be rearchitected. Technically provider_override could be an option within a provider. |
Fwiw, we've solved this problem using TL;DR: I acknowledge why at first glance not supporting multiple providers in a loop seems like an awful limitation and why some things would be simplified if it were supported; that said, we deploy enormous infrastructures at Cloud Posse in strict enterprise environments, and don't feel any impact of this inherent limitation. |
I could not agree more to @osterman I'm following this thread since a long time and I also came here because I thought that I needed this feature. Meanwhile I think that relying on a feature like this could possibly be a sign of a bad design. As @osterman said - just think of the enourmous blast radius. One could argue that there are certain cases where you e.g. want to dynamically create provider instances e.g. in an AWS organization to assume the OrganizationAccountAccessRole for bootstrapping things. But once you think about managing the whole lifecycle of hundreds of those accounts you'll realize that this does not scale. Instead I now use AFT with AWS Control Tower to customize those accounts. And maybe a few words on all the hate against Hashicorp. I also think that their pricing model Yes, Hashicorp is bad at communication. And in my opinion they somehow now try to squeeze a lot of money out of their customers. But please do not forget what their impact on our community had been. I remember the old days back in around 2010 when @mitchellh created Vagrant. It was the first time we could manage those VM in a way which did not suck. Having said all the those things… I understand the demand and I feel that the lack of communication from Hashicorp contributed to this situation. They better could have pointed out the reasons this feature is not available and demonstrate how to solve this problem by proper design. Love matters, |
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
There's another use case which I think hasn't been mentioned: Optional resource creation within a module. I have a module which mostly provisions AWS resources, but there's a single Github resource that is created conditionally (if a particular key is present in one of the module's variable objects). It's likely that many of the people using the module aren't using Github, or don't need this particular feature / resource, so I don't want to add it to the required providers block. |
Current Terraform Version
Use-cases
In my current situation, I am using the AWS provider so I will scope this feature request to that specific provider, although this may extend to other providers as well.
I am attempting to create resources in multiple AWS accounts. The number of the accounts ranges from 0....x and will be dynamic. I would like to be able to instantiate multiple providers which can assume a role in each account, and in turn, create resources with the associated provider without hard-coding providers for each subsequent account.
For example, something like this:
The text was updated successfully, but these errors were encountered: