backend/s3: add ec2_metadata_service_endpoint argument

pull/33765/head
Jared Baker 3 years ago
parent 1003032508
commit c1a2d94efd
No known key found for this signature in database

@ -30,6 +30,7 @@ ENHANCEMENTS:
* `shared_config_files` and `shared_credentials_files` arguments for specifying credential and configuration files as part of the backend configuration. ([#30493](https://github.com/hashicorp/terraform/issues/30493))
* Internally the backend now uses AWS SDK for Go v2, which should address various other missing behaviors that are handled by the SDK rather than by Terraform itself. ([#30443](https://github.com/hashicorp/terraform/issues/30443))
* `custom_ca_bundle` argument and support for the corresponding AWS environment variable, `AWS_CA_BUNDLE`, for providing custom root and intermediate certificates. ([#33689](https://github.com/hashicorp/terraform/issues/33689))
* `ec2_metadata_service_endpoint` and `ec2_metadata_service_endpoint_mode` arguments and support for the corresponding AWS environment variables, `AWS_EC2_METADATA_SERVICE_ENDPOINT` and `AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE` for setting the EC2 metadata service (IMDS) endpoint. The environment variable `AWS_METADATA_URL` is also supported for compatibility with the AWS provider, but is deprecated. ([#30444](https://github.com/hashicorp/terraform/issues/30444))
* backend/cos: Support custom HTTP(S) endpoint and root domain for the API client. [#33656]
BUG FIXES:

@ -72,6 +72,16 @@ func (b *Backend) ConfigSchema() *configschema.Block {
Description: "A custom endpoint for the DynamoDB API",
Deprecated: true,
},
"ec2_metadata_service_endpoint": {
Type: cty.String,
Optional: true,
Description: "Address of the EC2 metadata service (IMDS) endpoint to use.",
},
"ec2_metadata_service_endpoint_mode": {
Type: cty.String,
Optional: true,
Description: "Mode to use in communicating with the metadata service.",
},
"endpoint": {
Type: cty.String,
Optional: true,
@ -568,6 +578,7 @@ func (b *Backend) Configure(obj cty.Value) tfdiags.Diagnostics {
"AWS_IAM_ENDPOINT": "AWS_ENDPOINT_URL_IAM",
"AWS_S3_ENDPOINT": "AWS_ENDPOINT_URL_S3",
"AWS_STS_ENDPOINT": "AWS_ENDPOINT_URL_STS",
"AWS_METADATA_URL": "AWS_EC2_METADATA_SERVICE_ENDPOINT",
} {
if val := os.Getenv(envvar); val != "" {
diags = diags.Append(deprecatedEnvVarDiag(envvar, replacement))
@ -607,6 +618,21 @@ func (b *Backend) Configure(obj cty.Value) tfdiags.Diagnostics {
}
}
if v, ok := retrieveArgument(&diags,
newAttributeRetriever(obj, cty.GetAttrPath("ec2_metadata_service_endpoint")),
newEnvvarRetriever("AWS_EC2_METADATA_SERVICE_ENDPOINT"),
newEnvvarRetriever("AWS_METADATA_URL"),
); ok {
cfg.EC2MetadataServiceEndpoint = v
}
if v, ok := retrieveArgument(&diags,
newAttributeRetriever(obj, cty.GetAttrPath("ec2_metadata_service_endpoint_mode")),
newEnvvarRetriever("AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE"),
); ok {
cfg.EC2MetadataServiceEndpointMode = v
}
if val, ok := stringAttrOk(obj, "shared_credentials_file"); ok {
cfg.SharedCredentialsFiles = []string{
val,

@ -516,6 +516,82 @@ func TestBackendConfig_S3Endpoint(t *testing.T) {
}
}
func TestBackendConfig_EC2MetadataEndpoint(t *testing.T) {
testACC(t)
cases := map[string]struct {
config map[string]any
vars map[string]string
expectedEndpoint string
expectedDiags tfdiags.Diagnostics
}{
"none": {
expectedEndpoint: "",
},
"config": {
config: map[string]any{
"ec2_metadata_service_endpoint": "ec2.test",
},
expectedEndpoint: "ec2.test",
},
"envvar": {
vars: map[string]string{
"AWS_EC2_METADATA_SERVICE_ENDPOINT": "ec2.test",
},
expectedEndpoint: "ec2.test",
},
"deprecated envvar": {
vars: map[string]string{
"AWS_METADATA_URL": "ec2.test",
},
expectedEndpoint: "ec2.test",
expectedDiags: tfdiags.Diagnostics{
deprecatedEnvVarDiag("AWS_METADATA_URL", "AWS_EC2_METADATA_SERVICE_ENDPOINT"),
},
},
}
for name, tc := range cases {
t.Run(name, func(t *testing.T) {
config := map[string]interface{}{
"region": "us-west-1",
"bucket": "tf-test",
"key": "state",
}
if tc.vars != nil {
for k, v := range tc.vars {
os.Setenv(k, v)
}
t.Cleanup(func() {
for k := range tc.vars {
os.Unsetenv(k)
}
})
}
if tc.config != nil {
for k, v := range tc.config {
config[k] = v
}
}
_, diags := testBackendConfigDiags(t, New(), backend.TestWrapConfig(config))
// raw, diags := testBackendConfigDiags(t, New(), backend.TestWrapConfig(config))
// b := raw.(*Backend)
if diff := cmp.Diff(diags, tc.expectedDiags, cmp.Comparer(diagnosticComparer)); diff != "" {
t.Errorf("unexpected diagnostics difference: %s", diff)
}
if !diags.HasErrors() {
// TODO: Convert to AWS SDK v2 equivalent
// checkClientEndpoint(t, b.s3Client.Config, tc.expectedEndpoint)
}
})
}
}
func TestBackendConfig_AssumeRole(t *testing.T) {
testACC(t)

@ -155,6 +155,8 @@ The following configuration is optional:
* `access_key` - (Optional) AWS access key. If configured, must also configure `secret_key`. This can also be sourced from the `AWS_ACCESS_KEY_ID` environment variable, AWS shared credentials file (e.g. `~/.aws/credentials`), or AWS shared configuration file (e.g. `~/.aws/config`).
* `custom_ca_bundle` - (Optional) File containing custom root and intermediate certificates. Can also be set using the `AWS_CA_BUNDLE` environment variable. Setting ca_bundle in the shared config file is not supported.
* `secret_key` - (Optional) AWS access key. If configured, must also configure `access_key`. This can also be sourced from the `AWS_SECRET_ACCESS_KEY` environment variable, AWS shared credentials file (e.g. `~/.aws/credentials`), or AWS shared configuration file (e.g. `~/.aws/config`).
* `ec2_metadata_service_endpoint` - (Optional) Address of the EC2 metadata service (IMDS) endpoint to use. Can also be set with the `AWS_EC2_METADATA_SERVICE_ENDPOINT` environment variable.
* `ec2_metadata_service_endpoint_mode` - (Optional) Mode to use in communicating with the metadata service. Valid values are `IPv4` and `IPv6`. Can also be set with the `AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE` environment variable.
* `iam_endpoint` - (Optional, **Deprecated**) Custom endpoint for the AWS Identity and Access Management (IAM) API.
Use `endpoints.iam` instead.
* `max_retries` - (Optional) The maximum number of times an AWS API request is retried on retryable failure. Defaults to 5.

Loading…
Cancel
Save