diff --git a/.changelog/2892.txt b/.changelog/2892.txt new file mode 100644 index 0000000000..ef24bef748 --- /dev/null +++ b/.changelog/2892.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +provider: add new auth for `cam_role_name` +``` \ No newline at end of file diff --git a/tencentcloud/provider.go b/tencentcloud/provider.go index 154f8eef77..334799ad73 100644 --- a/tencentcloud/provider.go +++ b/tencentcloud/provider.go @@ -131,6 +131,7 @@ const ( PROVIDER_ASSUME_ROLE_ARN = "TENCENTCLOUD_ASSUME_ROLE_ARN" PROVIDER_ASSUME_ROLE_SESSION_NAME = "TENCENTCLOUD_ASSUME_ROLE_SESSION_NAME" PROVIDER_ASSUME_ROLE_SESSION_DURATION = "TENCENTCLOUD_ASSUME_ROLE_SESSION_DURATION" + PROVIDER_ASSUME_ROLE_EXTERNAL_ID = "TENCENTCLOUD_ASSUME_ROLE_EXTERNAL_ID" PROVIDER_ASSUME_ROLE_SAML_ASSERTION = "TENCENTCLOUD_ASSUME_ROLE_SAML_ASSERTION" PROVIDER_ASSUME_ROLE_PRINCIPAL_ARN = "TENCENTCLOUD_ASSUME_ROLE_PRINCIPAL_ARN" PROVIDER_ASSUME_ROLE_WEB_IDENTITY_TOKEN = "TENCENTCLOUD_ASSUME_ROLE_WEB_IDENTITY_TOKEN" @@ -249,6 +250,12 @@ func Provider() *schema.Provider { Optional: true, Description: "A more restrictive policy when making the AssumeRole call. Its content must not contains `principal` elements. Notice: more syntax references, please refer to: [policies syntax logic](https://intl.cloud.tencent.com/document/product/598/10603).", }, + "external_id": { + Type: schema.TypeString, + Optional: true, + DefaultFunc: schema.EnvDefaultFunc(PROVIDER_ASSUME_ROLE_EXTERNAL_ID, nil), + Description: "External role ID, which can be obtained by clicking the role name in the CAM console. It can contain 2-128 letters, digits, and symbols (=,.@:/-). Regex: [\\w+=,.@:/-]*. It can be sourced from the `TENCENTCLOUD_ASSUME_ROLE_EXTERNAL_ID`.", + }, }, }, }, @@ -2249,6 +2256,7 @@ func providerConfigure(d *schema.ResourceData) (interface{}, error) { assumeRoleSessionName string assumeRoleSessionDuration int assumeRolePolicy string + assumeRoleExternalId string ) // get assume role from credential @@ -2262,8 +2270,7 @@ func providerConfigure(d *schema.ResourceData) (interface{}, error) { if assumeRoleArn != "" && assumeRoleSessionName != "" { assumeRoleSessionDuration = 7200 - assumeRolePolicy = "" - _ = genClientWithSTS(&tcClient, assumeRoleArn, assumeRoleSessionName, assumeRoleSessionDuration, assumeRolePolicy) + _ = genClientWithSTS(&tcClient, assumeRoleArn, assumeRoleSessionName, assumeRoleSessionDuration, assumeRolePolicy, assumeRoleExternalId) } // get assume role from env @@ -2282,6 +2289,8 @@ func providerConfigure(d *schema.ResourceData) (interface{}, error) { assumeRoleSessionDuration = 7200 } + assumeRoleExternalId = os.Getenv(PROVIDER_ASSUME_ROLE_EXTERNAL_ID) + // get assume role with saml from env envSamlAssertion := os.Getenv(PROVIDER_ASSUME_ROLE_SAML_ASSERTION) envPrincipalArn := os.Getenv(PROVIDER_ASSUME_ROLE_PRINCIPAL_ARN) @@ -2290,7 +2299,7 @@ func providerConfigure(d *schema.ResourceData) (interface{}, error) { if envSamlAssertion == "" && envPrincipalArn == "" && envWebIdentityToken == "" { // use assume role - _ = genClientWithSTS(&tcClient, envRoleArn, envSessionName, assumeRoleSessionDuration, "") + _ = genClientWithSTS(&tcClient, envRoleArn, envSessionName, assumeRoleSessionDuration, "", assumeRoleExternalId) } else if envSamlAssertion != "" && envPrincipalArn != "" && envWebIdentityToken != "" { return nil, fmt.Errorf("can not set `TENCENTCLOUD_ASSUME_ROLE_SAML_ASSERTION`, `TENCENTCLOUD_ASSUME_ROLE_PRINCIPAL_ARN`, `TENCENTCLOUD_ASSUME_ROLE_WEB_IDENTITY_TOKEN` at the same time.\n") } else if envSamlAssertion != "" && envPrincipalArn != "" { @@ -2315,9 +2324,14 @@ func providerConfigure(d *schema.ResourceData) (interface{}, error) { assumeRoleSessionName = assumeRole["session_name"].(string) assumeRoleSessionDuration = assumeRole["session_duration"].(int) assumeRolePolicy = assumeRole["policy"].(string) + assumeRoleExternalId = assumeRole["external_id"].(string) - _ = genClientWithSTS(&tcClient, assumeRoleArn, assumeRoleSessionName, assumeRoleSessionDuration, assumeRolePolicy) - needSecret = true + _ = genClientWithSTS(&tcClient, assumeRoleArn, assumeRoleSessionName, assumeRoleSessionDuration, assumeRolePolicy, assumeRoleExternalId) + if camRoleName != "" { + needSecret = false + } else { + needSecret = true + } } } @@ -2393,7 +2407,7 @@ func genClientWithCAM(tcClient *TencentCloudClient, roleName string) error { return nil } -func genClientWithSTS(tcClient *TencentCloudClient, assumeRoleArn, assumeRoleSessionName string, assumeRoleSessionDuration int, assumeRolePolicy string) error { +func genClientWithSTS(tcClient *TencentCloudClient, assumeRoleArn, assumeRoleSessionName string, assumeRoleSessionDuration int, assumeRolePolicy string, assumeRoleExternalId string) error { // applying STS credentials request := sdksts.NewAssumeRoleRequest() request.RoleArn = helper.String(assumeRoleArn) @@ -2403,6 +2417,10 @@ func genClientWithSTS(tcClient *TencentCloudClient, assumeRoleArn, assumeRoleSes request.Policy = helper.String(url.QueryEscape(assumeRolePolicy)) } + if assumeRoleExternalId != "" { + request.ExternalId = helper.String(assumeRoleExternalId) + } + ratelimit.Check(request.GetAction()) response, err := tcClient.apiV3Conn.UseStsClient().AssumeRole(request) if err != nil { diff --git a/website/docs/index.html.markdown b/website/docs/index.html.markdown index 249b718672..be98dff0f1 100644 --- a/website/docs/index.html.markdown +++ b/website/docs/index.html.markdown @@ -141,7 +141,7 @@ $ terraform plan ### Assume role -If provided with an assume role, Terraform will attempt to assume this role using the supplied credentials. Assume role can be provided by adding an `role_arn`, `session_name`, `session_duration` and `policy`(optional) in-line in the tencentcloud provider block: +If provided with an assume role, Terraform will attempt to assume this role using the supplied credentials. Assume role can be provided by adding an `role_arn`, `session_name`, `session_duration`, `policy`(optional) and `external_id`(optional) in-line in the tencentcloud provider block: Usage: @@ -160,7 +160,7 @@ provider "tencentcloud" { } ``` -The `role_arn`, `session_name`, `session_duration` can also provided via `TENCENTCLOUD_ASSUME_ROLE_ARN`, `TENCENTCLOUD_ASSUME_ROLE_SESSION_NAME` and `TENCENTCLOUD_ASSUME_ROLE_SESSION_DURATION` environment variables. +The `role_arn`, `session_name`, `session_duration` and `external_id` can also provided via `TENCENTCLOUD_ASSUME_ROLE_ARN`, `TENCENTCLOUD_ASSUME_ROLE_SESSION_NAME`, `TENCENTCLOUD_ASSUME_ROLE_SESSION_DURATION` and `TENCENTCLOUD_ASSUME_ROLE_EXTERNAL_ID` environment variables. Usage: @@ -254,7 +254,7 @@ provider "tencentcloud" { ### Cam role name -If provided with a Cam role name, Terraform will just access the metadata URL: http://metadata.tencentyun.com/latest/meta-data/cam/security-credentials/ to obtain the STS credential. The CVM Instance Role also can be set using the TENCENTCLOUD_CAM_ROLE_NAME environment variables. +If provided with a Cam role name, Terraform will just access the metadata URL: `http://metadata.tencentyun.com/latest/meta-data/cam/security-credentials/` to obtain the STS credential. The CVM Instance Role also can be set using the `TENCENTCLOUD_CAM_ROLE_NAME` environment variables. -> **Note:** Cam-role-name is used to grant the role entity the permissions to access services and resources and perform operations in Tencent Cloud. You can associate the CAM role with a CVM instance to call other Tencent Cloud APIs from the instance using the periodically updated temporary Security Token Service (STS) key. @@ -268,6 +268,24 @@ provider "tencentcloud" { } ``` +It can also be authenticated together with method Assume role. Authentication process: Perform CAM authentication first, then proceed with Assume role authentication. + +Usage: + +```hcl +provider "tencentcloud" { + cam_role_name = "my-cam-role-name" + + assume_role { + role_arn = "my-role-arn" + session_name = "my-session-name" + policy = "my-role-policy" + session_duration = 3600 + external_id = "my-external-id" + } +} +``` + ### CDC cos usage You can set the cos domain by setting the environment variable `TENCENTCLOUD_COS_DOMAIN`, and configure the cdc scenario as follows: @@ -347,6 +365,7 @@ The nested `assume_role` block supports the following: * `session_name` - (Required) The session name to use when making the AssumeRole call. It can also be sourced from the `TENCENTCLOUD_ASSUME_ROLE_SESSION_NAME` environment variable. * `session_duration` - (Required) The duration of the session when making the AssumeRole call. Its value ranges from 0 to 43200(seconds), and default is 7200 seconds. It can also be sourced from the `TENCENTCLOUD_ASSUME_ROLE_SESSION_DURATION` environment variable. * `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 the passed policy to grant permissions that are in excess of those allowed by the access policy of the role that is being assumed. +* `external_id` - (Optional) External role ID, which can be obtained by clicking the role name in the CAM console. It can contain 2-128 letters, digits, and symbols (=,.@\:/-). Regex: [\\w+=,.@\:/-]*. It can be sourced from the `TENCENTCLOUD_ASSUME_ROLE_EXTERNAL_ID`. The nested `assume_role_with_saml` block supports the following: * `role_arn` - (Required) The ARN of the role to assume. It can also be sourced from the `TENCENTCLOUD_ASSUME_ROLE_ARN` environment variable.