From 8462c5f3e5efc95593e3fd59acf03f7bd92391b3 Mon Sep 17 00:00:00 2001 From: "guimin.hgm" Date: Mon, 3 Mar 2025 17:18:59 +0800 Subject: [PATCH] backend/oss: Supports more standard environment variables to keep same with provider setting --- .../v1.12/ENHANCEMENTS-20250303-171838.yaml | 5 ++ internal/backend/remote-state/oss/backend.go | 70 ++++++++++--------- website/docs/language/backend/oss.mdx | 32 ++++----- 3 files changed, 59 insertions(+), 48 deletions(-) create mode 100644 .changes/v1.12/ENHANCEMENTS-20250303-171838.yaml diff --git a/.changes/v1.12/ENHANCEMENTS-20250303-171838.yaml b/.changes/v1.12/ENHANCEMENTS-20250303-171838.yaml new file mode 100644 index 000000000000..2669acf1d594 --- /dev/null +++ b/.changes/v1.12/ENHANCEMENTS-20250303-171838.yaml @@ -0,0 +1,5 @@ +kind: ENHANCEMENTS +body: 'backend/oss: Supports more standard environment variables to keep same with provider setting' +time: 2025-03-03T17:18:38.679213+08:00 +custom: + Issue: "36581" diff --git a/internal/backend/remote-state/oss/backend.go b/internal/backend/remote-state/oss/backend.go index 6819f84bae60..2750b98c6731 100644 --- a/internal/backend/remote-state/oss/backend.go +++ b/internal/backend/remote-state/oss/backend.go @@ -50,13 +50,13 @@ func deprecatedAssumeRoleSchema() *schema.Schema { Type: schema.TypeString, Required: true, Description: "The ARN of a RAM role to assume prior to making API calls.", - DefaultFunc: schema.EnvDefaultFunc("ALICLOUD_ASSUME_ROLE_ARN", ""), + DefaultFunc: schema.MultiEnvDefaultFunc([]string{"ALICLOUD_ASSUME_ROLE_ARN", "ALIBABA_CLOUD_ROLE_ARN"}, ""), }, "session_name": { Type: schema.TypeString, Optional: true, Description: "The session name to use when assuming the role.", - DefaultFunc: schema.EnvDefaultFunc("ALICLOUD_ASSUME_ROLE_SESSION_NAME", ""), + DefaultFunc: schema.MultiEnvDefaultFunc([]string{"ALICLOUD_ASSUME_ROLE_SESSION_NAME", "ALIBABA_CLOUD_ROLE_SESSION_NAME"}, ""), }, "policy": { Type: schema.TypeString, @@ -95,27 +95,27 @@ func New() backend.Backend { Type: schema.TypeString, Optional: true, Description: "Alibaba Cloud Access Key ID", - DefaultFunc: schema.EnvDefaultFunc("ALICLOUD_ACCESS_KEY", os.Getenv("ALICLOUD_ACCESS_KEY_ID")), + DefaultFunc: schema.MultiEnvDefaultFunc([]string{"ALICLOUD_ACCESS_KEY", "ALIBABA_CLOUD_ACCESS_KEY_ID", "ALICLOUD_ACCESS_KEY_ID"}, ""), }, "secret_key": { Type: schema.TypeString, Optional: true, Description: "Alibaba Cloud Access Secret Key", - DefaultFunc: schema.EnvDefaultFunc("ALICLOUD_SECRET_KEY", os.Getenv("ALICLOUD_ACCESS_KEY_SECRET")), + DefaultFunc: schema.MultiEnvDefaultFunc([]string{"ALICLOUD_SECRET_KEY", "ALIBABA_CLOUD_ACCESS_KEY_SECRET", "ALICLOUD_ACCESS_KEY_SECRET"}, ""), }, "security_token": { Type: schema.TypeString, Optional: true, Description: "Alibaba Cloud Security Token", - DefaultFunc: schema.EnvDefaultFunc("ALICLOUD_SECURITY_TOKEN", ""), + DefaultFunc: schema.MultiEnvDefaultFunc([]string{"ALICLOUD_SECURITY_TOKEN", "ALIBABA_CLOUD_SECURITY_TOKEN"}, ""), }, "ecs_role_name": { Type: schema.TypeString, Optional: true, - DefaultFunc: schema.EnvDefaultFunc("ALICLOUD_ECS_ROLE_NAME", os.Getenv("ALICLOUD_ECS_ROLE_NAME")), + DefaultFunc: schema.MultiEnvDefaultFunc([]string{"ALICLOUD_ECS_ROLE_NAME", "ALIBABA_CLOUD_ECS_METADATA"}, ""), Description: "The RAM Role Name attached on a ECS instance for API operations. You can retrieve this from the 'Access Control' section of the Alibaba Cloud console.", }, @@ -123,25 +123,25 @@ func New() backend.Backend { Type: schema.TypeString, Optional: true, Description: "The region of the OSS bucket.", - DefaultFunc: schema.EnvDefaultFunc("ALICLOUD_REGION", os.Getenv("ALICLOUD_DEFAULT_REGION")), + DefaultFunc: schema.MultiEnvDefaultFunc([]string{"ALICLOUD_REGION", "ALIBABA_CLOUD_REGION", "ALICLOUD_DEFAULT_REGION"}, ""), }, "sts_endpoint": { Type: schema.TypeString, Optional: true, Description: "A custom endpoint for the STS API", - DefaultFunc: schema.EnvDefaultFunc("ALICLOUD_STS_ENDPOINT", ""), + DefaultFunc: schema.MultiEnvDefaultFunc([]string{"ALICLOUD_STS_ENDPOINT", "ALIBABA_CLOUD_STS_ENDPOINT"}, ""), }, "tablestore_endpoint": { Type: schema.TypeString, Optional: true, Description: "A custom endpoint for the TableStore API", - DefaultFunc: schema.EnvDefaultFunc("ALICLOUD_TABLESTORE_ENDPOINT", ""), + DefaultFunc: schema.MultiEnvDefaultFunc([]string{"ALICLOUD_TABLESTORE_ENDPOINT", "ALIBABA_CLOUD_TABLESTORE_ENDPOINT"}, ""), }, "endpoint": { Type: schema.TypeString, Optional: true, Description: "A custom endpoint for the OSS API", - DefaultFunc: schema.EnvDefaultFunc("ALICLOUD_OSS_ENDPOINT", os.Getenv("OSS_ENDPOINT")), + DefaultFunc: schema.MultiEnvDefaultFunc([]string{"ALICLOUD_OSS_ENDPOINT", "ALIBABA_CLOUD_OSS_ENDPOINT", "OSS_ENDPOINT"}, ""), }, "bucket": { @@ -217,27 +217,27 @@ func New() backend.Backend { "shared_credentials_file": { Type: schema.TypeString, Optional: true, - DefaultFunc: schema.EnvDefaultFunc("ALICLOUD_SHARED_CREDENTIALS_FILE", ""), + DefaultFunc: schema.MultiEnvDefaultFunc([]string{"ALICLOUD_SHARED_CREDENTIALS_FILE", "ALIBABA_CLOUD_CREDENTIALS_FILE"}, ""), Description: "This is the path to the shared credentials file. If this is not set and a profile is specified, `~/.aliyun/config.json` will be used.", }, "profile": { Type: schema.TypeString, Optional: true, Description: "This is the Alibaba Cloud profile name as set in the shared credentials file. It can also be sourced from the `ALICLOUD_PROFILE` environment variable.", - DefaultFunc: schema.EnvDefaultFunc("ALICLOUD_PROFILE", ""), + DefaultFunc: schema.MultiEnvDefaultFunc([]string{"ALICLOUD_PROFILE", "ALIBABA_CLOUD_PROFILE"}, ""), }, "assume_role": deprecatedAssumeRoleSchema(), "assume_role_role_arn": { Type: schema.TypeString, Optional: true, Description: "The ARN of a RAM role to assume prior to making API calls.", - DefaultFunc: schema.EnvDefaultFunc("ALICLOUD_ASSUME_ROLE_ARN", ""), + DefaultFunc: schema.MultiEnvDefaultFunc([]string{"ALICLOUD_ASSUME_ROLE_ARN", "ALIBABA_CLOUD_ROLE_ARN"}, ""), }, "assume_role_session_name": { Type: schema.TypeString, Optional: true, Description: "The session name to use when assuming the role.", - DefaultFunc: schema.EnvDefaultFunc("ALICLOUD_ASSUME_ROLE_SESSION_NAME", ""), + DefaultFunc: schema.MultiEnvDefaultFunc([]string{"ALICLOUD_ASSUME_ROLE_SESSION_NAME", "ALIBABA_CLOUD_ROLE_SESSION_NAME"}, ""), }, "assume_role_policy": { Type: schema.TypeString, @@ -301,24 +301,26 @@ func (b *Backend) configure(ctx context.Context) error { b.serverSideEncryption = d.Get("encrypt").(bool) b.acl = d.Get("acl").(string) - var getBackendConfig = func(str string, key string) string { - if str == "" { - value, err := getConfigFromProfile(d, key) - if err == nil && value != nil { - str = value.(string) + var getBackendConfig = func(schemaKey string, profileKey string) string { + if schemaKey != "" { + if v, ok := d.GetOk(schemaKey); ok && v != nil && v.(string) != "" { + return v.(string) } } - return str + if v, err := getConfigFromProfile(d, profileKey); err == nil && v != nil { + return v.(string) + } + return "" } - accessKey := getBackendConfig(d.Get("access_key").(string), "access_key_id") - secretKey := getBackendConfig(d.Get("secret_key").(string), "access_key_secret") - securityToken := getBackendConfig(d.Get("security_token").(string), "sts_token") - region := getBackendConfig(d.Get("region").(string), "region_id") + accessKey := getBackendConfig("access_key", "access_key_id") + secretKey := getBackendConfig("secret_key", "access_key_secret") + region := getBackendConfig("region", "region_id") + securityToken := getBackendConfig("security_token", "sts_token") stsEndpoint := d.Get("sts_endpoint").(string) endpoint := d.Get("endpoint").(string) - schma := "https" + protocol := "https" roleArn := getBackendConfig("", "ram_role_arn") sessionName := getBackendConfig("", "ram_session_name") @@ -370,7 +372,7 @@ func (b *Backend) configure(ctx context.Context) error { } if accessKey == "" { - ecsRoleName := getBackendConfig(d.Get("ecs_role_name").(string), "ram_role_name") + ecsRoleName := getBackendConfig("ecs_role_name", "ram_role_name") subAccessKeyId, subAccessKeySecret, subSecurityToken, err := getAuthCredentialByEcsRoleName(ecsRoleName) if err != nil { return err @@ -403,7 +405,7 @@ func (b *Backend) configure(ctx context.Context) error { } } if !strings.HasPrefix(endpoint, "http") { - endpoint = fmt.Sprintf("%s://%s", schma, endpoint) + endpoint = fmt.Sprintf("%s://%s", protocol, endpoint) } log.Printf("[DEBUG] Instantiate OSS client using endpoint: %#v", endpoint) var options []oss.ClientOption @@ -423,7 +425,7 @@ func (b *Backend) configure(ctx context.Context) error { otsInstanceName := d.Get("tablestore_instance_name").(string) if otsEndpoint != "" { if !strings.HasPrefix(otsEndpoint, "http") { - otsEndpoint = fmt.Sprintf("%s://%s", schma, otsEndpoint) + otsEndpoint = fmt.Sprintf("%s://%s", protocol, otsEndpoint) } b.otsEndpoint = otsEndpoint if otsInstanceName == "" { @@ -563,9 +565,13 @@ func getConfigFromProfile(d *schema.ResourceData, ProfileKey string) (interface{ } current := d.Get("profile").(string) // Set CredsFilename, expanding home directory - profilePath, err := homedir.Expand(d.Get("shared_credentials_file").(string)) - if err != nil { - return nil, err + var profilePath string + if v, ok := d.GetOk("shared_credentials_file"); ok { + path, err := homedir.Expand(v.(string)) + if err != nil { + return nil, err + } + profilePath = path } if profilePath == "" { profilePath = fmt.Sprintf("%s/.aliyun/config.json", os.Getenv("HOME")) @@ -574,7 +580,7 @@ func getConfigFromProfile(d *schema.ResourceData, ProfileKey string) (interface{ } } providerConfig = make(map[string]interface{}) - _, err = os.Stat(profilePath) + _, err := os.Stat(profilePath) if !os.IsNotExist(err) { data, err := ioutil.ReadFile(profilePath) if err != nil { diff --git a/website/docs/language/backend/oss.mdx b/website/docs/language/backend/oss.mdx index 822b2f0d44c9..94740e9d7ea5 100644 --- a/website/docs/language/backend/oss.mdx +++ b/website/docs/language/backend/oss.mdx @@ -75,17 +75,17 @@ data "terraform_remote_state" "network" { The following configuration options or environment variables are supported: -* `access_key` - (Optional) Alibaba Cloud access key. It supports environment variables `ALICLOUD_ACCESS_KEY` and `ALICLOUD_ACCESS_KEY_ID`. +* `access_key` - (Optional) Alibaba Cloud access key. It supports environment variables `ALICLOUD_ACCESS_KEY` and `ALIBABA_CLOUD_ACCESS_KEY_ID`(Recommended). -* `secret_key` - (Optional) Alibaba Cloud secret access key. It supports environment variables `ALICLOUD_SECRET_KEY` and `ALICLOUD_ACCESS_KEY_SECRET`. +* `secret_key` - (Optional) Alibaba Cloud secret access key. It supports environment variables `ALICLOUD_SECRET_KEY` and `ALIBABA_CLOUD_ACCESS_KEY_SECRET`(Recommended). -* `security_token` - (Optional) STS access token. It supports environment variable `ALICLOUD_SECURITY_TOKEN`. +* `security_token` - (Optional) STS access token. It supports environment variable `ALICLOUD_SECURITY_TOKEN` and `ALIBABA_CLOUD_SECURITY_TOKEN`(Recommended). -* `ecs_role_name` - (Optional, Available in 0.12.14+) The RAM Role Name attached on a ECS instance for API operations. You can retrieve this from the 'Access Control' section of the Alibaba Cloud console. +* `ecs_role_name` - (Optional) The RAM Role Name attached on a ECS instance for API operations. You can retrieve this from the 'Access Control' section of the Alibaba Cloud console. -* `region` - (Optional) The region of the OSS bucket. It supports environment variables `ALICLOUD_REGION` and `ALICLOUD_DEFAULT_REGION`. +* `region` - (Optional) The region of the OSS bucket. It supports environment variables `ALICLOUD_REGION` and `ALIBABA_CLOUD_REGION`(Recommended). -* `endpoint` - (Optional) A custom endpoint for the OSS API. It supports environment variables `ALICLOUD_OSS_ENDPOINT` and `OSS_ENDPOINT`. +* `endpoint` - (Optional) A custom endpoint for the OSS API. It supports environment variables `ALICLOUD_OSS_ENDPOINT` and `ALIBABA_CLOUD_OSS_ENDPOINT`(Recommended). * `bucket` - (Required) The name of the OSS bucket. @@ -93,14 +93,14 @@ The following configuration options or environment variables are supported: * `key` - (Optional) The name of the state file. Defaults to `terraform.tfstate`. -* `tablestore_endpoint` / `ALICLOUD_TABLESTORE_ENDPOINT` - (Optional) A custom endpoint for the TableStore API. +* `tablestore_endpoint` - (Optional) A custom endpoint for the TableStore API. It supports environment variables `ALICLOUD_TABLESTORE_ENDPOINT` and `ALIBABA_CLOUD_TABLESTORE_ENDPOINT`(Recommended). * `tablestore_instance_name` - (Optional) Specifies the name of an instance that `TableStore` belongs to. By default, Terraform parses the name from `tablestore_endpoint`. You should set the access URL explicitly when the `tablestore` endpoint is a VPC access URL. * `tablestore_table` - (Optional) A TableStore table for state locking and consistency. The table must have a primary key named `LockID` of type `String`. -* `sts_endpoint` - (Optional, Available in 1.0.11+) Custom endpoint for the AliCloud Security Token Service (STS) API. It supports environment variable `ALICLOUD_STS_ENDPOINT`. +* `sts_endpoint` - (Optional) Custom endpoint for the AliCloud Security Token Service (STS) API. It supports environment variable `ALICLOUD_STS_ENDPOINT` and `ALIBABA_CLOUD_STS_ENDPOINT`(Recommended). * `encrypt` - (Optional) Whether to enable server side encryption of the state file. If it is true, OSS will use 'AES256' encryption algorithm to encrypt state file. @@ -109,24 +109,24 @@ The following configuration options or environment variables are supported: ACL](https://www.alibabacloud.com/help/doc-detail/52284.htm) to be applied to the state file. -* `shared_credentials_file` - (Optional, Available in 0.12.8+) This is the path to the shared credentials file. It can also be sourced from the `ALICLOUD_SHARED_CREDENTIALS_FILE` environment variable. If this is not set and a profile is specified, `~/.aliyun/config.json` will be used. +* `shared_credentials_file` - (Optional) This is the path to the shared credentials file. It can also be sourced from the `ALICLOUD_SHARED_CREDENTIALS_FILE` or `ALIBABA_CLOUD_CREDENTIALS_FILE`(Recommended) environment variable. If this is not set and a profile is specified, `~/.aliyun/config.json` will be used. -* `profile` - (Optional, Available in 0.12.8+) This is the Alibaba Cloud profile name as set in the shared credentials file. It can also be sourced from the `ALICLOUD_PROFILE` environment variable. +* `profile` - (Optional) This is the Alibaba Cloud profile name as set in the shared credentials file. It supports environment variable `ALICLOUD_PROFILE` and `ALIBABA_CLOUD_PROFILE`(Recommended). -* `assume_role_role_arn` - (Optional, Available in 1.1.0+) The ARN of the role to assume. If ARN is set to an empty string, it does not perform role switching. It supports the environment variable `ALICLOUD_ASSUME_ROLE_ARN`. +* `assume_role_role_arn` - (Optional) The ARN of the role to assume. If ARN is set to an empty string, it does not perform role switching. It supports the environment variable `ALICLOUD_ASSUME_ROLE_ARN` and `ALIBABA_CLOUD_ROLE_ARN`(Recommended). Terraform executes configuration on account with provided credentials. -* `assume_role_policy` - (Optional, Available in 1.1.0+) A more restrictive policy to apply to the temporary credentials. This gives you a way to further restrict the permissions for the resulting temporary security credentials. You cannot use this policy to grant permissions that exceed those of the role that is being assumed. +* `assume_role_policy` - (Optional) A more restrictive policy to apply to the temporary credentials. This gives you a way to further restrict the permissions for the resulting temporary security credentials. You cannot use this policy to grant permissions that exceed those of the role that is being assumed. -* `assume_role_session_name` - (Optional, Available in 1.1.0+) The session name to use when assuming the role. If omitted, 'terraform' is passed to the AssumeRole call as session name. It supports environment variable `ALICLOUD_ASSUME_ROLE_SESSION_NAME`. +* `assume_role_session_name` - (Optional) The session name to use when assuming the role. If omitted, 'terraform' is passed to the AssumeRole call as session name. It supports environment variable `ALICLOUD_ASSUME_ROLE_SESSION_NAME` and `ALIBABA_CLOUD_ROLE_SESSION_NAME`(Recommended). -* `assume_role_session_expiration` - (Optional, Available in 1.1.0+) The time after which the established session for assuming role expires. Valid value range: \[900-3600] seconds. Default to 3600 (in this case Alibaba Cloud uses its own default value). It supports environment variable `ALICLOUD_ASSUME_ROLE_SESSION_EXPIRATION`. +* `assume_role_session_expiration` - (Optional) The time after which the established session for assuming role expires. Valid value range: \[900-3600] seconds. Default to 3600 (in this case Alibaba Cloud uses its own default value). It supports environment variable `ALICLOUD_ASSUME_ROLE_SESSION_EXPIRATION`. -* `assume_role` - (**Deprecated as of 1.1.0+**, Available in 0.12.6+) If provided with a role ARN, will attempt to assume this role using the supplied credentials. It will be ignored when `assume_role_role_arn` is specified. +* `assume_role` - (**Deprecated as of 1.1.0+**) If provided with a role ARN, will attempt to assume this role using the supplied credentials. It will be ignored when `assume_role_role_arn` is specified. **Deprecated in favor of flattening assume_role_\* options** - * `role_arn` - (Required) The ARN of the role to assume. If ARN is set to an empty string, it does not perform role switching. It supports the environment variable `ALICLOUD_ASSUME_ROLE_ARN`. + * `role_arn` - (Required) The ARN of the role to assume. If ARN is set to an empty string, it does not perform role switching. It supports the environment variable `ALICLOUD_ASSUME_ROLE_ARN` and `ALIBABA_CLOUD_ROLE_ARN`(Recommended). Terraform executes configuration on account with provided credentials. * `policy` - (Optional) A more restrictive policy to apply to the temporary credentials. This gives you a way to further restrict the permissions for the resulting temporary security credentials. You cannot use this policy to grant permissions that exceed those of the role that is being assumed.