Skip to content

Introduction of write-only arguments in resources that takes private key as one of the argument #704

Description

@JakubSzuber

Terraform CLI and Provider Versions

Starting 1.11.X

Use Cases or Problem Statement

The tls_certificate data source stores all of its attributes in Terraform state, so, among other TLS public certs, are stored there, which is not a good idea from a security standpoint.

Proposal

Starting 1.11.X, Terraform introduces ephemeral resources that allow for handling temporary values: https://developer.hashicorp.com/terraform/language/resources/ephemeral

Introduction of an ephemeral resource tls_certificate would allow us to temporarily get the value of e.g. SHA1 fingerprint and then store it, e.g., as an AWS SSM parameter or secret in AWS Secret Manager - it would allow for full automation and security!

We already have ephemeral resource tls_private_key in terraform-provider-tls since I created #629, which is now closed thanks to @lonegunmanb and @stephybun

Here is my current Terraform code, which unfortunately exposed public certs in TF state (this is part of my AWS LB controller config):

data "tls_certificate" "oidc_thumbprint" {
  url = aws_eks_cluster.main.identity[0].oidc[0].issuer
}

resource "aws_iam_openid_connect_provider" "eks" {
  client_id_list  = ["sts.amazonaws.com"]
  thumbprint_list = [data.tls_certificate.oidc_thumbprint.certificates[0].sha1_fingerprint]
  url             = aws_eks_cluster.main.identity[0].oidc[0].issuer
}

resource "aws_iam_role" "lb_controller" {
  name = "iam-${replace(var.env_name, "-", "")}-role_lb_controller-global"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Effect = "Allow"
      Principal = {
        Federated = aws_iam_openid_connect_provider.eks.arn
      }
      Action = "sts:AssumeRoleWithWebIdentity"
      Condition = {
        StringEquals = {
          "${element(split("oidc-provider/", aws_iam_openid_connect_provider.eks.arn), 1)}:aud": "sts.amazonaws.com",
          "${element(split("oidc-provider/", aws_iam_openid_connect_provider.eks.arn), 1)}:sub": "system:serviceaccount:${local.lb_controller_service_account_namespace}:${local.lb_controller_service_account_name}"
        }
      }
    }]
  })
}

When a feature that is proposed in this issue is implemented, I will be able to create an SSM parameter based on this new ephemeral resource, and then in thumbprint_list argument of my aws_iam_openid_connect_provider resource, I will just specify the SHA1 fingerprint which will be pulled from aws_ssm_parameter data source -> so we end up with enhanced security as no public certs (nor any other attributes of tls_certificate) in TF state, with only a single exception - the SHA1 fingerprint which is fine as it's SHA1 is one-way hash.

I'm aware that public certs aren't very sensitive data, but especially when we use a private K8s cluster, we don't want to keep these values, and any other TLS cert-related info (expiration date, issuer info, etc.), in our Terraform state.

How much impact is this issue causing?

Medium

Additional Information

No response

Code of Conduct

  • I agree to follow this project's Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions