Skip to content

Instantly share code, notes, and snippets.

@yuta-aoyagi
Created November 14, 2018 15:29
Show Gist options
  • Save yuta-aoyagi/e3fb67df2fdc92f3edf8ad263f821e83 to your computer and use it in GitHub Desktop.
Save yuta-aoyagi/e3fb67df2fdc92f3edf8ad263f821e83 to your computer and use it in GitHub Desktop.
CloudFormation を操作できる IAM ポリシーを付与する CloudFormation テンプレート

CFnOperator.template

「CloudFormation スタックを作成・更新できる IAM ポリシーを指定されたユーザ(たち)に付与する」 CloudFormation テンプレート。 このテンプレートは「特定のスタックだけを更新できる」といった細かな制御を行わず、(下で述べる例外を除く)すべてのスタックを操作できるポリシーを定義するため、小規模な開発向けである。

使い方

  1. CloudFormation を操作する IAM ユーザ(複数可)を作成する (optional / しかし、このテンプレートが定義するポリシーはそれなりに強力(例えば S3) なので、他の一般用途のユーザとは分離することを勧める)
  2. このユーザが更新すべきでない CloudFormation スタックを決める (optional / その選択にあたっては下の「注意」節を参照)
  3. 十分に強い権限を持つユーザ(事実上は管理者)でログインする (このテンプレートが定義するポリシー自身に加えて、 IAM グループ・ロールの作成、ポリシーのアタッチなどをできる必要がある)
  4. CloudFormation コンソールからこのテンプレートを指定してスタックを作成する
  5. その際、1.で決めたユーザを Users 、2.で決めたスタックを StacksNotAllowedToOperate パラメータ(複数可)として指定する

注意

このテンプレートで権限を付与されたユーザは、このテンプレートから作られるスタック自身と StacksNotAllowedToOperate パラメータで指定されたスタックを除くすべてのスタックを更新できる。 更新できるスタックに制限があるのは、 「IAM リソースを変更できるスタック」を更新できるユーザは(事実上ほとんど確実に)自身の権限を昇格できてしまうためである。 これを問題にしないならば、単に管理者の IAM ユーザで CloudFormation をお使いなさい。

このテンプレートから作るスタックを維持する間、 「IAM リソースを変更できるスタック」のすべてが常に StacksNotAllowedToOperate パラメータに含まれることを確認せよ。

このパラメータはコンマ区切りの ARN で指定し、細かいことを気にしないなら arn:*:cloudformation:*:*:stack/<StackName>/* の形式である。 ただし、 ARN の最後の要素2文字は /* の形でスタックの ID をワイルドカードに置き換える必要がある。 さもないとそのスタックの操作が禁止されない場合がある。 (CloudFormation の undocumented な挙動)

License

MIT License. See the head of CFnOperator.template.

# Copyright 2018 yuta-aoyagi
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
Users:
Type: CommaDelimitedList
Description: Users to allow to manage CloudFormation
StacksNotAllowedToOperate:
Type: CommaDelimitedList
Description: Stacks not allowed to operate by the users in CFnOperators
Conditions:
AreNoStacksSpecified: !Equals [
!Join ["", !Ref StacksNotAllowedToOperate],
""
]
Resources:
CFnServiceRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
Effect: Allow
Principal:
Service: cloudformation.amazonaws.com
Action: "sts:AssumeRole"
Policies:
# FIXME: replace this policy document with what you want
- PolicyName: S3Bucket
PolicyDocument:
Version: "2012-10-17"
Statement:
Effect: Allow
Action:
- "s3:CreateBucket"
- "s3:DeleteBucket"
Resource: "*"
CFnOperators:
Type: "AWS::IAM::Group"
Properties:
Policies:
- PolicyName: CFnOperators
PolicyDocument:
Version: "2012-10-17"
Statement:
- Sid: CFnActions
Effect: Allow
Action:
- "cloudformation:DescribeStacks"
- "cloudformation:DescribeStackEvents"
- "cloudformation:DescribeStackResource"
- "cloudformation:DescribeStackResources"
- "cloudformation:ListStacks"
- "cloudformation:ListStackResources"
- "cloudformation:GetTemplateSummary"
- "cloudformation:ValidateTemplate"
Resource: "*"
- Effect: Allow
Action:
- "cloudformation:*ChangeSet*"
- "cloudformation:GetTemplate"
NotResource: !If [
AreNoStacksSpecified,
!Sub "arn:${AWS::Partition}:cloudformation:${AWS::Region}:${AWS::AccountId}:stack/${AWS::StackName}/*",
!Ref StacksNotAllowedToOperate
]
- Effect: Deny
Action: "cloudformation:*ChangeSet*"
Resource: !Sub "arn:${AWS::Partition}:cloudformation:${AWS::Region}:${AWS::AccountId}:stack/${AWS::StackName}/*"
- Sid: ConsoleActions
Effect: Allow
Action:
- "cloudformation:CreateUploadBucket"
- "s3:PutObject"
- "s3:ListBucket"
- "s3:GetObject"
- "s3:CreateBucket"
Resource: "*"
- Effect: Allow
Action: "iam:ListRoles"
Resource: "*"
- Effect: Allow
Action:
- "iam:GetRole"
- "iam:PassRole"
Resource: !GetAtt CFnServiceRole.Arn
- Effect: Allow
Action: "sns:ListTopics"
Resource: "*"
AllowUsersToManageCFn:
Type: "AWS::IAM::UserToGroupAddition"
Properties:
GroupName: !Ref CFnOperators
Users: !Ref Users
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment