Skip to content
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

Unable to use Dynamic Roles created inside of sub modules as providers #2282

Closed
spanhotra opened this issue Dec 19, 2023 · 2 comments
Closed
Labels
bug Used to mark issues with provider's incorrect behavior

Comments

@spanhotra
Copy link

Terraform CLI and Provider Versions

Terraform v1.6.4
on windows_amd64

  • provider registry.terraform.io/hashicorp/aws v5.30.0
  • provider registry.terraform.io/snowflake-labs/snowflake v0.80.0

Your version of Terraform is out of date! The latest version
is 1.6.6. You can update by downloading from https://www.terraform.io/downloads.html

Terraform Configuration

main.tf 

provider "snowflake" {
  alias = "sf_dba"
  role  = module.base.snowflake_dba_role_name

  private_key   = "from aws secrets"
  authenticator = "JWT"
}

module "base" {
  source = "./modules/base"

  data_retention_time_in_days     = var.data_retention_time_in_days
  enable_query_acceleration_bi_wh = var.enable_query_acceleration_bi_wh
  snowflake_analyst_user_list     = var.snowflake_analyst_user_list
  allowed_ip_list                 = var.allowed_ip_list

  create_tagging_structure    = var.create_tagging_structure
  datamart_tag_allowed_values = var.datamart_tag_allowed_values

  providers = {
    snowflake.sf_sysadmin      = snowflake.sf_sysadmin
    snowflake.sf_accountadmin  = snowflake.sf_accountadmin
    snowflake.sf_dba           = snowflake.sf_dba
    snowflake.sf_securityadmin = snowflake.sf_securityadmin
    snowflake.sf_useradmin     = snowflake.sf_useradmin
  }
}

module "base" {
  source = "./modules/base"

  providers = {
    snowflake.sf_sysadmin      = snowflake.sf_sysadmin
    snowflake.sf_accountadmin  = snowflake.sf_accountadmin
    snowflake.sf_securityadmin = snowflake.sf_securityadmin
    snowflake.sf_useradmin     = snowflake.sf_useradmin
  }
}


# base module 

main.tf
terraform {
  required_providers {
    snowflake = {
      source                = "Snowflake-Labs/snowflake"
      version               = "~> 0.35"
      configuration_aliases = [snowflake.sf_sysadmin, snowflake.sf_accountadmin, snowflake.sf_securityadmin, snowflake.sf_useradmin]
    }
  }
}

resource "snowflake_role" "dba_role" {
  provider = snowflake.sf_securityadmin
  name     = "DBA"
  comment  = "Cloud Data Warehouse Administrator."
}

Expected Behavior

Role should get created and I should be able to use it in other sub modules.

Actual Behavior

Plan: 14 to add, 0 to change, 0 to destroy.

│ Error: open snowflake connection: 390189 (08004): Role 'DBA' specified in the connect string does not exist or not authorized. Contact your local system administrator, or attempt to login with another role, e.g. PUBLIC.

│ with provider["registry.terraform.io/snowflake-labs/snowflake"].sf_dba,
│ on main.tf line 45, in provider "snowflake":
│ 45: provider "snowflake" {

Steps to Reproduce

  1. terraform plan

How much impact is this issue causing?

High

Logs

https://gist.github.com/spanhotra/3946daf2bbe6ed542b702e98b4e8d316

Additional Information

It was working until 2 weeks ago.

@spanhotra spanhotra added the bug Used to mark issues with provider's incorrect behavior label Dec 19, 2023
@sfc-gh-swinkler
Copy link
Collaborator

Hello @spanhotra !

While it is an interesting use case, there isn't much we can do about it, as this is the intended behavior of Terraform providers. Values for configuration arguments to providers must be known during the plan. In this example, the role would not be known until after the apply, so it is rightfully throwing an error about the role not existing. From the official documentation on provider configuration:

https://developer.hashicorp.com/terraform/language/providers/configuration#provider-configuration-1

You can use expressions in the values of these configuration arguments but can only reference values that are known before the configuration is applied. This means you can safely reference input variables but not attributes exported by resources (with an exception for resource arguments that are specified directly in the configuration).

What you could do instead is perform a two-step operation. First, apply without the module, only creating roles you need to use later. Then, you can safely add the module back and use the roles since they will have already been created. You can also use data sources instead of resources, as the values will be known during the plan. Also, you can split this into two workspaces, the first workspaces creating the roles and the second workspace using the roles. I know that none of these suggestions are as convenient as using a single Terraform workspace, but they would at least unblock you.

I could perhaps think of a convoluted way to get this to work, despite the limitations of Terraform, such as delaying the initialization of the client until it's absolutely needed, but it wouldn't work for situations where you already had existing resources or imported resources. I'm not sure we want to go down that path, though.

Hope this helps,
Scott

@spanhotra
Copy link
Author

Thank you @sfc-gh-swinkler for your response.
I will go ahead with your suggestion and create 2 step process for this.

May be this could be a feature request, a similar tool called Pulumi does support Dynamic Providers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Used to mark issues with provider's incorrect behavior
Projects
None yet
Development

No branches or pull requests

2 participants