🤹🏻‍♀️

【覚え書き】実装で学ぶIAMポリシーとIAMロールとAssumeRole

2023/12/02に公開

はじめに

いろんなことをいい感じにしてくれるAWSさんのおかげで独自ルールのある繰り返しカレンダー登録を自動化できました(うれしい)
その仕組みをTerraformで構築したことで、権限周りの設定を書く過程で「どのサービスにどのようなIAM設定が必要でどのように記述するのか」という点を理解する必要がありました。
改めてIAM周りの勉強になった+このあたりの設定をする度に忘れている(理解があいまいなままである)ので、具体的+よくある簡単な実装を通して整理してみます。

話すこと

  • IAMポリシーとIAMロールとAssumeロールの違いと関係

話さないこと

  • IAMポリシーの種類について
  • IAMロールの使い方について

やったこと

  • EventBridgeSchedulerによるLambda定期実行
  • LambdaはS3に保存されたファイルを取得する
  • Lambdaの実行ログをCloudWatchに保存する

    よくある構成です。

まずは答え(必要な権限設定)

【EventBridgeScheduler】

  • 実行ロール
    • Lambdaを実行するポリシーのアタッチ
    • ユーザーに代わってロールを引き受けるための信頼ポリシーの定義

【Lambda】

  • 実行ロール
    • 以下を許可するポリシーのアタッチ
      • S3からオブジェクト取得
      • CloudWatchへの書き込み
    • ユーザーに代わってロールを引き受けるための信頼ポリシーの定義

他のAWSサービスを使用する場合にそのための権限が必要、と理解しました。(EventBridgeSchedulerがLambdaを実行する/LambdaがS3を使う・CloudWatchを使う)
上記図で言うと矢印の向きに対し設定が必要というイメージです。

IAMナントカってなんだっけ?

AWS IAM=Identity and Access ManagementとはAWSリソースへのアクセスを安全に管理するためのサービスです。
IAMにより、誰を認証して誰に何を許可するかを制御します。
IAMの話をするにあたって、AWSには大きく二種類の概念があると思っています。それは「人」と「物」です。(※この記事では「何」と表しているものは「物」を指しています。)
IAMの仕組みをものすごく簡単に表すと「誰 or 何が」「何に対して」「何をできるか」だと理解しています。
この制御を定義するために使われるのが「IAMポリシー」や「IAMロール」です。

IAMポリシー

「誰 or 何が」「何に」「何をできるか」を定義したものです。条件を決めることもできます。使い方によって主語を除くこともあります。
こういうことができますよ〜っていう許可証のイメージ。いろんな種類がある。

S3からオブジェクト取得を許可するポリシー
{
    "Version": "2012-10-17",
    "Statement":  [
        {
            "Effect": "Allow",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::${bucket_name}/*"
        }
    ]
}

IAMロール

今までの流れで言うと、「誰 or 何が」をより柔軟に定めるためにあるのがIAMロールです。
もうちょっと正確に言うと、「何に」「何をできるか」を定めたIAMポリシーを持つものであり「誰 or 何が」そのアクセス権限を担ってもらうかをひとまとめにしたものです。

ロールは言葉通り「役割」です。何ができるのかという役割を決めています。「人」=ユーザーや「物」=サービスアプリケーションが「役割」=ロールを引き受けることで、その役割に定められたアクセス権限を持つことができます。
こういうことができる役割を与えますよ〜のためにあるイメージ。
IAMロールでの設定はいくつかありますが、その一部として「許可ポリシー」と「信頼ポリシー」があります。コンソール上のこれ。

  • 許可ポリシー
    許可ポリシーはIAMロールに添付=アタッチするポリシーです。
    「何に」「何をできるか」 を定めたポリシー(アイデンティティベースのポリシー)を添付します。
    (アイデンティティベースポリシーはIAM ユーザー、グループ、ロールにアタッチされるもので、その実行主体はアタッチ先になるので「誰 or 何が」=Principalの記載はしません。)

  • 信頼ポリシー
    信頼ポリシーはコンソール上では「信頼関係」とされ、当該のIAMロールを委任する(引き受ける)条件を記したポリシーです。このIAMロールを渡すためにここに記した内容を信頼しますよ〜というイメージ。この人を信頼する、このサービスを信頼する、みたいな感じ。
    なので「誰 or 何が」に当たるPrincipalの記述が必要です。
    この信頼ポリシーに定義するのがsts:AssumeRoleというアクションです。

AssumeRole

IAMポリシー、IAMロールと並列に書いており分かりづらいですが、 AssumeRoleはロールではなくポリシーに記述するアクションのこと です。「何をできるか」に当たる部分。(※私は当初IAMポリシー、IAMロール、AssumeRoleの違いを整理したかったのでこのように並列で書いています)
Assumeは日本語にすると「(役割を)引き受ける」といった意味です。つまりそのまま、AssumeRoleはロールを引き受けるということになります。
また AWS STS = Security Token Serviceという一時的な認証情報を生成するサービスがあり、AssumeRoleはこのSTSのアクションの一つです。
例えば、Lambdaの実行ロールとなるIAMロールに記す信頼ポリシーに以下のように記述します。

Lambdaにロールの引き受けを許可するポリシー
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "lambda.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

この信頼ポリシーを記したIAMロールをロールAとすると、「ロールAを引き受けるアクションをLambdaに許可する」という意味になります。
ロールAからするとLambdaというPrincipalを信頼しますよ〜というイメージです。

まとめる

今回の実装はこのようになります。

考え方

使用するサービスに実行ロールを定義することで、そのサービスが他のAWSサービスを操作する権限(役割)を担うことができます。
そのために、まずIAMロールに できることの内容を添付(アタッチ) し、 役割を誰or何に任せるかを定義します。そしてそのIAMロールを当該サービスの実行ロールとする、という流れです。(なので役割を何に任せるかという部分は当該サービスとなる)

【Lambdaの実行ロールとするIAMロールのイメージ】

最後に

ここでは記していない様々な種類のポリシーがありますし、ポリシーやロールの与え方も様々です。とにかくいろいろあって混乱します。今回私はIAMポリシー、IAMロール、AssumeRoleがあやふやでした。
IAMポリシーはできること(アクション)を記したもの。IAMロールはポリシーをまとめて人や物に授けられるようにしたもの。AssumeRoleはロールを担うというアクションの一つ。
ちょっとした仕組みを構築するだけでもこれだけステップを踏む必要があり複雑だなあと感じました。ですが一度整理するとすっきり理解できましたし、最小特権の原則を守りながら柔軟な仕組みづくりをするために必要なことなのだと思いました。
ユースケースによって色々なパターンがあり、それを実現する仕組みがAWS IAMにはあります。これからまたその都度で整理・理解していきたいです。

GitHubで編集を提案
Fusic 技術ブログ

Discussion