Terraform 身份认证

更新时间:

阿里云 Terraform Provider 支持多种身份认证方式,其选择需综合考虑 Terraform 的运行环境与应用场景。

认证方式优先级

配置阿里云 Provider 时,通常只需选择一种身份认证方式。Terraform Provider 会按以下顺序寻找身份凭证,一旦匹配成功,即停止寻找:

  1. 静态配置:优先读取 provider 块中显式指定的 access_key、secret_key、security_token 或 ecs_role_name。

  2. 环境变量:若无静态配置,则读取系统环境变量(如 ALICLOUD_ACCESS_KEY、ALICLOUD_SECRET_KEY 等)。

  3. 共享配置文件

    1. 静态配置:从本地共享配置文件中读取指定 profile 的认证信息,如AK/SK、ram_role_arn、ram_role_name、sts_token等。

    2. 高级配置:若共享配置文件中无静态配置,但配置了 CloudSSO、OAuth、外部程序(External)或链式角色(ChainableRamRoleArn),则调用相应插件获取临时STS凭证。

  4. URL 凭证:若以上皆为空,则尝试从 credentials_uri 指定的地址拉取凭证。

安全性建议

为提高生产环境的安全性,推荐使用以下基于临时凭证的认证方式:

  • ECS 实例 RAM 角色

  • RAM 角色扮演(AssumeRole)

  • OIDC 身份提供商角色扮演

这些方式具有以下安全优势:

  • 避免在配置中硬编码或暴露长期有效的 AccessKey,从而降低密钥泄露风险。

  • 通过固定有效期限制权限的暴露窗口。

精细化授权支持

当需要根据应用、团队或项目等维度对资源访问权限进行精细化管控时,可使用 RAM 角色扮演和 OIDC 身份提供商角色扮演。通过为不同的 Terraform 工作负载绑定专属的角色及权限策略,以遵循最小权限原则。

Terraform 身份认证方式

阿里云 Terraform Provider 提供以下身份认证方式:

认证方式

使用说明

适应场景

静态配置

(access_key)

将 AccessKey (AK) 明文定义在配置文件中,或通过参数传入。

  • 开发环境测试验证;

  • CI/CD 资源管理流程。

环境变量

(ALIBABA_CLOUD_ACCESS_KEY)

从环境变量中读取 AK 信息。

  • 开发环境测试验证;

  • 独立的运行环境(如 ECS)。

ECS服务角色

(ecs_role_name)

从 ECS 实例的元数据(Metadata)中获取其绑定的 RAM 角色对应的访问凭证。

Terraform 运行在 ECS 实例中。

OIDC角色扮演(assume_role_with_oidc)

通过 OIDC 角色扮演换取访问凭证。

Terraform 运行在支持 OIDC 的 Kubernetes 集群中(如阿里云 ACK)。

角色扮演

(assume_role)

通过扮演 RAM 角色换取访问凭证。

  • 多账号资源管理;

  • CI/CD 资源管理流程。

URL凭证

(credentials_uri)

指定一个 URI 地址,通过访问该地址获取临时凭证。

从自定义的凭证服务(API 或文件)中获取凭证。

共享配置文件

(profile)

支持多种认证方式通过阿里云 CLI 配置到统一的文件中,通过指定 profile 的名称来获取访问凭证。目前支持的认证方式有:

  • AK

  • STSToken

  • ECSRamRole

  • CloudSSO

  • ChainableRamRoleArn

  • External

  • OAuth

  • 多账号,多地域资源管理。

  • 多环境资源管理。

静态配置

静态配置是指直接在 Terraform 配置文件的 provider 块中定义访问凭证。

参数

参数名称

说明

示例值

access_key

Access Key ID。

abcd*******

secret_key

Access Key Secret。

abcd*******

security_token(可选)

STS 临时访问凭证的 Security Token。

abcd*******

provider "alicloud" {
  access_key = "<Access Key ID>"
  secret_key = "<Access Key Secret>"
  # 如果使用 STS 凭证,需配置 security_token
  # security_token = "<STS Token>"
}

示例配置

为提高安全性,建议通过变量传入访问凭证,而非在配置文件中硬编码明文,且变量不设置默认值:

variable "access_key_id" {
  description = "The AccessKey ID for operating your infrastructure"
}
variable "access_key_secret" {
  description = "The AccessKey Secret for operating your infrastructure"
}
variable "security_token" {
  description = "The Security Token for operating your infrastructure"
}
provider "alicloud" {
  access_key = var.access_key_id
  secret_key = var.access_key_secret
  # 如果使用 STS 凭证,需配置 security_token
  # security_token = var.security_token
}

运行 terraform 命令时,可通过 -var 选项传入变量值:

$ terraform plan -var access_key_id="<Access Key ID>" -var access_key_secret="<Access Key Secret>" -var security_token="<STS Token>"

环境变量配置

将访问凭证保存在环境变量中。当配置文件中未静态配置凭证时,Terraform 会从指定的环境变量中读取凭证。

参数

参数名称

说明

示例值

ALICLOUD_ACCESS_KEY

Access Key ID。

abcd*******

ALICLOUD_SECRET_KEY

Access Key Secret。

abcd*******

ALICLOUD_SECURITY_TOKEN(可选)

STS 临时访问凭证的 Security Token。

abcd*******

示例配置

Linux/macOS
说明

使用 export 命令配置的临时环境变量仅对当前 Shell 会话有效。如需长期保留,可将 export 命令写入 Shell 的启动配置文件(如 .bash_profile 或 .zshrc)。

# AccessKey ID
$ export ALICLOUD_ACCESS_KEY="<AccessKey ID>"
# AccessKey Secret
$ export ALICLOUD_SECRET_KEY="<AccessKey Secret>"
# 如果使用 STS 凭证,需配置 security_token
$ export ALICLOUD_SECURITY_TOKEN="<STS Token>"
Windows
  1. 在桌面右键单击 此电脑,选择 属性 > 高级系统设置 > 环境变量

  2. 在 系统变量 或 用户变量 中,单击 新建,创建以下环境变量:ALICLOUD_ACCESS_KEYALICLOUD_SECRET_KEYALICLOUD_SECURITY_TOKEN(可选)。

设置环境变量后,provider 块中无需声明凭证,可仅声明地域等其他信息:

provider "alicloud" {
  region = "cn-hangzhou"
}

region 也支持通过环境变量 ALICLOUD_REGION 配置。如果未在 provider 块或环境变量中指定 region,将默认使用 cn-beijing

相比静态配置,使用环境变量更便捷,安全性更高。

ECS服务角色

当 Terraform 运行在 ECS 实例上时,可使用 ECS 服务角色进行身份认证。通过为 ECS 实例关联一个 RAM 角色,实例内部的应用程序(包括 Terraform)可以自动获取并刷新临时访问凭证。此方式无需配置 AccessKey,降低了密钥泄露风险,并可通过 RAM 角色实现精细化的权限控制。详情请参见实例RAM角色

参数

参数名称

说明

示例值

ecs_role_name

绑定到 ECS 实例的 RAM 角色名称。

terraform-ecs-role

示例配置

  1. 准备一台具有公网访问能力的 ECS 实例。

  2. 创建一个 RAM 角色,并将其绑定到该 ECS 实例。

  3. 在 provider 块中设置 ecs_role_name 参数,其值为该 RAM 角色的名称:

provider "alicloud" {
  ecs_role_name = "<绑定到 ECS 实例上的 RAM 角色名称>"
}

该参数也支持通过环境变量 ALICLOUD_ECS_ROLE_NAME 设置。

基于 ECS 服务角色的认证方式安全性高,建议在 ECS 实例中执行 Terraform 时使用此方式。

OIDC角色扮演

OIDC 角色扮演与角色扮演(AssumeRole)类似,都是通过获取 RAM 角色的临时凭证来访问阿里云资源。其区别在于,OIDC 角色扮演所扮演的身份由 OIDC 身份提供商(IdP)颁发。详情请参见管理OIDC身份提供商

参数

配置 OIDC 角色扮演时,所有相关参数均在 assume_role_with_oidc 块中设置:

参数名称

说明

示例值

oidc_provider_arn(必填)

身份提供商的 ARN,格式为 :acs:ram::<阿里云账号ID>:oidc-provider/<RAM Provider 角色名称>。可通过 RAM 控制台或 API 查看。该参数支持通过环境变量 ALIBABA_CLOUD_OIDC_PROVIDER_ARN 设置。

acs:ram::151192xxxxxx:oidc-provider/ackrole

oidc_token(可选)

由外部 IdP 签发的 OIDC 令牌(OIDC Token)。oidc_token 和 oidc_token_file 必须设置其一。该参数支持通过环境变量 ALIBABA_CLOUD_OIDC_TOKEN 设置。

eyJhbGciOiJSUzI1NiIsImtpZCI6IjEifQ.************

oidc_token_file(可选)

存放 OIDC 令牌的文件的绝对路径。oidc_token 和 oidc_token_file 必须设置其一。该参数支持通过环境变量 ALIBABA_CLOUD_OIDC_TOKEN_FILE 设置。

/var/run/secrets/oidc/token

role_arn(必填)

指定要扮演的 RAM 角色 ARN,格式为 acs:ram::<阿里云账号ID>:role/<RAM角色名称>。该参数支持通过环境变量 ALIBABA_CLOUD_ROLE_ARN 设置。

acs:ram::151192xxxxxx:role/k8srole

policy(可选)

一个 RAM 权限策略。如果设置,临时凭证的最终权限是此策略与 role_arn 对应角色所关联权限策略的交集。如果未设置,则最终权限仅由 role_arn 对应角色的权限决定。

{"Version":"1","Statement":[{"Effect":"Allow","Action":"oss:ListBuckets","Resource":"acs:oss:oss-cn-hangzhou:*:*"}]}

role_session_name(可选)

自定义的角色会话名称,通常设置为调用角色扮演的用户身份。如果未设置,默认为 terraform。该参数支持通过环境变量 ALIBABA_CLOUD_ROLE_SESSION_NAME 设置。

用户名

session_expiration(可选)

临时凭证的有效期,单位为秒。取值范围为 900 到所扮演角色的 MaxSessionDuration(默认为 3600)。可通过 更新角色信息修改角色的最大会话时间,上限为 43200 秒。

900

示例配置

OIDC 角色扮演认证是通过调用 AssumeRoleWithOIDC - OIDC角色SSO时获取扮演角色的临时身份凭证 实现。配置前,需准备以下信息:

  1. 创建 OIDC 身份提供商,从外部 IdP 获取 OIDC 令牌(OIDC Token),并记录提供商的 ARN 和 OIDC Token。

  2. 创建一个授信实体为“身份提供商”的 RAM 角色,为其授予所需权限(如 AliyunOSSFullAccess),并记录该角色的 ARN。

  3. (可选)编写一个 RAM 自定义权限策略(如仅允许访问杭州地域的 Bucket),用于与角色权限取交集,以实现更精细的访问控制。

准备完成后,在 provider 块中进行如下配置:

provider "alicloud" {
  assume_role_with_oidc {
    oidc_provider_arn  = "<OIDC 身份提供商的 ARN>"
    oidc_token         = "<外部 IDP 申请签发的 OIDC Token>"
    role_arn           = "<RAM 角色的 ARN>"
    policy             = "<RAM 权限策略的具体内容>"
    role_session_name  = "<自定义的角色会话名称>"
    session_expiration = <临时身份访问凭证的最大有效期>
  }
}

阿里云容器服务 ACK 支持通过 RRSA 功能自动创建 OIDC Provider 和签发 OIDC 令牌。详情请参见通过RRSA配置ServiceAccountRAM权限实现Pod权限隔离。开启 RRSA 后,ack-pod-identity-webhook 组件会自动为 Pod 注入 ALIBABA_CLOUD_OIDC_PROVIDER_ARNALIBABA_CLOUD_OIDC_TOKEN_FILE 和 ALIBABA_CLOUD_ROLE_ARN 环境变量。在此环境下,若要在 ACK Pod 内运行 Terraform,上述示例可简化为:

provider "alicloud" {
  region = "cn-hangzhou"
  assume_role_with_oidc {
    policy             = <<EOF
    {
      "Version": "1",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": "oss:ListBuckets",
          "Resource": "acs:oss:oss-cn-hangzhou:*:*"
        }
      ]
    }
    EOF
    session_name = "terraform-assume-role-session"
    session_expiration = 1000
  }
}

如果不需要通过 policy 参数进行精细化授权,可直接将所需权限授予 RAM 角色。此时,配置可进一步简化:

provider "alicloud" {
  region = "cn-hangzhou"
  assume_role_with_oidc {
    session_name = "terraform-assume-role-session"
    session_expiration = 1000
  }
}

角色扮演

角色扮演(AssumeRole)适用于需要将权限与身份(如 RAM 用户或 ECS 实例角色)分离,或需要跨账号访问资源的场景。它通过一个已有身份(如 RAM 用户)扮演另一个 RAM 角色,从而获取该角色的临时凭证来访问资源。

参数

配置角色扮演时,支持以下参数:

  1. access_key / secret_key 用于扮演角色的 RAM 用户的 AccessKey。该用户必须拥有 sts:AssumeRole 权限。这些参数也支持通过环境变量设置。

  2. assume_role:是一个配置块,包含以下参数:

参数名称

说明

示例值

role_arn(必填)

指定要扮演的 RAM 角色 ARN,格式为 acs:ram::1234567890123456:role/<RAM角色名称>

acs:ram::151192xxxxxx:role/k8srole

policy(可选)

一个 RAM 权限策略。如果设置,临时凭证的最终权限是此策略与 role_arn 对应角色所关联权限策略的交集。如果未设置,则最终权限仅由 role_arn 对应角色的权限决定。

{"Version":"1","Statement":[{"Effect":"Allow","Action":"oss:ListBuckets","Resource":"acs:oss:oss-cn-hangzhou:*:*"}]}

session_name(可选)

自定义的角色会话名称,用于在审计日志中区分操作者。如果未设置,默认为 terraform

terraform

session_expiration(可选)

临时凭证的有效期,单位为秒。取值范围为 900 到所扮演角色的 MaxSessionDuration(默认为 3600)。可通过 更新角色信息修改角色的最大会话时间,上限为 43200 秒。

3600

external_Id(可选)

角色外部 ID,用于防止“混淆代理人”问题。详情请参见使用ExternalId防止混淆代理人问题

ID

示例配置

角色扮演认证通过调用 AssumeRole - 获取扮演角色的临时身份凭证 实现。配置前,需准备以下内容:

  1. 创建一个 RAM 用户,并授予 AliyunSTSAssumeRoleAccess 策略(或包含 sts:AssumeRole 权限的自定义策略)。

  2. 为该 RAM 用户创建 AccessKey。

  3. 创建一个授信实体为“阿里云账号”的 RAM 角色,为其授予所需权限(如 AliyunOSSFullAccess),并记录该角色的 ARN。

  4. (可选)编写一个 RAM 自定义权限策略,用于与角色权限取交集,以实现更精细的访问控制。

准备完成后,在 provider 块中进行如下配置:

provider "alicloud" {
  # 用于调用 AssumeRole 的 RAM 用户的 AccessKey ID
  access_key = "<RAM 用户的 AccessKey ID>"
  # 用于调用 AssumeRole 的 RAM 用户的 AccessKey Secret
  secret_key = "<RAM 用户的 AccessKey Secret>"
  assume_role {
    role_arn           = "<一个 RAM 角色的 ARN>"
    policy             = "<一个 RAM 权限策略的具体内容>"
    session_name       = "<一个自定义的角色会话名称>"
    session_expiration = <临时身份访问凭证的最大有效期>
  }
}

以下示例演示了如何通过角色扮演获取访问杭州地域 OSS Bucket 列表的权限。为安全起见,示例中的 access_key 和 secret_key 通过环境变量设置,未在代码中明文写入:

provider "alicloud" {
  # 为了安全起见,此处的 access_key 和 secret_key 已经通过环境变量进行了设置
  region = "cn-hangzhou"
  assume_role {
    role_arn           = "acs:ram::11827xxxxxx:role/tf-assume-role"
    policy             = <<EOF
    {
      "Version": "1",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": "oss:ListBuckets",
          "Resource": "acs:oss:oss-cn-hangzhou:*:*"
        }
      ]
    }
    EOF
    session_name       = "terraform-assume-role-session"
    session_expiration = 1000
  }
}
说明

运行此示例前,需确保 tf-assume-role 角色已被授予 AliyunOSSFullAccess 权限,否则访问 OSS Bucket 时会因权限不足而失败。

如果 Terraform 运行在 ECS 实例上,可结合 ECS 服务角色,避免硬编码 AccessKey。此时,只需为绑定到 ECS 实例的 RAM 角色授予 AliyunSTSAssumeRoleAccess 策略即可。配置方式如下:

provider "alicloud" {
  ecs_role_name = "<绑定到 ECS 实例上的 RAM 角色名称>"
  region        = "cn-hangzhou"
  assume_role {
    role_arn           = "acs:ram::11827xxxxxx:role/tf-assume-role"
    policy             = <<EOF
    {
      "Version": "1",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": "oss:ListBuckets",
          "Resource": "acs:oss:oss-cn-hangzhou:*:*"
        }
      ]
    }
    EOF
    session_name       = "terraform-assume-role-session"
    session_expiration = 1000
  }
}

URL凭证

通过访问一个指定的 URI 来获取凭证。

参数

参数名称

说明

示例值

credentials_url

一个用于获取凭证的本地或远程 URI 地址。如果该 URI 未返回 HTTP 200 状态码或返回内容格式不正确,认证将失败。

http://credentials.uri/

region

默认地域和可用区

部分云产品不支持跨地域访问,建议将默认地域设置为资源所在地域。

cn-hangzhou

示例配置

provider "alicloud" {
  region = "cn-hangzhou"
  credentials_url= "http://credentials.uri/"
}

共享配置文件

Terraform 支持通过共享配置文件来使用已配置的访问凭证。共享配置文件是阿里云 CLI 生成的 config.json 文件,可以在一个文件中配置多种凭证信息(如静态 AK、ECS 角色、角色扮演等),并通过 profile 名称进行引用。更多配置方法,请参见配置凭证

共享配置文件的默认路径如下:

  • Linux/Mac系统:~/.aliyun/config.json

  • Windows系统: C:\Users\USER_NAME\.aliyun\config.json

配置示例

在 Terraform 的 provider 配置中,通过 profile 参数指定要使用的凭证配置名称。如果配置文件不在默认路径,可通过 shared_credentials_file 参数指定配置文件的绝对路径。配置示例如下:

provider "alicloud" {
  region                  = "cn-hangzhou"
  shared_credentials_file = "~/.aliyun/config.json"
  profile                 = "TerraformTest"
}

config.json配置文件示例:

{
    "current": "<PROFILE_NAME>",
    "profiles": [
        {
            "name": "<PROFILE_NAME>",
            "mode": "AK",
            "access_key_id": "<ALIBABA_CLOUD_ACCESS_KEY_ID>",
            "access_key_secret": "<ALIBABA_CLOUD_ACCESS_KEY_SECRET>"
        },
        {
            "name": "<PROFILE_NAME1>",
            "mode": "StsToken",
            "access_key_id": "<ALIBABA_CLOUD_ACCESS_KEY_ID>",
            "access_key_secret": "<ALIBABA_CLOUD_ACCESS_KEY_SECRET>",
            "sts_token": "<SECURITY_TOKEN>"
        },
        {
            "name": "<PROFILE_NAME2>",
            "mode": "RamRoleArn",
            "access_key_id": "<ALIBABA_CLOUD_ACCESS_KEY_ID>",
            "access_key_secret": "<ALIBABA_CLOUD_ACCESS_KEY_SECRET>",
            "ram_role_arn": "<ROLE_ARN>",
            "ram_session_name": "<ROLE_SESSION_NAME>",
            "expired_seconds": 3600
        },
        {
            "name": "<PROFILE_NAME3>",
            "mode": "EcsRamRole",
            "ram_role_name": "<RAM_ROLE_ARN>"
        },
        {
            "name": "<PROFILE_NAME4>",
            "mode": "External",
            "process_command": "<YOUR_COMMAND>",
            "region_id": "<REGION_ID>",
            "output_format": "json",
            "language": "en"
        },
        {
            "name": "<PROFILE_NAME5>",
            "mode": "OIDC",
            "oidc_provider_arn": "<OIDC_PROVIDER_ARN>",
            "oidc_token_file": "<OIDC_TOKEN_FILE>",
            "ram_role_arn": "<ROLE_ARN>",
            "ram_session_name": "<ROLE_SESSION_NAME>",
            "expired_seconds": 3600
        },
        {
            "name": "<PROFILE_NAME6>",
            "mode": "ChainableRamRoleArn",
            "source_profile": "<PROFILE_NAME>",
            "ram_role_arn": "<ROLE_ARN>",
            "ram_session_name": "<ROLE_SESSION_NAME>",
            "expired_seconds": 3600
        },
        {
            "name": "<PROFILE_NAME7>",
            "mode": "CloudSSO",
            "cloud_sso_sign_in_url": "https://******/login",
            "access_token": "eyJraWQiOiJiYzViMzUwYy******",
            "cloud_sso_access_token_expire": 1754316142,
            "cloud_sso_access_config": "ac-00s1******",
            "cloud_sso_account_id": "151266******"
        },
        {
            "name": "<PROFILE_NAME8>",
            "mode": "OAuth",
            "access_key_id": "<ALIBABA_CLOUD_ACCESS_KEY_ID>",
            "access_key_secret": "<ALIBABA_CLOUD_ACCESS_KEY_SECRET>",
            "sts_token": "<SECURITY_TOKEN>",
            "region_id": "<REGION_ID>",
            "output_format": "json",
            "language": "<zh|en>",
            "sts_expiration": "<STS_EXPIRATION>",
            "oauth_access_token": "<OAUTH_ACCESS_TOKEN>",
            "oauth_refresh_token": "<OAUTH_REFRESH_TOKEN>",
            "oauth_access_token_expire": 1754316142,
            "oauth_site_type": "<CN|EN>"
        }
    ]
}

config.json配置文件中可以通过mode指定不同的凭据:

  • AK:使用用户的Access Key作为凭据信息;

  • StsToken:使用STS Token作为凭据信息;

  • RamRoleArn:使用RAM角色的ARN来获取凭据信息;

  • EcsRamRole:利用ECS绑定的RAM角色来获取凭据信息;

  • External:通过执行外部程序命令动态获取凭证;

  • OIDC:通过OIDC ARNOIDC Token来获取凭据信息;

  • ChainableRamRoleArn:采用角色链的方式,通过source_profile指定config.json配置文件中其他凭据的名称,以重新获取新的凭据信息;

  • OAuth: 使用CLI通过OAuth登录方式来获取的凭据信息;

  • CloudSSO:云SSO用户使用阿里云CLI获取的凭据信息。