AssumeRole — механизм аутентификации в AWS IAM, позволяющий получить временные данные доступа для выполнения запросов к ресурсам, к которым у вас нет доступа.
Эти временные данные доступа состоят из привычных ACCESS и SECRET ключей, плюс security token.
Одним из примеров AssumeRole может быть Jenkins в EC2, джобы которого могут выполнять операции в AWS-аккаунте, используя EC2 Instance IAM role вместо обычного набора ACCESS/SECRET ключей. См. AWS: ротация ключей IAM пользователей, EC2 IAM Roles и Jenkins .
При таком варианте код, запущенный на ЕС2, к которой подключена IAM Instance Role, фактически выполняет assume-role от имени инстанса, и получает его временные данные доступа.
Проверить подключенную к ЕС2 роль можно из его метаданных:
admin@bttrm-stage-console:~$ curl http://169.254.169.254/latest/meta-data/iam/info
{
"Code" : "Success",
"LastUpdated" : "2020-01-24T11:07:49Z",
"InstanceProfileArn" : "arn:aws:iam::534***385:instance-profile/mobilebackend-stage-CloudWatchAccessProfile-190BQNQP5L33O",
"InstanceProfileId" : "AIPAIB4MIE6GWWX6DP6RA"
}
Документация по EC2 metadata — тут>>> .
Документация по IAM AssumeRole — тут>>> .
Подготовка IAM
Создание пользователя
Добавляем нового юзера:
aws iam --region eu-west-3 --profile arseniy create-user --user-name iam-test-user
{
"User": {
"Path": "/",
"UserName": "iam-test-user",
"UserId": "AIDAXY5JMBME22RMBUPWJ",
"Arn": "arn:aws:iam::534***385:user/iam-test-user",
"CreateDate": "2020-01-24T08:41:09Z"
}
}
IAM test policy
Создаём IAM политику с разрешениями на выполнение некоторых API-вызовов к ядру AWS, назовём её iam-test-policy.json
:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:Describe*",
"iam:ListRoles",
"sts:AssumeRole"
],
"Resource": "*"
}
]
}
Добавляем её в AWS:
aws iam --region eu-west-3 --profile arseniy create-policy --policy-name example-policy --policy-document file://iam-test-user.json
{
"Policy": {
"PolicyName": "example-policy",
"PolicyId": "ANPAXY5JMBMEWA6G4ZMSP",
"Arn": "arn:aws:iam::534***385:policy/example-policy",
"Path": "/",
"DefaultVersionId": "v1",
"AttachmentCount": 0,
"PermissionsBoundaryUsageCount": 0,
"IsAttachable": true,
"CreateDate": "2020-01-24T08:43:26Z",
"UpdateDate": "2020-01-24T08:43:26Z"
}
}
Сохраняем её ARN — «arn:aws:iam::534***385:policy/example-policy» .
Attach IAM policy
Подключаем эту политику к созданному ранее пользователю:
aws iam --region eu-west-3 --profile arseniy attach-user-policy --user-name iam-test-user --policy-arn "arn:aws:iam::534***385:policy/example-policy"
Проверяем:
aws iam --region eu-west-3 --profile arseniy list-attached-user-policies --user-name iam-test-user
{
"AttachedPolicies": [
{
"PolicyName": "example-policy",
"PolicyArn": "arn:aws:iam::534***385:policy/example-policy"
}
]
}
AWS IAM trust policy
Создаём файл iam-test-role-trust-policy.json
, описываем политику, она будет являться AssumePolicyDocument :
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Principal": { "AWS": "arn:aws:iam::534***385:root" },
"Action": "sts:AssumeRole"
}
}
В «Principal»: { «AWS»: «arn:aws:iam::534***385:root» } указываем кто именно может assume роль, к которой подключена эта политика.
В данном случае значение root указывает на всех пользователей AWS-аккаунта 534***385 , см. документацию тут>>> .
RDS read-only IAM role
Создаём роль, подключаем AssumePolicyDocument , который создали выше:
aws iam --region eu-west-3 --profile arseniy create-role --role-name iam-test-role --assume-role-policy-document file://iam-test-role-trust-policy.json
{
"Role": {
"Path": "/",
"RoleName": "iam-test-role",
"RoleId": "AROAXY5JMBMEZUQEDSWLK",
"Arn": "arn:aws:iam::534***385:role/iam-test-role",
"CreateDate": "2020-01-24T09:50:44Z",
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::534***385:root"
},
"Action": "sts:AssumeRole"
}
}
}
}
Подключаем к нашей роли встроенную полиси самого AWS — AmazonRDSReadOnlyAccess :
aws iam --region eu-west-3 --profile arseniy attach-role-policy --role-name iam-test-role --policy-arn "arn:aws:iam::aws:policy/AmazonRDSReadOnlyAccess"
Проверяем политики, подключенные к нашей роли:
aws iam --region eu-west-3 --profile arseniy list-attached-role-policies --role-name iam-test-role
{
"AttachedPolicies": [
{
"PolicyName": "AmazonRDSReadOnlyAccess",
"PolicyArn": "arn:aws:iam::aws:policy/AmazonRDSReadOnlyAccess"
}
]
}
Проверка
Проверим, что пользователь может выполнит API-вызов ec2:Describe
к ядру Amazon Web Services.
Access keys
Получаем ключи доступа:
aws iam --region eu-west-3 --profile arseniy create-access-key --user-name iam-test-user
{
"AccessKey": {
"UserName": "iam-test-user",
"AccessKeyId": "AKI***VFY",
"Status": "Active",
"SecretAccessKey": "tPF***9Ee",
"CreateDate": "2020-01-24T09:54:57Z"
}
}
AWS profile
Настраиваем новый AWS-профиль :
aws configure --profile iam-test-user
AWS Access Key ID [None]: AKIAXY5JMBMEY36IZVFY
AWS Secret Access Key [None]: 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
Default region name [None]: eu-west-3
Default output format [None]: json
Проверяем, что мы пользуемся именно им:
aws --profile iam-test-user sts get-caller-identity
{
"UserId": "AIDAXY5JMBME22RMBUPWJ",
"Account": "534***385",
"Arn": "arn:aws:iam::534***385:user/iam-test-user"
}
И выполняем ec2:Describe
— должен сработать:
aws ec2 --profile iam-test-user describe-instances --query "Reservations[*].Instances[*].[VpcId, InstanceId, ImageId, InstanceType]"
[
[
[
"vpc-05161aa8c42ab63f0",
"i-0c449083586521956",
"ami-0db9a057d2e5a2554",
"t3.medium"
]
],
...
Теперь проверим доступ к RDS — должен вернуть AccessDenied :
aws rds --profile iam-test-user describe-db-instances --query "DBInstances[*].[DBInstanceIdentifier, DBName, DBInstanceStatus, AvailabilityZone, DBInstanceClass]"
An error occurred (AccessDenied) when calling the DescribeDBInstances operation: User: arn:aws:iam::534***385:user/iam-test-user is not authorized to perform: rds:DescribeDBInstances
Отлично.
Assume the IAM role
Находим ARN нашей iam-test-role роли:
aws iam --profile iam-test-user list-roles --query "Roles[?RoleName == 'iam-test-role'].[RoleName, Arn]"
[
[
"iam-test-role",
"arn:aws:iam::534***385:role/iam-test-role"
]
]
Создаём новую сессию — собственно, и выполняем assume-role
:
aws sts --profile iam-test-user assume-role --role-arn "arn:aws:iam::534***385:role/iam-test-role" --role-session-name AWSCLI-TestSession
{
"Credentials": {
"AccessKeyId": "ASI***DCU",
"SecretAccessKey": "CuO***JgT",
"SessionToken": "Fwo***bq0=",
"Expiration": "2020-01-24T11:05:07Z"
},
"AssumedRoleUser": {
"AssumedRoleId": "ARO***WLK:AWSCLI-TestSession",
"Arn": "arn:aws:sts::534***385:assumed-role/iam-test-role/AWSCLI-TestSession"
}
}
Отсюда берём три переменных, задаём их в окружение:
export AWS_ACCESS_KEY_ID=ASI***DCU
export AWS_SECRET_ACCESS_KEY=CuO***JgT
export AWS_SESSION_TOKEN=Fwo***bq0=
Ещё раз проверяем себя — теперь без указания профиля, что бы использовать переменные, которые только что задали (они имеют преимущество перед default профилем в /.aws/credentials
):
aws sts get-caller-identity
{
"UserId": "ARO***WLK:AWSCLI-TestSession",
"Account": "534***385",
"Arn": "arn:aws:sts::534***385:assumed-role/iam-test-role/AWSCLI-TestSession"
}
И сравним с вызовом раньше, после создания пользователя:
aws --profile iam-test-user sts get-caller-identity
{
"UserId": "AID***PWJ",
"Account": "534***385",
"Arn": "arn:aws:iam::534***385:user/iam-test-user"
}
Сравните UserId и Arn .
Проверяем доступы — сначала ЕС2, должен заблокировать:
aws ec2 describe-instances --query "Reservations[*].Instances[*].[VpcId, InstanceId, ImageId, InstanceType]"
An error occurred (UnauthorizedOperation) when calling the DescribeInstances operation: You are not authorized to perform this operation.
И RDS:
aws rds describe-db-instances --query "DBInstances[*].[DBInstanceIdentifier, DBName, DBInstanceStatus, AvailabilityZone, DBInstanceClass]"
[
[
"better-datascience-1",
"dsdb",
"available",
"eu-west-1a",
"db.t2.xlarge"
],
...
Assume IAM Role в AWS CLI
Проверяем ~/.aws/config
— тут у меня есть профиль arseniy , которым изначально и пользовались:
[profile arseniy]но
region = us-east-2
output = json
Создаём новый профиль, назовём его iam-test-user-cli :
...
[profile iam-test-user-cli]
role_arn = arn:aws:iam::534***385:role/iam-test-role
source_profile = arseniy
region = eu-west-3
Теперь при вызове AWS CLI с опцией --profile iam-test-user-cli
мы должны выполнить запрос от имени arseniy .
Порядок выполнения запроса будет следующим:
вызываем rds:Describe
(командой aws rds describe-db-instances
)
AWS CLI выполняет запрос к AWS IAM сервису, передавая ему arseniy как пользователя, и выполнит попытку assume role роли iam-test-role
AWS IAM проверит Trust Policy роли iam-test-role , в частности — Principal
, указанный там
если пользователь arseniy входит в Principal
(а «Principal»: { «AWS»: «arn:aws:iam::534***385:root » } включает всех пользователей аккаунта) — то IAM разрешит использование политики iam-test-role
и AWS выполнит API-запрос к RDS
Проверяем — получим текущего пользователя, используя --profile iam-test-user-cli
:
aws sts --profile iam-test-user-cli get-caller-identity
{
"UserId": "ARO***WLK:botocore-session-1579866288",
"Account": "534***385",
"Arn": "arn:aws:sts::534***385:assumed-role/iam-test-role/botocore-session-1579866288"
}
И проверяем доступ к RDS:
aws rds --profile iam-test-user-cli describe-db-instances --query "DBInstances[*].[DBInstanceIdentifier, DBName, DBInstanceStatus, AvailabilityZone, DBInstanceClass]"
[
[
"better-datascience-1",
"dsdb",
"available",
"eu-west-1a",
"db.t2.xlarge"
],
...
Готово.