使用Terraform首次开通ACK并授权默认角色

首次使用容器服务ACK时,需要为服务账号授予系统默认角色。当且仅当该角色被正确授予后,容器服务ACK才能正常地调用相关服务(ECS、OSS、NAS、SLB等)、创建集群以及保存日志等。本文介绍在首次使用ACK时如何通过Terraform授权容器服务默认角色。

索引

前提条件

  • 已安装Terraform

    说明

    请确认Terraform版本不低于v0.12.28,可通过terraform --version命令查看Terraform版本。

    • Cloud Shell默认安装配置了Terraform和阿里云账号信息,无需任何额外配置。

    • 如果您不使用Cloud Shell,关于安装Terraform的方式,请参见在本地安装和配置Terraform

  • 配置阿里云账号信息。

    执行如下命令,创建环境变量,用于存放身份认证信息。

    • Linux 环境

      export ALICLOUD_ACCESS_KEY="************"   #替换为阿里云账号的AK信息。
      export ALICLOUD_SECRET_KEY="************"   #替换为阿里云账号的SK信息。
      export ALICLOUD_REGION="cn-beijing"         #替换为您集群所在的地域。
    • Windows 环境

      set ALICLOUD_ACCESS_KEY="************"   #替换为阿里云账号的AK信息。
      set ALICLOUD_SECRET_KEY="************"   #替换为阿里云账号的SK信息。
      set ALICLOUD_REGION="cn-beijing"         #替换为您集群所在的地域。
    说明

    为提高权限管理的灵活性和安全性,建议您创建名为Terraform的RAM用户,并为该RAM用户创建AccessKey和授权。具体操作,请参见创建RAM用户为RAM用户授权

步骤一:开通容器服务ACK

容器服务ACK现已正式商用,在创建ACK集群前您需要开通相应服务。

  1. 创建一个工作目录,并在工作目录中创建名为main.tf的配置文件。

  2. 将如下代码复制到main.tf配置文件。

    展开查看本文用到的main.tf文件

    provider "alicloud" {   
    }
    
    // 开通容器服务ACK。
    data "alicloud_ack_service" "open" {
        enable = "On"
        type   = "propayasgo"
    }
  3. 执行如下命令,初始化Terraform运行环境。

    terraform init

    返回信息如下,Terraform初始化成功。

    Initializing the backend...
    Initializing provider plugins...
    ...
    Terraform has been successfully initialized!
    ...
  4. 执行如下命令,开通容器服务ACK。

    terraform apply

    返回信息如下,输入yes,按Enter键,服务开通成功。

    You can apply this plan to save these new output values to the Terraform state, without changing any real infrastructure.
    
    Do you want to perform these actions?
      Terraform will perform the actions described above.
      Only 'yes' will be accepted to approve.
    
      Enter a value: yes
    
    
    Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

步骤二:授权默认角色

首次登录容器服务ACK时,需要为服务账号授予系统默认角色,步骤如下。

  1. main.tf配置文件中添加如下代码,并执行terraform apply查询账号中是否存在已授权的角色。

    说明

    由于Terraform本身限制,无法自动检测角色是否存在,且自动授权不存在的角色,因此需要您手动查询角色信息,并为账号手动授权需要的角色。

    // 判断角色是否存在。
    data "alicloud_ram_roles" "roles" {
        policy_type = "System"
    }
    
    // 列举出账号已被完整授权角色信息。
    output "exist_role" {
      value = data.alicloud_ram_roles.roles
    }

    返回信息如下。

    No changes. Your infrastructure matches the configuration.
    
    Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.
    
    Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
    
    Outputs:
    ...
    exist_role = {
      "id" = "1788****59"
      "ids" = tolist([
        "3009617019****1438",
        "3023233020****0278",
        "3302003419****4675",
        "3178548808****5924",
        "3371411011****5177",
        "3475619590****3519",
      ])
      "name_regex" = tostring(null)
      "names" = tolist([
        "AliyunCASDefaultRole",
        "AliyunContainerRegistryDefaultRole",
        "AliyunCSDefaultRole",
        "AliyunCSKubernetesAuditRole",
        "AliyunCSManagedArmsRole",
        "AliyunCSManagedCmsRole",
        "AliyunCSManagedCsiRole",
        "AliyunCSManagedKubernetesRole",
        "AliyunCSManagedLogRole",
        "AliyunCSManagedNetworkRole",
        "AliyunCSManagedVKRole",
        "AliyunCSServerlessKubernetesRole",
        "AliyunServiceRoleForCSB",
        "AliyunServiceRoleForECI",
        "AliyunServiceRoleForGws",
        "AliyunServiceRoleForResourceDirectory",
        "AliyunServiceRoleForServiceMesh",
      ])
      "output_file" = tostring(null)
      "policy_name" = tostring(null)
      "policy_type" = "System"
      "roles" = tolist([
        {
          "arn" = "acs:ram::1848450434088535:role/aliyuncasdefaultrole"
          "assume_role_policy_document" = <<-EOT
          {
              "Statement": [{
                      "Action": "sts:AssumeRole",
                      "Effect": "Allow",
                      "Principal": {"Service": ["cas.aliyuncs.com"]}}],
              "Version": "1"}
          EOT
          "create_date" = "2023-07-17T03:27:28Z"
          "description" = "云盾证书服务(CAS)默认使用此角色来访问您在其他云产品中的资源"
          "document" = <<-EOT
          {
              "Statement": [{
                      "Action": "sts:AssumeRole",
                      "Effect": "Allow",
                      "Principal": {"Service": ["cas.aliyuncs.com"]}}],
              "Version": "1"}
          EOT
          "id" = "300961701980****"
          "name" = "AliyunCASDefaultRole"
          "update_date" = "2023-07-17T03:27:28Z"
        },
        {
          "arn" = "acs:ram::1848450434****:role/aliyuncontainerregistrydefaultrole"
          "assume_role_policy_document" = <<-EOT
          {
              "Statement": [{
                      "Action": "sts:AssumeRole",
                      "Effect": "Allow",
                      "Principal": {"Service": ["cr.aliyuncs.com"]}}],
              "Version": "1"}
          "id" = "3502335964487******"
          "name" = "AliyunServiceRoleForServiceMesh"
          "update_date" = "2022-09-27T10:26:50Z"
        },
      ])
    }

    如果您的账号已经授权了部分角色或者未授权任何角色信息,请参考下文的角色信息,为您的账号进行角色授权。

    展开查看所有角色详细信息

    provider "alicloud" {
    }
    
    // 创建角色。
    resource "alicloud_ram_role" "role" {
      for_each    = { for r in var.roles : r.name => r }
      name        = each.value.name
      document    = each.value.policy_document
      description = each.value.description
      force       = true
    }
    
    // 角色关联系统权限。
    resource "alicloud_ram_role_policy_attachment" "attach" {
      for_each    = { for r in var.roles : r.name => r }
      policy_name = each.value.policy_name
      policy_type = "System"
      role_name   = each.value.name
      depends_on  = [alicloud_ram_role.role]
    }
    
    // 所需角色。
    variable "roles" {
      type = list(object({
        name            = string
        policy_document = string
        description     = string
        policy_name     = string
      }))
      default = [
        {
          name            = "AliyunCSManagedLogRole"
          policy_document = "{\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":[\"cs.aliyuncs.com\"]}}],\"Version\":\"1\"}"
          description     = "容器服务(CS)Kubernetes集群日志组件使用此角色来访问您在其他云产品中的资源。"
          policy_name     = "AliyunCSManagedLogRolePolicy"
        },
        {
          name            = "AliyunCSManagedCmsRole"
          policy_document = "{\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":[\"cs.aliyuncs.com\"]}}],\"Version\":\"1\"}"
          description     = "容器服务(CS)集群CMS组件使用此角色来访问您在其他云产品中的资源。"
          policy_name     = "AliyunCSManagedCmsRolePolicy"
        },
        {
          name            = "AliyunCSManagedCsiRole"
          policy_document = "{\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":[\"cs.aliyuncs.com\"]}}],\"Version\":\"1\"}"
          description     = "容器服务(CS)Kubernetes集群存储插件使用此角色来访问您在其他云产品中的资源。"
          policy_name     = "AliyunCSManagedCsiRolePolicy"
        },
        {
          name            = "AliyunCSManagedVKRole"
          policy_document = "{\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":[\"cs.aliyuncs.com\"]}}],\"Version\":\"1\"}"
          description     = "容器服务(CS)Serverless集群VK组件使用此角色来访问您在其他云产品中的资源。"
          policy_name     = "AliyunCSManagedVKRolePolicy"
        },
        {
          name            = "AliyunCSClusterRole"
          policy_document = "{\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":[\"cs.aliyuncs.com\"]}}],\"Version\":\"1\"}"
          description     = "容器服务(CS)在应用运行期使用此角色来访问您在其他云产品中的资源。"
          policy_name     = "AliyunCSClusterRolePolicy"
        },
        {
          name            = "AliyunCSServerlessKubernetesRole"
          policy_document = "{\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":[\"cs.aliyuncs.com\"]}}],\"Version\":\"1\"}"
          description     = "容器服务(CS)ServerlessKubernetes版默认使用此角色来访问您在其他云产品中的资源。"
          policy_name     = "AliyunCSServerlessKubernetesRolePolicy"
        },
        {
          name            = "AliyunCSKubernetesAuditRole"
          policy_document = "{\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":[\"cs.aliyuncs.com\"]}}],\"Version\":\"1\"}"
          description     = "容器服务(CS)Kubernetes审计功能使用此角色来访问您在其他云产品中的资源。"
          policy_name     = "AliyunCSKubernetesAuditRolePolicy"
        },
        {
          name            = "AliyunCSManagedNetworkRole"
          policy_document = "{\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":[\"cs.aliyuncs.com\"]}}],\"Version\":\"1\"}"
          description     = "容器服务(CS)集群网络组件使用此角色来访问您在其他云产品中的资源。"
          policy_name     = "AliyunCSManagedNetworkRolePolicy"
        },
        {
          name            = "AliyunCSDefaultRole"
          policy_document = "{\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":[\"cs.aliyuncs.com\"]}}],\"Version\":\"1\"}"
          description     = "容器服务(CS)在集群操作时默认使用此角色来访问您在其他云产品中的资源。"
          policy_name     = "AliyunCSDefaultRolePolicy"
        },
        {
          name            = "AliyunCSManagedKubernetesRole"
          policy_document = "{\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":[\"cs.aliyuncs.com\"]}}],\"Version\":\"1\"}"
          description     = "容器服务(CS)ManagedKubernetes版默认使用此角色来访问您在其他云产品中的资源。"
          policy_name     = "AliyunCSManagedKubernetesRolePolicy"
        },
        {
          name            = "AliyunCSManagedArmsRole"
          policy_document = "{\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":[\"cs.aliyuncs.com\"]}}],\"Version\":\"1\"}"
          description     = "容器服务(CS)Kubernetes集群Arms插件使用此角色来访问您在其他云产品中的资源。"
          policy_name     = "AliyunCSManagedArmsRolePolicy"
        },
        {
          name            = "AliyunCISDefaultRole"
          policy_document = "{\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":[\"cs.aliyuncs.com\"]}}],\"Version\":\"1\"}"
          description     = "容器服务(CS)智能运维使用此角色来访问您在其他云产品中的资源。"
          policy_name     = "AliyunCISDefaultRolePolicy"
        },
        {
          name            = "AliyunOOSLifecycleHook4CSRole"
          policy_document = "{\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":[\"oos.aliyuncs.com\"]}}],\"Version\":\"1\"}"
          description     = "容器服务(CS)Kubernetes集群扩缩容节点池依赖OOS服务,OOS使用此角色来访问您在其他云产品中的资源。"
          policy_name     = "AliyunOOSLifecycleHook4CSRolePolicy"
        }
      ]
    }
  2. 执行如下命令,初始化Terraform运行环境。

    terraform init

    返回信息如下Terraform初始化成功。

    Initializing the backend...
    Initializing provider plugins...
    ...
    Terraform has created a lock file .terraform.lock.hcl to record the providerselections it made above. Include this file in your version control repositoryso that Terraform can guarantee to make the same selections by default whenyou run "terraform init" in the future.
    Terraform has been successfully initialized!
    ...
  3. 执行terraform apply,为您的账号进行角色授权。

    返回信息如下,输入yes,按Enter键,表示授权成功。

    .....
    Do you want to perform these actions?  
     Terraform will perform the actions described above.  
     Only 'yes' will be accepted to approve.  Enter a value:
  4. 执行如下命令,查看已存在的角色。

    terraform show

    返回信息如下,列举出了账号授权的所有角色信息,表示角色授权已完成。

    data "alicloud_ram_roles" "roles" {
      ...
      "names"       = [
        "AliyunCISDefaultRole",
        "AliyunCSClusterRole",
        "AliyunCSDefaultRole",
        ...
      ]
      ...
    }