-
Notifications
You must be signed in to change notification settings - Fork 907
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
Dynamic provider configuration assignment #300
Comments
Hey @RafPe thanks for submitting! To help us maintain a clear separation between opentf and hashicorp's offerings, we're asking that people describe issues that are in other repositories rather than linking those directly. If there's any more context or description to the problem you think would be good to share and add in please do. Thanks! |
@roni-frantchi Sure - I understand. Let me explain more in detail what I mean here. Situation now :we define our providers more less in a static way ( there is a level where we can use variables ) and then reference them completely static (no vars, no dynamics etc )
Scenario 1dynamically referencing providers: Having the above providers, we could either have something in form of
Scenario 2dynamically referencing providers with for_each/count: Having the same above providers, we could either have something in form of
I believe this approach ( especially in bigger organisations ) would allow for more automation and maintaining the logic within the tool instead of leveraging external templating mechanism Please let me know if the above makes sense :) |
In my situation I have multiple AWS accounts (dev, test, prod). All accounts use the us-west-2 region, but the prod account also uses a few other regions. So in my case I really need one provider enabled when deploying to dev and test and multiple providers enabled when deploying to prod. I am able to work around this currently by just including all regional providers in all accounts and I just don’t use the extra providers during a dev or test deploy. This work around no longer works though when you have a module that needs to be deployed to multiple AWS partitions. For example standard and govcloud. A govcloud provider will not work when deploying to a standard partition and a standard provider will not work when deploying to govcloud. In this situation I am able to work around this by using some custom code outside of opentofu to generate the provider config before running opentofu. It would be nice to just have the ability to do loops and conditionals on providers. |
This could be OpenTF's killer app ;) |
@roni-frantchi as I myself would be open to contributing to this ... would eb anyone else experienced already in the code base that could guide me towards making this possible ? |
Hey @RafPe !
Very much appreciated.
Of course if you're willing to dive in there yourself or assisted by anyone else from the community would love to see such a design from you |
Ref to issue in terraform repo, quite a bit of discussion over there on it: hashicorp/terraform#19932 |
Issue 19932 has been open since Jan 7th 2019 - it doesn't look like it's been given much love since Plenty of people wanting this ability (myself included) This ability would be fantastic, and yes, bring people over to the Open Source side |
This needs to be fixed ASAP, 3 years are a lot |
With the way providers currently work, esp. with for_each blocks, this would require a very technical and detailed RFC prior to being accepted. But overall, we're open to adding this as an OpenTofu feature, if we come up with a good way to do so. |
@cube2222 maybe I do not see the whole technical picture - but would it for example be possible to split it in two working items ?
Feels like doing the |
I think that makes sense, as |
Scenario 2 feels like it'll cover most of the cases I encounter in the wild... but I say without any hesitation that no matter how unergonomic the solution is, I'll figure it out and use it and be happy to have it. That being said, would it be possible to configure and pass a provider like:
|
Something worth noting, I think the |
In this case this helps for people in the mean time. I've used workspaces with a specific tfvars containing a variable for the region as a workaround for creating the same resources in multiple regions or multiple accounts.
variable region {}
variable account {}
provider aws {
region = var.region
assume_role {
role_arn = "arn:aws:iam::${module.account_map.accounts[var.account]}:role/cicd"
}
}
region = "us-west-2"
account = "dev" Commands terraform workspace select uw2-dev
terraform init -var-file uw2-dev.tfvars |
As of now, I think you're right about workspaces being the best answer when needing dynamic providers. I've done something similar like the following in Azure: locals {
cntxts = {
defaults = {
subscription_id = "00000000-0000-0000-0000-000000000000"
dynamic_subscription_id = "12345678-0000-0000-0000-000000000000"
tenant_id = "00000000-0000-0000-0000-000000000000"
}
dev = {
dynamic_subscription_id = "abcdefgh-0000-0000-0000-000000000000"
}
infra = {
dynamic_subscription_id = "abc123hi-0000-0000-0000-000000000000"
}
stg = {
dynamic_subscription_id = "foobar12-0000-0000-0000-000000000000"
}
prd = {
dynamic_subscription_id = "RunningO-utOf-Gene-ricG-UIDideas1234"
}
}
contexts = module.contexts.merged
default_subscription_id = local.contexts.subscription_id
dynamic_subscription_id = local.contexts.dynamic_subscription_id
tenant_id = local.contexts.tenant_id
# where workspaces are like (dev, infra, stg, prd)
context = terraform.workspace
}
module "contexts" {
source = "Invicton-Labs/deepmerge/null"
maps = [
local.cntxts.defaults,
local.cntxts[local.context],
]
}
provider "azurerm" {
alias = "default"
subscription_id = local.default_subscription_id
tenant_id = local.tenant_id
}
provider "azurerm" {
alias = "dynamic"
subscription_id = local.dynamic_subscription_id
tenant_id = local.tenant_id
}
However, this often forces you into architecture patterns that could be more simply solved with a loop of providers |
Hello,
Kind Regards |
Signed-off-by: ollevche <[email protected]> Signed-off-by: Christian Mesh <[email protected]>
Signed-off-by: ollevche <[email protected]> Signed-off-by: Christian Mesh <[email protected]>
Signed-off-by: ollevche <[email protected]> Signed-off-by: Christian Mesh <[email protected]> Co-authored-by: Christian Mesh <[email protected]> Signed-off-by: Christian Mesh <[email protected]>
…es (#1963) Signed-off-by: ollevche <[email protected]> Signed-off-by: Ronny Orot <[email protected]> Signed-off-by: Christian Mesh <[email protected]> Co-authored-by: ollevche <[email protected]> Co-authored-by: Christian Mesh <[email protected]> Signed-off-by: Christian Mesh <[email protected]> Signed-off-by: Christian Mesh <[email protected]>
This RFC describes an alternative approach for issue #300 that treats it as a dynamic evaluation problem rather than as an early-eval problem. For the moment my goal of this proposal is not to actually replace the existing early eval proposal, but rather to draw attention to some aspects of it that would be difficult to translate to fully-dynamic eval if we heard requests for that later. This document therefore aims to ask the question of firstly whether we'd like to impose some similar constraints on the early eval approach even though they aren't strictly needed there, and secondly whether this realization that we don't have any current experience retroactively changing a feature from early eval to dynamic eval represents enough risk that we might prefer to put even the early-eval approach on pause while we analyze the potential risks in more detail. It's likely that if we _did_ choose to implement the dynamic approach we'd want to refine this RFC further to draw out some more detail in the implementation section. I've intentionally skimped on that section here because the priority is to have the conversation about the potential new user-facing constraints, and not to actually implement what this proposal describes in the near future. The implementation details are included as a starting point, but are insufficiently detailed to actually begin implementation. Signed-Off-By: Martin Atkins <[email protected]>
Signed-off-by: ollevche <[email protected]> Co-authored-by: Christian Mesh <[email protected]> Signed-off-by: Christian Mesh <[email protected]>
Signed-off-by: ollevche <[email protected]> Signed-off-by: Christian Mesh <[email protected]>
Signed-off-by: ollevche <[email protected]> Signed-off-by: Christian Mesh <[email protected]>
Signed-off-by: ollevche <[email protected]> Signed-off-by: Christian Mesh <[email protected]> Co-authored-by: Christian Mesh <[email protected]> Signed-off-by: Christian Mesh <[email protected]>
…es (#1963) Signed-off-by: ollevche <[email protected]> Signed-off-by: Ronny Orot <[email protected]> Signed-off-by: Christian Mesh <[email protected]> Co-authored-by: ollevche <[email protected]> Co-authored-by: Christian Mesh <[email protected]> Signed-off-by: Christian Mesh <[email protected]> Signed-off-by: Christian Mesh <[email protected]>
Signed-off-by: ollevche <[email protected]> Co-authored-by: Christian Mesh <[email protected]> Signed-off-by: Christian Mesh <[email protected]>
Signed-off-by: ollevche <[email protected]> Signed-off-by: Christian Mesh <[email protected]>
Signed-off-by: ollevche <[email protected]> Signed-off-by: Christian Mesh <[email protected]>
Signed-off-by: ollevche <[email protected]> Signed-off-by: Christian Mesh <[email protected]> Co-authored-by: Christian Mesh <[email protected]> Signed-off-by: Christian Mesh <[email protected]>
…es (#1963) Signed-off-by: ollevche <[email protected]> Signed-off-by: Ronny Orot <[email protected]> Signed-off-by: Christian Mesh <[email protected]> Co-authored-by: ollevche <[email protected]> Co-authored-by: Christian Mesh <[email protected]> Signed-off-by: Christian Mesh <[email protected]> Signed-off-by: Christian Mesh <[email protected]>
Will this feature allow us to use the provider block as a dependency? |
I was testing the
As the key is not part of the error, it's very hard to find which one has an issue; it would be nice to have something more like:
|
Not in this feature. Take a look at #2088 for thoughts to expand upon the existing provider configuration. |
@thuck thanks for the feedback, can you post the full error so I can make sure I update that log message? |
@cam72cam no problem at all.
Here the main.tf that I'm using to test:
|
Hi all! I realize that yesterday I neglected to explicitly mention here that v1.9.0-alpha2 includes an early version of a solution for this feature that we've been working on over in #2123. If you have the time and interest, we'd love to hear feedback from folks who try this with somewhat-realistic configurations that match whatever problems had caused them to be interested in this issue. Please don't use this in production, though! It's tough to keep track of multiple threads of conversation in a single GitHub issue, and we'd like to keep this issue focused on the use-case rather than on details of the initial solution to it, so if you do try the alpha and have feedback please open a new issue for each feedback item, and then we'll collect links to them in #2123 to make sure we can investigate each one. Thanks! EDIT: I originally wrote this comment linking to alpha1, but we've just published alpha2 with some important fixes so I'd ask that anyone who wants to test this should focus on testing with alpha2 instead. |
I'm attempting to fetch a list of AWS Account IDs from the remote state of a separate OpenTofu configuration, and dynamically generate providers for each on 1.9.0-alpha2. Is this outside the scope of the current enhancement? data "terraform_remote_state" "org" {
backend = "s3"
config = {
bucket = var.s3_bucket_name
key = "terraform-aws-org/terraform.tfstate"
region = var.aws_region
}
}
locals {
account_ids = values(data.terraform_remote_state.org.outputs.member_account_ids)
}
provider "aws" {
alias = "child"
for_each = toset(local.account_ids)
region = var.aws_region
assume_role {
role_arn = "arn:aws:iam::${each.key}:role/OrganizationAccountAccessRole"
session_name = "TerraformSession-${each.key}"
}
} tofu plan
╷
│ Error: Dynamic value in static context
│
│ on locals.tf line 4, in locals:
│ 4: account_ids = values(data.terraform_remote_state.org.outputs.member_account_ids)
│
│ Unable to use data.terraform_remote_state.org in static context, which is required by local.account_ids
╵
╷
│ Error: Unable to compute static value
│
│ on providers.tf line 5, in provider "aws":
│ 5: for_each = toset(local.account_ids)
│
│ provider.aws.child.for_each depends on local.account_ids which is not available
╵ |
Hi @kylan11, Indeed, for this first iteration of the feature the We are hoping to extend it to be fully-dynamic in future -- #2088 is representing that -- but we wanted to get an initial version of this out sooner, with less risk, and then iterate on it. We'll be making new issues to represent some of the intentionally-omitted capabilities in this first release soon, as we get closer to the v1.9.0 beta period and its final release. I expect we'll add a comment linking to all of those issues here once we've created them, so that folks can vote on them separately to help prioritize that work. For now you will need to specify your set of account ids either statically inside the configuration, or as an input variable. Thanks! |
@apparentlymart Apologies for posting here! I read your last comment too late. Thank you! |
This is really great and interesting, thanks for working on it 👍 I have a question though. Are the following use cases covered by this issue? Usecase1: Usecase2: variable "dns_record" {
type = object({
create = bool
zone = string
provider = string
record = string
})
description = "DNS record for the controlplane. Provider can be cloudflare, aws, azure"
} My provider config has all needed providers. Currently this fails as I must provide valid credentials for all providers even if only Cloudflare is actually used. Only the providers which have aktive resources should be initialized in the first place. Question: |
Suggest an existing issue in legacy Terraform to fix in OpenTF.
To increase automation we struggle many times when configuring providers. It would be great to finally be able to configure them dynamically or at least to be able to dynamically reference them instead of having all of that statically typed
Implementation PR: #2054
The text was updated successfully, but these errors were encountered: