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
エレメントでは、予め用意されているStringEquals
やNumericGreaterThan
といった条件演算子によって、リクエストに含まれるコンテキストの値と条件が一致しているかを確認する。
{
"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ユーザのname
orpath
を変更する場合は、force_detach_policies
引数がtrue
にセットして適用する必要がある。
そうしないとDeleteConflict
エラーが発生してしまう。
aws_iam_role_policy_attachment
はこれをおこなう必要性はない
aws_iam_role
IAMロール を作成する
aws_iam_policy_attachment
リソースを通じてIAMポリシーがIAMユーザにアタッチされていた時に、IAMユーザのname
orpath
を変更する場合は、ふぉr
引数がtrue
にセットして適用する必要がある。
そうしないとDeleteConflict
エラーが発生してしまう。aws_iam_user_policy_attachment
はこれをおこなう必要性はない
assume_role_policy
に対してaws_iam_policy
を使うことはできないがaws_iam_policy_document
data sourceを使うことはできる。
aws_iam_role_policy
インラインポリシーを作成してIAMロールにアタッチする
(同じくインラインポリシーを作成する)aws_iam_role
リソースのinline_policy
argumentと互換性がない
両方同時に使うと、どちらもインラインポリシーの管理を試みるので、常に差分が表示されるなどの不具合が生じる
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_attachment
、aws_iam_user_policy_attachment
、aws_iam_group_policy_attachment
リソースは、排他的なIAMポリシーのアタッチメントを強制しない。
まとめ
めっちゃややこしい