terramate-io / terramate

Terramate CLI is an open-source Infrastructure as Code (IaC) Orchestration and Code Generation tool for Terraform, OpenTofu and Terragrunt.
https://terramate.io
Mozilla Public License 2.0
3.25k stars 91 forks source link

[FEATURE] Support block type for generated provider config #1868

Open CtrlAltDft opened 1 month ago

CtrlAltDft commented 1 month ago

Is your feature request related to a problem? Please describe. Terramate currently lacks support for block-typed configuration in generated providers, only supporting argument-based configuration. This limitation is problematic when working with providers like AWS and Helm, where block-typed configurations (e.g., assume_role in AWS, kubernetes in Helm) are necessary. The absence of block support forces users to work around the limitation or manually configure these providers, reducing the automation benefits of Terramate.

provider "helm" {
  kubernetes { // Not supported
    host                   = data.aws_eks_cluster.cluster.endpoint
    cluster_ca_certificate = base64decode(data.aws_eks_cluster.cluster.certificate_authority[0].data)
    token                  = data.aws_eks_cluster_auth.cluster.token
  }
}

provider "aws" {
  assume_role { // Not supported
    role_arn = ""
  }
}

Describe the solution you'd like I would like Terramate to support block-typed configuration for generated providers

Describe alternatives you've considered

Additional context

krystek17 commented 1 month ago

Hi @CtrlAltDft

I had that issue but I have managed to solve it by following the azure's example since a features {} block is required.

Inside providers.tm.hcl

generate_hcl "_providers.tf" {

 lets  { <same as in the example>}
  content {
    terraform {
      required_version = tm_try(global.terraform.version, "~> 1.8.0")
    }

    terraform {
      tm_dynamic "required_providers" {
        attributes = let.required_providers
      }
    }

    tm_dynamic "provider" {
      for_each   = let.providers
      labels     = [provider.key] 
      attributes = provider.value 

      content {
        tm_dynamic "assume_role" {
          condition = tm_try(global.assume_role.enabled, false)

          content {
            role_arn = global.assume_role.role_arn
          }
        }
      }
    }
  }
}

And the globals values

globals "terraform" "providers" "aws" {
  enabled = true
  source  = "hashicorp/aws"
  version = "~> 5.0"

  config = {
    region = "<some_region>"
  }
}

globals "assume_role" {
  enabled  = true
  role_arn = "arn:aws:iam::<account_id>:role/<role_name>"
}

The original example can be found here

I'm not sure if this is the most optimal solution but at least it allowed me to use the assume_role block

Krystek

i4ki commented 3 weeks ago

Hi @CtrlAltDft

As @krystek17 pointed out, you can customise the provider's generate block to also generate specific inner blocks based on a configuration condition. The annoying part is that you cannot just configure blocks in a generic way. We are looking into options to make that possible but HCL syntax is quite limited in this regard.