LoginSignup
16
9

More than 5 years have passed since last update.

自分なりにAWS IAMについてまとめた

Posted at

AWSに限ったことではないが、権限周りが苦手でした。
やれ「権限があるのね」やれ「権限がないのね」でわかったふりをしていたことは否めません。
いろいろと環境構築していく中で、自分なりに整理できるようになったかな?と思えるようになったので吐き出してみます。
まず、IAMは以下の用語を抑えれば、ほとんどの状況において、IAMを使いこなせるのではないかと個人的には思っています。

  • ユーザ
  • グループ
  • ポリシー
  • ロール
  • サービスロール
  • EC2インスタンスのサービスロール

ユーザとポリシー

AWSのサービスを操作するうえで、まずユーザを作る必要があります。
aws-cliでawsのサービス操作をしたい場合、ユーザを作成するとき(または作成したあと)に、アクセスキーとシークレットアクセスキーを付与することが出来ます。
これを、aws-cliを利用する際の認証としてつかうことで、各種サービスはどのユーザからのアクセスであるのかを判断しています。

しかし、ユーザを作ったからといって、AWSのサービスを操作することが出来るかといえばそうではありません。
作成したユーザに対いて、作成者はサービスを操作するうえで必要な権限を付与してあげなければいけません。
この必要な権限をポリシーといいます。

以下は、権限(S3へバケットを作成できるポリシー)が付与されていないユーザの作成し、S3へバケットを参照しようとした結果。

ユーザ作成
aws iam create-user --user-name dev-nemoto
  # {
  #     "User": {
  #         "UserName": "dev-nemoto",
  #         "Path": "/",
  #         "CreateDate": "2018-11-26T02:58:51Z",
  #         "UserId": "AIDAIBVEMHJXDRLYUICD6",
  #         "Arn": "arn:aws:iam::123456789012:user/dev-nemoto"
  #     }
  # }
aws iam create-access-key --user-name dev-nemoto
  # {
  #     "AccessKey": {
  #         "UserName": "dev-nemoto",
  #         "Status": "Active",
  #         "CreateDate": "2018-11-26T03:03:53Z",
  #         "SecretAccessKey": "EqECbJGPzgRtxaxp5uevJP00uKcPohlv6si+xMKb",
  #         "AccessKeyId": "AKIAJGLI4OTSMW6OESKQ"
  #     }
  # }
aws configure --profile dev-nemoto
  # AWS Access Key ID [None]: AKIAJGLI4OTSMW6OESKQ
  # AWS Secret Access Key [None]: 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
  # Default region name [None]: ap-northeast-1
  # Default output format [None]:
S3参照
aws s3 ls --profile dev-nemoto
  # 
  # An error occurred (AccessDenied) when calling the ListBuckets operation: Access Denied

必要であれば管理者がユーザに対して権限(AmazonS3ReadOnlyAccess)を付与してあげる。

権限付与
POLICY_ARN=$(aws iam list-policies --query "Policies[?PolicyName==\`AmazonS3ReadOnlyAccess\`].Arn" --output text)
echo ${POLICY_ARN}
  # arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
aws iam attach-user-policy --user-name dev-nemoto --policy-arn ${POLICY_ARN}

付与してあげた結果、ユーザはS3へバケットを作成することが出来るようになります。

ユーザとポリシーの関係はシンプルでわかりやすいですね。

グループ

先の説明のように、S3への操作権限だけを付与していくだけであれば、たいして問題ではないのかもしれませんが、ユーザの役割ごとに異なった権限が必要な場合に、ユーザが追加されるたびに管理者がポリシーの設定をするのは現実的ではないと思います。
もちろん「それぞれの役割ごとにシェルスクリプトを組んでいるのから、ユーザを新規作成した際に、そのスクリプトを実行しているから楽よ」という人はいるかもしれませんが、変更があった場合などに、ユーザ分のシェルスクリプトを実行することを考えると、大規模なユーザを抱えている管理者は手間でしかありません。

そこで利用するのがグループです。
グループでは、役割ごとに権限を設定することが出来ます。
つまり、ユーザに直接ポリシーを付与するのではなく、ユーザをグループに所属させることで、
グループ自体の役割が変わった場合には、各ユーザのポリシーを変更するのではなく、グループに付与されているポリシーを変更することで、この問題を解決することができます。
もちろん、グループに所属する以外に、ユーザには一時的に特別なポリシーを付与したり、またユーザに対して複数のグループに所属させることも可能です。

ユーザから権限をデタッチ
aws iam detach-user-policy --user-name dev-nemoto --policy-arn ${POLICY_ARN}
グループ作成
aws iam create-group --group-name develop
  # {
  #     "Group": {
  #         "Path": "/",
  #         "CreateDate": "2018-11-26T03:26:39Z",
  #         "GroupId": "AGPAI66QMQD3W7MUCNRJW",
  #         "Arn": "arn:aws:iam::123456789012:group/develop",
  #         "GroupName": "develop"
  #     }
  # }
グループに権限付与
aws iam attach-group-policy --group-name develop --policy-arn ${POLICY_ARN}
グループに所属
aws iam add-user-to-group --group-name develop --user-name dev-nemoto

ロール

ユーザはアクセスする際に、アクセスキーおよびシークレットアクセスキーを持って認証され、アクセスキー、シークレットアクセスキーは長期的に利用することが出来ます。
例えば、他のAWSアカウントに属しているユーザに対して、他のAWSアカウントを利用させたい場合などはどのようにすればよいでしょうか?
利用させたいAWSアカウントにユーザを作成してしまうのも手ですが、この場合、ユーザの管理が煩雑になってしまう他、セキュリティリスクの可能性が残ります。
そのような場合に、ロールは一時的にその権限を提供する仕組みです。

そのため、ロール作成時には信頼されたエンティティを指定する必要があり、その信頼されたエンティティにのみ作成されたロールは一時的な権限を付与します。

サービスロール

作成するロールでは、信頼する相手として、AWSサービス、別のAWSアカウント、ウェブID、SAML2.0フェデレーションなどがあります。
中でもAWSサービスがロールを引き受けるような利用シーンがよくありますが、そのロールをサービスロールと言います。

例えばLambdaでサーバレスなアプリケーションを作成する場合、そのサービス単体で動作する場合は少なく、いくつかのサービスと連携させていると思います。
CloudWatch Logsにログを出力する必要があれば、新しいロググループを作成する権限、そのロググループに新しいログストリームを作成する権限、ログイベントをログストリームに更新する権限が必要になります。

ただしLambdaはユーザではありませんので直接権限を持つことは出来ません。そこでLambdaはロールを引き受け、一時的にその権限を持つことで、ログを出力する権限を得ることが出来ます。

CloudFormationを利用して各サービスを構築していくことを考えた場合、いろいろな権限を持ったロールが必要になることが想像できると思います。

ロールの作成
cat << EOT > trust-policy.json
{
  "Version": "2012-10-17",
  "Statement": {
    "Effect": "Allow",
    "Principal": {"Service": "lambda.amazonaws.com"},
    "Action": "sts:AssumeRole"
  }
}
EOT
aws iam create-role --role-name devLambdaRole --assume-role-policy-document file://trust-policy.json
  # {
  #     "Role": {
  #         "AssumeRolePolicyDocument": {
  #             "Version": "2012-10-17",
  #             "Statement": {
  #                 "Action": "sts:AssumeRole",
  #                 "Effect": "Allow",
  #                 "Principal": {
  #                     "Service": "lambda.amazonaws.com"
  #                 }
  #             }
  #         },
  #         "RoleId": "AROAJGCUXVJJU7ED7URBQ",
  #         "CreateDate": "2018-11-26T03:38:29Z",
  #         "RoleName": "devLambdaRole",
  #         "Path": "/",
  #         "Arn": "arn:aws:iam::123456789012:role/devLambdaRole"
  #     }
  # }
ロールに管理ポリシーを付与
POLICY_ARN=$(aws iam list-policies --query "Policies[?PolicyName==\`CloudWatchLogsFullAccess\`].Arn" --output text)
echo ${POLICY_ARN}
  # arn:aws:iam::aws:policy/CloudWatchLogsFullAccess
aws iam attach-role-policy --role-name devLambdaRole --policy-arn ${POLICY_ARN}

EC2インスタンスのサービスロール

サービスロールと何が違うのか?
例えば、S3にデータをアップロード、ダウのロードするアプリをEC2インスタンスにデプロイした場合を考えてみてください。
このアプリが、S3を操作する権限をどのように管理すればいいだろうか?

  • アプリ用のユーザをIAMで作成
  • 作成したユーザにS3の操作権限を付与
  • そのユーザを利用したアプリがS3を操作

など考えられると思います。
この場合、ユーザは永続的な認証情報を保持しているため、仮にこの認証情報が洩れることがあればセキュリティ被害を受ける可能性があります。
では、認証情報をローテートすればいいかというと、その度にEC2インスタンスの情報を書き換える必要が出てきてしまい、これもまた面倒で現実的ではありません。
そう考えると、一時的に権限を持つことが出来るロールを使って操作すればセキュリティ被害を軽減することが出来るのではないか?と想像できるだろうと思われます。

ここで利用するのがEC2インスタンスのサービスロールになります。
この場合、EC2インスタンス構築時にインスタンスにサービスロールを設定します。
ここで設定したサービスロールは、EC2インスタンスで動作するアプリなどで一時的にサービスの権限が付与されることでアプリでサービスを操作可能にするという仕組みになります。

ロールの作成
cat << EOT > trust-policy.json
{
  "Version": "2012-10-17",
  "Statement": {
    "Effect": "Allow",
    "Principal": {"Service": "ec2.amazonaws.com"},
    "Action": "sts:AssumeRole"
  }
}
EOT
aws iam create-role --role-name devEc2InstanceRole --assume-role-policy-document file://trust-policy.json
  # {
  #     "Role": {
  #         "AssumeRolePolicyDocument": {
  #             "Version": "2012-10-17",
  #             "Statement": {
  #                 "Action": "sts:AssumeRole",
  #                 "Effect": "Allow",
  #                 "Principal": {
  #                     "Service": "ec2.amazonaws.com"
  #                 }
  #             }
  #         },
  #         "RoleId": "AROAIH36GLO2GMWW72LVC",
  #         "CreateDate": "2018-11-26T03:48:23Z",
  #         "RoleName": "devEc2InstanceRole",
  #         "Path": "/",
  #         "Arn": "arn:aws:iam::123456789012:role/devEc2InstanceRole"
  #     }
  # }
ロールに管理ポリシーを付与
POLICY_ARN=$(aws iam list-policies --query "Policies[?PolicyName==\`AmazonS3FullAccess\`].Arn" --output text)
echo ${POLICY_ARN}
  # arn:aws:iam::aws:policy/AmazonS3FullAccess
aws iam attach-role-policy --role-name devEc2InstanceRole --policy-arn ${POLICY_ARN}
インスタンスプロファイルの設定
aws iam create-instance-profile --instance-profile-name devEc2InstanceProfile
  # {
  #     "InstanceProfile": {
  #         "InstanceProfileId": "AIPAJJAOJLHXALQVAKSES",
  #         "Roles": [],
  #         "CreateDate": "2018-11-26T03:49:25Z",
  #         "InstanceProfileName": "devEc2InstanceProfile",
  #         "Path": "/",
  #         "Arn": "arn:aws:iam::123456789012:instance-profile/devEc2InstanceProfile"
  #     }
  # }
aws iam add-role-to-instance-profile \
  --instance-profile-name devEc2InstanceProfile \
  --role-name devEc2InstanceRole
16
9
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
16
9