TerraformにおけるAWS IAMに関するリソースを改めて整理しよう

Posted on
AWS IAM

TerraformにおけるIAM系のresourceの書き方がややこしいので、頭の中を整理しておく。

そもそものIAMリソースの話

よく忘れるポイントをまとめておく。

AWSにおけるIAM関連のリソース種別

  • IAMポリシー:AWSのサービスやリソースに対する操作権限をJSON形式で定義したもの。
  • IAMユーザ:AWSの操作をおこなうためのユーザ。
  • IAMグループ:ユーザをグルーピングするための概念。
  • IAMロール:AWSリソースそのものにAWSのリソースへの操作権限を付与する仕組み。

AWSにおけるポリシーの種別

  • インラインポリシー:単一のIAMユーザ/グループ/ロール内でのみ使用出来る。
  • 管理ポリシー:複数のIAMユーザ・グループ・ロールに付与できる。
    • AWS管理ポリシー:AWSが用意してくれている基本的なポリシー、PowerUserAccessみたいなやつ。
    • カスタマ管理ポリシー:ユーザが独自で定義するIAMポリシー。
  • (IAMロールの)信頼関係:IAMロールの権限移譲操作に特化したポリシーで、当該の信頼ポリシーを関連づけたIAMロールが保有する権限を、信頼ポリシーの操作主体であるPrincipalに移譲(を許可)する。
  • リソースベースのポリシー:関連付ける先がAWSサービス。S3のバケットポリシーのようなもの。

IAMポリシー

基本的な文法

いくつかの要素について覚えておく必要がある。

  • Version:IAMポリシーの文法のバージョン。2021年6月現在、現行のバージョンは 2012-10-17 でそこから変わってない。
  • Effect:Allow/Denyなのか。
  • Action:「どのAWSのサービス」に対する「どのような操作」を許可(拒否)するのか。
  • Resource「どのAWSリソース」に対する操作を許可(拒否)するのか。
  • Princopal:信頼関係/リソースベースのポリシーにのみ登場する。
  • Condition:ポリシーに対する条件を定義する。

公式のリファレンスを確認したときは「IAM JSON ポリシーの要素のリファレンス」を参照する。

Condition

IAMポリシーのConditionエレメントでは、予め用意されているStringEqualsNumericGreaterThanといった条件演算子によって、リクエストに含まれるコンテキストの値と条件が一致しているかを確認する。

{
  "Version": "2012-10-17",
  "Statement": {
    "Effect": "Allow",
    "Action": "iam:*AccessKey*",
    "Resource": "arn:aws:iam::ACCOUNT-ID-WITHOUT-HYPHENS:user/*",
    "Condition": {"Bool": {"aws:SecureTransport": "true"}}
  }
}

条件演算子の一覧は「IAM JSON ポリシーの要素: 条件演算子」に記載がある。 よく使われる例をあげる。

  • StringEquals:文字列の比較。完全一致で大文字と小文字を区別する。
  • Bool:true/falseの比較。
  • IpAddress/NotIpAddress:IPアドレスに基づいてアクセスを制限する。aws:SourceIpと合わせて使用する。
    • 「AWSへのAPIリクエストが指定したCIDRブロックの範囲から送られてくる必要がある」といった制御を実現する。
    • Action及びResource*にしてNotIpAddressのCondtionを設定することで、特定のCIDR範囲外からのActionをすべてブロックする、といった制御を実現する。

Terraform HCLで書く時は「Data Source: aws_iam_policy_document」を参考にする。

  • test(Required):IAM Condition Operator(条件演算子)
  • values(Required):条件を評価する耐え目の値。複数の値がある場合、少なくとも1つが適用されると条件は一致する(OR
  • variable(Required):条件を適用するコンテキスト変数の名前。コンテキスト変数は、aws:で始まる標準のAWS変数、またはサービス名のプレフィックスが付いたサービス固有の変数のいずれか。

TerraformにおけるIAM関連のリソース

Terraformを使ってIAM関連のリソースを作成する時に覚えておきたいリソースを整理しておく。

aws_iam_user

IAMユーザ を作成する

aws_iam_policy_attachmentリソースを通じてIAMポリシーがIAMユーザにアタッチされていた時に、 IAMユーザのnameorpathを変更する場合は、force_detach_policies引数がtrueにセットして適用する必要がある。 そうしないとDeleteConflictエラーが発生してしまう。 aws_iam_role_policy_attachmentはこれをおこなう必要性はない

aws_iam_role

IAMロール を作成する

aws_iam_policy_attachmentリソースを通じてIAMポリシーがIAMユーザにアタッチされていた時に、IAMユーザのnameorpathを変更する場合は、ふぉr引数がtrueにセットして適用する必要がある。 そうしないとDeleteConflictエラーが発生してしまう。aws_iam_user_policy_attachmentはこれをおこなう必要性はない

assume_role_policyに対してaws_iam_policyを使うことはできないがaws_iam_policy_documentdata sourceを使うことはできる。

aws_iam_role_policy

インラインポリシーを作成してIAMロールにアタッチする

(同じくインラインポリシーを作成する)aws_iam_roleリソースのinline_policyargumentと互換性がない 両方同時に使うと、どちらもインラインポリシーの管理を試みるので、常に差分が表示されるなどの不具合が生じる

aws_iam_role_policy_attachment

IAMポリシーをIAMロールに対してアタッチする

aws_iam_user_policy

インラインポリシーを作成してユーザにアタッチする

aws_iam_policy

管理ポリシー(カスタマ管理ポリシー) を作成する

aws_iam_user_policy_attachment

IAMポリシーをIAMユーザに対してアタッチする

aws_iam_policy_attachment

管理ポリシーをIAMユーザ・ロール・グループにアタッチする

aws_iam_policy_attachmentリソースは排他的なIAMポリシーのアタッチメントをおこなう。 AWSアカウント全体で、単一のポリシーがアタッチされた全てのユーザ・グループ・ロールは、単一のaws_iam_policy_attachmentによって宣言される必要がある。 これはTerraform以外の手段、あるいは他のTerraformのリソースを使ってポリシーがアタッチされたユーザ・グループ・ロールは、このリソースによってrevokeされることを意味する。 aws_iam_role_policy_attachmentaws_iam_user_policy_attachmentaws_iam_group_policy_attachmentリソースは、排他的なIAMポリシーのアタッチメントを強制しない。

まとめ

めっちゃややこしい