IAMについて

Last-modified: Tue, 12 Mar 2019 18:50:31 JST (7d)

IAMとは

IAM(Identity and Access Management)とは、AWS上のリソースに対して認証、許可するアクセス制御機構のことです。
これを使う事によって、プログラムから特定のAPIしかアクセスさせない、とか、特定ユーザ(オペレータとか)は参照権限のみ
渡すとか、そういう制御ができるようになります。

IAMユーザについて

IAMユーザとは、一般的なユーザアカウントと同じものです。ただ、AWSではプログラムが使用する(つまりAPIのみ使用しコンソールは使用しない)
アカウントも同様にIAMユーザと呼びます。
プログラムによるアクセスの場合は、ユーザID、PWの代わりに、「アクセスキーID」と「シークレットアクセスキー」で認証します。
ユーザ(AWSコンソールにアクセスする場合)は、一般的なユーザアカウントと同様、IDとパスワードによる認証と、二段階認証など複数の認証を組み合わせることができます。
IAMユーザは作成しただけでは何もできません。そのユーザに対して必要となる「権限(ポリシー)」を与えてあげないといけません。
ここで重要なのは、「IAMユーザとポリシーは1対1ではない」という事です。
1ユーザに対し、複数のポリシーを設定することも当然可能です。

IAMグループについて

先ほど、IAMユーザとポリシーは1対1ではないとしました。実際は複数のIAMユーザに同一のポリシーを適用したい場合があります。
例えば「開発者」と「管理者」などです。
その際、1ユーザ毎にポリシーを割り当てるのは手間とミスの元です。ですので、設定したポリシーを一括適用するグループを作成し、
IAMユーザをそのグループに所属させることで、グループのポリシーを適用することができます。
勿論IAMユーザとグループは1対1ではないので、同一IAMユーザが複数のグループに所属することもできます。
余談ですが、例えば同一IAMユーザが、片方は明示的にEC2アクセスを拒否するグループ、もう一方は明示的にEC2アクセスを許可するグループ両方に所属した場合、サービスは許可されるのでしょうか?
AWSのポリシー判定は「ポリシー内の明示的な拒否は、すべての許可に優先します。」ので、アクセス拒否されます。
逆に言うと、明示的に拒否されていない場合は、明示的に許可されたものが優先されます。つまりデフォルト(無指定)はすべて拒否されます。

IAMロールについて

IAMロールとは、AWSリソースへのアクセスを委任する仕組みのことです。
例えば、EC2内で、EC2のデータをS3にバックアップするアプリを動かそうとします。
通常このアプリケーション専用のIAMユーザを作成し、認証情報(アクセスキー、シークレットキー)を組み込んで動作させますが、その場合認証情報の管理が必要になってきます。
そこで、IAMロールとして、S3バケットへの書き込みを許可するロールを設定し、それを稼働させるEC2インスタンスへIAMロールとして適用することにより、
EC2内で動くアプリケーションに対し、指定したIAMロールの権限が委任されるようになります。このとき、プログラム側に認証情報は不要で、割り当てたIAMロールが一時的な認証情報を付与し、実行できます。
つまり、IAMロールを割り当てたEC2インスタンス内でaws cliを動かす場合、aws configureで認証情報をセットしなくても、IAMロールの権限内で動作するという事です。(正確には内部的に一時認証情報を取得している)

  • なお、EC2については正確には「インスタンスプロファイル」を適用しており、EC2インスタンスにIAMロールを直接適用している訳ではない。参考ので、IAMロール作成時に信頼関係としてS3を指定したものを、後で信頼関係をEC2に編集したとしても、インスタンスプロファイルがないのでEC2に割り当てることは出来ない(選択肢に出てこない)

ポリシーについて

IAMの権限(ポリシー)はAWSのサービスによって様々ですが、基本的には、「何を」「どこまで」許可するかになります。
設定はJSONフォーマットで内部的に管理されています。カスタムポリシーエディタでJSONを作成、編集することも可能です。
なお、AWSのポリシー設定については、IAMポリシー以外にも基本このJSONフォーマットになっていています。(例えばS3バケットに指定するポリシーなど)

  • JSONの主な要素
    • Version
      特別な理由がない場合、現時点で"2012-10-17"が最新なのでそれを指定します。
    • Statement
      実際に「何を」「どこまで」許可または拒否するかのセットになります。
      Statement内には複数の要素を持つことができます。すべての要素はOR評価されます。
      • Statementの要素
      • Sid
        複数のステートメントを識別するためのIDです。(オプション)
      • Effect
        デフォルトは拒否。なので明示的に拒否したい場合を除き、Allowとなる
      • Action
        許可するAWSサービスアクション。簡単に言うと許可するAPIです。配列形式で複数指定できます。
      • Resource
        対象となるAWSリソース。ARNを参照。
      • Condition
        適用条件。例えば指定したユーザとかパスとか(オプション)

具体的な例

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "ListObjectsInBucket",
            "Effect": "Allow",
            "Action": ["s3:ListBucket"],
            "Resource": ["arn:aws:s3:::bucket-name"]
        },
        {
            "Sid": "AllObjectActions",
            "Effect": "Allow",
            "Action": "s3:*Object",
            "Resource": ["arn:aws:s3:::bucket-name/*"]
        }
    ]
}

まず、1つ目のStatementでは、"bucket-name"というS3バケットに対し、"ListBucket"アクションを許可しています。
この権限でバケットの中身をリストアップすることができます。
次に2つ目のStatementでは、"bucket-name"バケット配下に対し、"*Object"アクションを許可しています。
この"*Object"とは、GetObject、DeleteObject、PutObject、および「Object」という単語で終わるその他の Amazon S3 アクションを表します。
例えば、"Get*"、"List*"とすれば、参照専用となるわけですね。

もう一つの例です。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ec2:StartInstances",
                "ec2:StopInstances"
            ],
            "Resource": "arn:aws:ec2:*:*:instance/*",
            "Condition": {
                "StringEquals": {
                    "ec2:ResourceTag/Owner": "${aws:username}"
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": "ec2:DescribeInstances",
            "Resource": "*"
        }
    ]
}

1つ目のStatementは"Condition"にて、EC2のタグ"Owner"にユーザ名が入っているインスタンスのみ、スタートとストップの権限を割り当てています。
2つ目のStaementですべてのEC2インスタンス一覧を表示する許可を与えています。これがないとAWSコンソール上でインスタンス一覧の表示でエラーが出ます。見えている他のユーザ名が入っているインスタンスは触るとエラーになります。

ARNとは

リソースの指定で、"arn:"から始まるARN(AmazonResourceName)を指定する必要があります。
ARNとは、AWS 全体でユーザーを一意に識別する識別子です。
ARNは”:”を区切り文字とした、以下の構造になっています。サービスによっては省略する項目がありますが、その場合は"::"のようにします。
また、全てのリージョンのように全てを表したい場合はアスタリスク":*:"を使用します。
例外は、すべてのリソースを表す場合のみ、アスタリスク1つで指定します。

arn:<パーティション>:<サービス>:<リージョン>:<アカウントID>:<リソース>または<リソースタイプ>/<リソース名>
  • パーティション
    リソースが置かれているパーティションです。通常は"aws"になります。(リージョンとは違う)
  • サービス
    ここにあるように、AWSの各サービスを識別する識別子になります。
    ここにあるように、AWSのサービスによっては、次のリージョンやアカウントIDが不要(省略)するものがあります。
  • リージョン
    リソースが置いてあるリージョンになります。リソースによっては省略します。
  • アカウントID
    リソースを保持しているAWSアカウントのID番号になります。サービスによっては省略します。
  • リソース
    サービスによって異なります。例えばS3ではバケット名を指定したり、EC2だとinstance/instance-idでインスタンスIDをしていしたりします。

例えば、

arn:aws:s3:::bucket-name/*

だと、

  • パーティション:aws
  • サービス:S3
  • リージョン:指定なし
  • アカウントID:指定なし
  • リソース:bucket-name/*("bucket-name"バケット配下全て)
    を表します。

結果整合性について

AWS内にある膨大なサービスに対しIAMポリシーを伝達させるため、IAMの変更は即時反映されず、ある程度の時間がかかります。
その為、ポリシー変更後即座にアクセス権が変わらないことがあります
プログラムなので動的にポリシー変更をする場合、注意しましょう。


Counter: 11, today: 1, yesterday: 0

このページの参照回数は、11です。