【AWS】提高开发体验并防止CI/CD权限不足
如果在云环境的配置管理工具中使用IaC,可以通过利用GitHub Actions或AWS CodeBuild等来自动化配置管理,从而提高运维的稳定性。
然而,CI/CD管道由于权限不足而失败,在这方面是常见的情况,不是吗?(我偶尔也会这样做得很好)
特别是在初始化存储库或改进CI/CD环境时,我们可能需要重复多次提交修复并进行多次尝试和错误,会遇到这样的情况…。
我将介绍一些解决上述问题的提示。
本文假定您使用AWS。
太长不看 – 让我们使用AWS提供者中的assume_role功能。
在”aws”提供者的配置中添加assume_role部分。
provider "aws" {
region = "ap-northeast-1"
+ assume_role {
+ role_arn = "arn:aws:iam::12345678910:role/role-to-assume"
+ }
}
使用此功能,可以在执行terraform plan或terraform apply时,在内部切换角色(assume role)并继续处理。如果切换后的角色权限不足,可能会在此时注意到。然而,即使如此也不能绝对防止权限不足的情况发生…。
通常情况下,如果自动化了CI/CD流程,原则上应该只在本地执行terraform plan进行确认,而不执行terraform apply操作。因为terraform plan和apply操作实际执行的行为是不同的,所以权限不足的可能性仍然存在。
设置步骤
以下介绍了指定给上述assume_role的IAM角色的创建方法。
前提知识:IAM角色的信任关系
在AWS IAM中,”一个IAM用户或角色使用(或扮演)另一个角色”的操作被称为”Assume Role(承担角色)”。要实现Assume Role,需要通过”信任关系”(或信任策略)进行必要的配置,并将其应用于要被扮演的角色上。
示例代码
这是一个使用Terraform创建这种IAM角色的例子。我们考虑使用一个本地工作用的IAM用户(kokado-iam-user)的情况。
参考 – terraform-aws-modules/iam/aws | iam-assumable-role 子模块 | Terraform 注册表
data "aws_caller_identity" "current" {}
# --- 信頼ポリシーに設定する「Assume Role可能な(= 信頼できる)IAMユーザー」
data "aws_iam_user" "user" {
user_name = "kokado-iam-user"
}
# --- terraform plan/apply の中で切り替えるIAMロールを定義する
module "role_to_assume_for_cicd" {
source = "terraform-aws-modules/iam/aws//modules/iam-assumable-role"
create_role = true
role_name = "role-to-assume-for-cicd"
role_requires_mfa = false
trusted_role_arns = [
# 1. ローカル用のIAMユーザーを信頼する
data.aws_iam_user.user.arn,
# 2. ここで作成するロール自体も信頼する(自己信頼)
"arn:aws:iam::${data.aws_caller_identity.current}:role/role-to-assume-for-cicd",
]
custom_role_policy_arns = [
# Assume Roleの際に iam:GetUser が必要であるため追加
"arn:aws:iam::aws:policy/IAMReadOnlyAccess",
# 以降は構成管理に必要なポリシーを追加する
# arn:aws:iam::aws:policy/AmazonS3FullAccess,
# ...
]
}
2. 这里不详细解释我们对于在这里创建的角色本身的信任(自信)。请参考以下内容。
参考 – [规范变更] IAM角色的信任策略行为发生了变化,IAM角色的“隐式自信”已被移除 | DevelopersIO
最后需要进行操作确认,此外,还需要进行预先手动创建此IAM角色的准备工作。
data "aws_caller_identity" "current" {}
output "caller_identity" {
value = data.aws_caller_identity.current.arn
}
执行上述代码时,可以确认输出结果显示的是被使用的身份验证信息是assumed-role,而不是IAM用户。
$ terraform plan
data.aws_caller_identity.current: Reading...
...
module.role_to_assume_for_cicd.aws_iam_role_policy_attachment.custom[0]: Refreshing state... [id=role-to-assume-for-cicd-20231206153119131500000001]
Changes to Outputs:
+ caller_identity = "arn:aws:sts::12345678910:assumed-role/role-to-assume-for-cicd/aws-go-sdk-xxx"