LoginSignup
18
15

More than 5 years have passed since last update.

AWS CLI で IAM Role を作りつつ、「Assume」や「Principal」について考える

Last updated at Posted at 2016-05-22

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

aws-iam-create-role
#!/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” がある。

原義としては「(何らかの集団の中で)一番目の人」の意味なので、下記の意味が出てきたのだろう。

  1. 「(演劇などの他の端役に対して)主役」「(オーケストラの他の楽器担当に対して)独奏」
  2. 「(一緒に働く代理人に対して)本人」

つまりは、そのポリシーを持ったもの(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

aws-iam-attach-role-policy
#!/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"
    }
  ]
}
18
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
15