最近花了些时间将服务的 AKSK 切换为 Role 认证方式,本篇博文对 AWS Role 及 AssumeRole 的一些知识点整理如下。
什么是 AWS Role?#
先从 AWS AKSK 说起,以往程序使用 S3、SQS 等 AWS 服务,一般是通过 KeyID、Secret Access Key 进行鉴权,好处是使用方便,但无法避免安全问题,一旦泄露就会对服务安全构成威胁。
使用 Role 可以解决这一问题,AWS 的 EC2 和 ECS Task 等资源都可以绑定 Role,从近期改造 Jenkins、Golang、Vector 的配置从 AKSK 到 Role 来看,使用 Role 很方便。
备忘记录。
什么是 AssumeRole?#
AssumeRole是AWS Identity and Access Management(IAM) 中的一个 API 操作,他允许一个 AWS 角色(Role) 临时地假设另一个角色,从而获得该角色的权限。当你需要一个 AWS 角色临时获得另一个角色的权限时,可以调用 AssumeRole API,让该角色假设目标角色身份,实现跨账号访问。
一个说不定有用的小 Tips:一个 Role 授权允许的情况下可以 AssumeRole 到自身,当多个服务公用配置的时候很灵活。
以下是几个使用 Role 的场景
场景1:ECS Task 内拉取 Code Commit 配置#

在这个场景下,Git CodeCommit 插件自动使用本机 Role 信息,即 Task Role,所以需要 ECS Task Role 具备访问 CodeCommit 的权限,Git 配合 CodeCommit 插件无需任何配置,即可使用本机的权限。
补充:通过设置 AWS_ROLE_ARN 和 AWS_ROLE_SESSION_NAME 两个环境变量,可以让 git-remote-codecommit 插件 AssumeRole 到其他角色。
场景2:ECS Task 内使用 Vector 上报 S3#
在 ECS Task 的 Vector 容器中,将收集到的日志发送到 S3,需要注意的是 S3 和 Vector 服务不在一个账号内。

Vector 服务跟 CodeCommit 插件的不同是,CodeCommit 自动使用本机的 Task Role,而 Vector 可以指定 assume_role,这样,我们可以在 S3 所在区域创建一个 IAM Role,为其赋予读写 S3 的权限。
再赋予 ECS Task Role 权限,使其能够具备 AssumeRole 的能力。这样,Vector 使用 Task Role 自动切换到 S3 Role,具备读写 S3 的能力。
场景3:EC2 下 Jenkins 使用 Role#
Jenkins 在使用 Jenkinsfile 调用 ansible 部署服务到正式环境时,使用 Role 进行认证。

使用 AWS 插件提供的 withAWS step,可以指定 Role 信息,跟 Vector 中指定 Assume Role 是类似的,需要 EC2 的基础 Role 具备切换为指定 Role 的权限,使得 ansible 具备访问 ECR / ECS 的能力。
EC2 和 ECS Task 配置 Role 在使用上有无区别?#
通过在不同场景的实践,可以得出以下结论
- ECS Task Role 可以理解为 EC2 Role,在使用 Role 上没有区别。
- 如果 Task 未绑定 ECS Task Role,那么在 Task 的容器内部获取到的 Role 即部署 Task 的 EC2 的 Role。
- 如果 Task 绑定了 ECS Task Role,那么在 Task 的容器内部获取到的 Role 是 ECS Task Role。
通过 AWS CLI 获取本机绑定的 Role#
首先,安装 aws-cli 后需要先配置地区,AKSK 不用填写,回车即可。
[root@jumpserver ~]# aws configure
AWS Access Key ID [None]:
AWS Secret Access Key [None]:
Default region name [None]: ap-northeast-1
Default output format [None]: json
而后获取当前身份
$ aws sts get-caller-identity
输出
{
"UserId": "AROA772VM***N4XQO3LPZ:i-0d8426c3***12cb43",
"Account": "AIOAM62***2S712R83HN",
"Arn": "arn:aws-cn:sts::AIOAM62***2S712R83HN:assumed-role/Role-allprompts-server-dev/i-0d843273d0b24cc2z"
}
测试其是否有 AssumeRole 到指定 Role 的权限#
AssumeRole 即程序可以借助当前机器的 Role,切换到另一个 Role,是否有权限切换,由绑定在机器上的 Role 权限决定。
$ aws sts assume-role --role-arn "arn:aws-cn:iam::AIOAM62***2S712R83HN:role/1122_server_ec2_dev_role" --role-session-name AWSCLI-Session
输出
{
"Credentials": {
"AccessKeyId": "<REDACTED_ACCESS_KEY_ID>",
"SecretAccessKey": "<REDACTED_SECRET_ACCESS_KEY>",
"SessionToken": "<REDACTED_SESSION_TOKEN>",
"Expiration": "2023-07-24T11:07:48+00:00"
},
"AssumedRoleUser": {
"AssumedRoleId": "<ACCOUNT_ID>:AWSCLI-Session",
"Arn": "arn:aws-cn:sts::<ACCOUNT_ID>:assumed-role/1122_server_ec2_dev_role/AWSCLI-Session"
}
}
正确输出如上,即机器绑定的 Role 允许用户或程序切换使用 1122_server_ec2_dev_role 角色。反之会提示权限错误
测试角色是否有 S3 权限#
$ aws s3 ls s3://my-bucket
如果当前机器 Role 拥有权限,则会输出目录,一般在使用时,也倾向于机器上配置比较基础的 Role,访问资源时 AssumeRole 到资源 Role,这样权限解耦,同时也能应对跨账号问题。
假设我们的机器绑定的是很基础的 Role,没有访问 S3 的权限,需要 AssumeRole 到指定 Role,如何通过 AWS CLI 模拟呢?
需要使用小节命令 aws sts assume-role ... 获取到的 Token,设置环境变量
$ export AWS_ACCESS_KEY_ID=<REDACTED_ACCESS_KEY_ID>
$ export AWS_SECRET_ACCESS_KEY=<REDACTED_SECRET_ACCESS_KEY>
$ export AWS_SESSION_TOKEN=<REDACTED_SESSION_TOKEN>
而后再次执行命令,即可查询 S3 桶下目录。
备注:如需要进一步确认可写权限,可以使用如下命令
$ echo "test file" > test_file.txt
$ aws s3 cp test_file.txt s3://my-bucket/test_file.txt
测试角色是否有 SQS 权限#
$ aws sqs get-queue-url --queue-name user_identity_event
结果
{
"QueueUrl": "https://sqs.cn-northwest-1.amazonaws.com.cn/AIOAM62***2S712R83HN/user_identity_event"
}
AssumeRole 使用方式跟 S3 使用临时 Token 的方式同理。
总结#
最后,Role 和 AssumeRole 的使用容易,但要避免混乱的权限分配,角色的命名和使用也需要设计一套方案来约束,保障安全的同时也便于维护。