はじめに
CloudFormationはロールを指定しなくても動作しますが、
その場合は実行ユーザーの権限でリソースが作成されます。
例えば、AdministratorAccessを持つユーザーで実行した場合、
CloudFormationも同等の強い権限で動作してしまいます。
この状態では以下の問題があります。
- 権限が広すぎて制御できない
- 誤操作による影響範囲が大きい
- CloudTrail上で誰の操作か判別しづらい
そこで本記事では、最小権限を実現するために
CloudFormation専用のExecution Roleを作成し、そのロール経由でリソースを作成する設計を行いました。
前提
- CloudFormationが使用するExecution Roleの設計
- GitHub ActionsやOIDCは使用しない(CloudFormation単体)
-
AwsStudyプレフィックスでリソース管理
設計方針
今回の設計では以下の方針を採用しました。
-
AwsStudy-*のリソースに限定する - Create系は制限が難しいため広めに許可
- Modify/Deleteはタグで制限
- 機密情報(SSM / KMS)は最小権限で制御
-
iam:PassRoleは特定ロールのみに限定
CloudFormationテンプレート
(※重要部分のみ抜粋)
# KMS decrypt only via SSM
- Sid: KmsDecryptViaSsm
Effect: Allow
Action: kms:Decrypt
Resource: !Ref SsmKmsKeyArn
Condition:
StringEquals:
kms:ViaService: !Sub ssm.${AWS::Region}.amazonaws.com
設計のポイント
① CloudFormation操作のスコープ制限
スタック名を AwsStudy-* に限定することで、
意図しないスタック操作を防ぎます。
② CreateとModify/Deleteの分離
Create系はリソース作成前のためARNで制限できません。
そのため、やむを得ず Resource: "*" を使用しています。
一方で、Modify/Deleteは以下のように制限しています。
Condition:
StringEquals:
ec2:ResourceTag/Project: AwsStudy
👉 タグベースで対象リソースを制御
③ Describe/List系の扱い
Describe や List 系のAPIは
リソースレベルで制御できないものが多いため、* を許可しています。
👉 IAM設計ではよくある制約
④ iam:PassRoleの制限
EC2にロールを渡す際の iam:PassRole は、
特定ロールのみに制限しています。
👉 権限昇格のリスクを防止
⑤ SSM + KMS の最小権限
RDSのパスワードはSSM Parameter Store(SecureString)で管理し、
KMSで暗号化しています。
kms:ViaService: ssm.${AWS::Region}.amazonaws.com
この設定により、
- SSM経由 → 復号可能
- 直接KMS → 復号不可
となります。
👉 復号の「経路」を制御しているのがポイント
IAM Access Analyzerについて
IAM Access Analyzerを利用すると、
CloudTrailログを元にポリシーを生成できます。
ただし以下の制約があります。
- 実行した操作しか取得できない
- 将来必要な権限(Modify/Deleteなど)が含まれない
そのため本記事では、
👉 設計ベースで最小権限を定義する方針
としました。
ハマったポイント
-
kms:Decryptが無いとSSM SecureStringが取得できない - Create系はARN制限が難しい
- Describe系は
*を許可せざるを得ない
改善点
- ALB Listenerなど一部リソースはさらに制限可能
- KMSのキーポリシー側でも制御を検討
- TerraformでのIAMモジュール化
まとめ
- CloudFormationはロールなしでも動くが、実務ではロールが必須
- CreateとModify/Deleteの分離が重要
- タグベース制御で安全性を高められる
-
kms:ViaServiceにより復号経路を制御できる - IAM Access Analyzerは補助ツールとして活用する
おわりに
本記事ではCloudFormationでIAMロールを設計しましたが、
Terraformでも同様の設計は可能です。
今後はTerraformでのIAM設計にも挑戦していきたいと思います。