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

Schema validation fails when RequiredWith attributes are combined with DefaultFunc #1099

Open
adamrothman opened this issue Nov 10, 2022 · 2 comments
Labels
bug Something isn't working

Comments

@adamrothman
Copy link

adamrothman commented Nov 10, 2022

SDK version

v2.16.0

I know this isn't the latest version, but it's the version specified in the go.mod file of github.com/hashicorp/terraform-provider-vault v3.10.0 (latest) and the relevant pieces of code do not appear to have changed since this version.

Relevant provider source code

The Vault provider's auth_login_aws attribute has attributes aws_access_key_id and aws_secret_access_key and uses RequiredWith to assert that they must be set together. Schemata for these fields are defined in internal/provider/auth_aws.go:

// static credential fields
consts.FieldAWSAccessKeyID: {
    Type:        schema.TypeString,
    Optional:    true,
    Description: `The AWS access key ID.`,
    DefaultFunc: schema.EnvDefaultFunc("AWS_ACCESS_KEY_ID", nil),
},
consts.FieldAWSSecretAccessKey: {
    Type:         schema.TypeString,
    Optional:     true,
    Description:  `The AWS secret access key.`,
    DefaultFunc:  schema.EnvDefaultFunc("AWS_SECRET_ACCESS_KEY", nil),
    RequiredWith: []string{fmt.Sprintf("%s.0.%s", authField, consts.FieldAWSAccessKeyID)},
},

The validator in play is validateRequiredWithAttribute() in helper/schema/schema.go:

func validateRequiredWithAttribute(
    k string,
    schema *Schema,
    c *terraform.ResourceConfig) error {

    if len(schema.RequiredWith) == 0 {
        return nil
    }

    allKeys := removeDuplicates(append(schema.RequiredWith, k))
    sort.Strings(allKeys)

    for _, key := range allKeys {
        if _, ok := c.Get(key); !ok {
            return fmt.Errorf("%q: all of `%s` must be specified", k, strings.Join(allKeys, ","))
        }
    }

    return nil
}

(*ResourceConfig).Get() calls (*ResourceConfig).get() which I won't reproduce here.

Terraform Configuration Files

provider "vault" {
  address         = "http://my.vault.host:8200"
  skip_tls_verify = true

  auth_login_aws {
    role         = "my-role"
    header_value = local.aws_auth_header
  }
}

Debug Output

I've encrypted the output of TF_LOG=trace terraform validate with Hashicorp's PGP key 72D7468F and uploaded the result as a Gist here.

Expected Behavior

provider "vault" {
  address         = "http://my.vault.host:8200"
  skip_tls_verify = true

  auth_login_aws {
    role         = "my-role"
    header_value = local.aws_auth_header
  }
}

When the environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are set, the provider configuration above is valid and well-formed. Validation of the auth_login_aws attribute should succeed even though its aws_access_key_id and aws_secret_access_key attributes are not set.

As far as I can tell, this happens because validateRequiredWithAttribute() does not take the default values for these attributes as provided by their DefaultFuncs into account.

Actual Behavior

Validation of the auth_login_aws attribute fails:

╷
│ Error: Missing required argument
│
│   with provider["registry.terraform.io/hashicorp/vault"],
│   on providers.tf line 13, in provider "vault":
│   13:   auth_login_aws {
│
│ "auth_login_aws.0.aws_secret_access_key": all of `auth_login_aws.0.aws_access_key_id,auth_login_aws.0.aws_secret_access_key` must be specified
╵

Steps to Reproduce

  1. Create a Terraform environment that includes the Vault provider as configured above.
  2. Set values (doesn't matter what) for environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY.
  3. Run any Terraform command that validates the configuration, e.g. terraform validate, terraform plan, or terraform apply.
  4. Observe failure.

References

@andris-cakuls
Copy link

https://support.hashicorp.com/hc/en-us/articles/4547786359571-Reading-and-using-environment-variables-in-Terraform-runs

This page has a work around

Unfortunately, the above-mentioned article does not work as a workaround in this case because it ends up putting sensitive AWS credentials in the statefile that otherwise would not be there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants