CLI でやってみようシリーズ。
とりあえずロールを作ってみる
インラインの Assume Role に何を指定して良いのか分からなかったので、とりあえずブラウザコンソールから一つ適当なロールを作り、それを取得してみる。 ∥ get-role — AWS CLI 1.10.32 Command Reference
$ aws iam get-role --role-name myLambdaRole | jq .
{
"Role": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
}
}
]
},
"RoleId": "AROA~NYHE",
"CreateDate": "2016-05-16T08:59:21Z",
"RoleName": "myLambdaRole",
"Path": "/",
"Arn": "arn:aws:iam::~:role/myLambdaRole"
}
}
それをコピペしてみる。jq(1) を通しておけば、とりあえずフォーマットとして不正な JSON は飛ばない。 ∥ create-role — AWS CLI 1.10.32 Command Reference
#!/bin/bash
# -*- coding: utf-8 -*-
set -o nounset -o errexit -o pipefail
name=myNewRole
path="/division_x/project_y/"
assume_role_principal_service=lambda.amazonaws.com
assume_role_policy_document=$(jq -c . <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "$assume_role_principal_service"
}
}
]
}
EOF
)
role=$(aws iam create-role \
--role-name "$name" \
--path "$path" \
--assume-role-policy-document "$assume_role_policy_document" | jq -c . )
jq . <<<"$role"
実行結果:
$ ./aws-iam-create-role
{
"Role": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
}
}
]
},
"RoleId": "AROA~UOW2",
"CreateDate": "2016-05-22T10:08:43.394Z",
"RoleName": "myNewRole",
"Path": "/division_x/project_y/",
"Arn": "arn:aws:iam::~:role/division_x/project_y/myNewRole"
}
}
説明
だんだん語源学みたいになって行きますが。
ロール名
まず、ロール名のつけ方について。ここでは “myNewRole” としている。ブラウザコンソールから新規ロールを作ろうとすると、サンプルとして出てくるロール名が “myRole” と lowerCamelCase 形式なので、それに従ってみた。
Assume Role Policy について
次に AssumeRolePolicyDocument
がそもそも何なのかである。
コンソールで言うと、“Role Type” の “AWS Service Roles” から選んだものに相当し、このサービスからしかこのロールが使えなくなる。
それを AWS 用語で言うと、この Assume Role Policy は、今回作ったこのロールが、AWS STS (AWS Security Token Service) によって使われる(STS が AssumePolicy アクションを起こすことを許す)ことを意味するポリシーである。 ∥ 一時的セキュリティ認証情報 - AWS Identity and Access Management
IAM における普通のポリシー(普通の Inline Policy や Managed Policy)が、「当該ロールが持つ、何かをする権限」について規定しているのに対して、このポリシーは「このロールが STS によって使われる際の権限」について規定しているので、別枠になっているのである。
“assume” は普通は「仮定する」「みなす」などの意味で用いられるが、やや形式張った用法として「〈実権など〉を握る; 〈役割責任任務など〉を引き受ける(undertake)」“take or begin to have (power or responsibility)” の意味がある。認証・認可系のコンテキストで出てくる “assume” はこちらだろうな。
どうやら “assume” は、原義としては「証拠無しに認める」ということのようです。よって、以下のような 2 通りの語義が出てきたのでしょう。 ∥ assume - Wiktionary
1.「(証拠は無いけれどとりあえず状況を認めて)仮定する」「みなす」
2.「(これといった credential は提示せずに、役割を)引き受ける」「(権限を)得る」
つまりこれは、とある Role なりサービスなりが、他の Role に対して sts:AssumeRole する(他の Role(の権限)を assume(取得する))ことができるという意味なんだな。 ∥ AssumeRole - AWS Security Token Service
Principal って?
次に、“principal” について。
ポリシーでは何かと出てくる「プリンシパル」だが、これもどうも今まで意味がピンと来ていなかった。一般的には「(演劇などの)主役, 主演者; (コンサートの)独奏者, 主席奏者; (犯罪の)主犯」の方の意味なんだろうが、別の意味で「〖しばしば~s〗(代理人に対して)本人; (決闘の介添人に対し)決闘する本人」“a person for whom another acts as an agent or representative” がある。
原義としては「(何らかの集団の中で)一番目の人」の意味なので、下記の意味が出てきたのだろう。
- 「(演劇などの他の端役に対して)主役」「(オーケストラの他の楽器担当に対して)独奏」
- 「(一緒に働く代理人に対して)本人」
つまりは、そのポリシーを持ったもの(User や Role)の権限で動く際はいわば agent であり、それを使う側(ユーザやサービス)が principal(代理人ではなく、代理人を使う本人)である、という意味になる。 ∥ IAM ポリシーエレメントの参照 - AWS Identity and Access Management
パス
web コンソールではパスが付けられず、API 経由ならば付けられるので嬉しくなってつけてみた。 ∥ IAM ID - AWS Identity and Access Management
要は、ディレクトリサービスにおける部署のようなもので、ユーザやロールの数が多くなってきたら、「パス」に基いて何かを出来るように用意されている属性です。あくまでも我々の便宜のために用意されている属性であり、AWS のシステム側では全く使っていない模様。
Managed Policy の付与
せっかくなので、role に managed policy が attach されているか否かを確認して、attach されていなかったら attach するようにしてみます。このへんの jq(1) の使い方については、前回の投稿を参考にしてください。 ∥ jq(1) の力を借りて Bash スクリプト内で JSON を操作する - Qiita
#!/bin/bash
# -*- coding: utf-8 -*-
set -o nounset -o errexit -o pipefail
role_name="myNewRole"
policy_arns=(
"arn:aws:iam::aws:policy/AWSLambdaFullAccess"
"arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
)
policies_attached=$(aws iam list-attached-role-policies \
--role-name "$role_name" | jq -c .AttachedPolicies )
for policy_arn in "${policy_arns[@]}"
do
if test "$(jq -c --arg policy_arn "$policy_arn" \
'. | map(select(.PolicyArn == $policy_arn))' <<<"$policies_attached" )" \
= "[]"
then
aws iam attach-role-policy \
--role-name "$role_name" \
--policy-arn "$policy_arn"
echo Attached "$policy_arn"
else
echo Policy "$policy_arn" already attached.
fi
done
実行結果:
$ aws iam attach-role-policy \
--role-name myNewRole \
--policy-arn "arn:aws:iam::aws:policy/AWSLambdaFullAccess"
$ ./aws-iam-attach-role-policy
Policy arn:aws:iam::aws:policy/AWSLambdaFullAccess already attached.
Attached arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
$ aws iam list-attached-role-policies --role-name myNewRole | jq .
{
"AttachedPolicies": [
{
"PolicyName": "AWSLambdaFullAccess",
"PolicyArn": "arn:aws:iam::aws:policy/AWSLambdaFullAccess"
},
{
"PolicyName": "AWSLambdaBasicExecutionRole",
"PolicyArn": "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}
]
}