7
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【AWS】CloudFormationでIAM RoleのPolicy定義に変数を用いる【小ネタ】

Last updated at Posted at 2019-10-08

はじめに

CloudFormationのResourceのPropertyの指定において、Typeが「Json」のものがいくつかあります。
IAM Roleの「AssumeRolePolicyDocument」や「Policies」などがこれに該当します。

しかしながら、IAM Entityに対して指定するPolicyドキュメントでCFnの関数を使いたいことが多く(PolicyドキュメントのResourceに、他のCFn Stackで作成したリソースを指定する、など)、JSONでは指定が難しいことも多々あります。

Typeが「Json」となっているProperyには、同等の内容をyamlとして定義して渡すことも可能です。
この仕様を利用して、PolicyドキュメントでCFn関数を指定することが可能です。

AWS::IAM::Role - AWS CloudFormation
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html#cfn-iam-role-assumerolepolicydocument
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html#cfn-iam-role-policies

AWS::IAM::Role Policy - AWS CloudFormation
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iam-policy.html#cfn-iam-policies-policydocument

IAM Role定義サンプル

以下の2つのCloudFormationテンプレート定義は等価です。

JSON形式でPolicyドキュメントを指定する

Resources:
  # AWS::IAM::Role - AWS CloudFormation
  # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html
  SampleAdminRole:
    Type: AWS::IAM::Role
    Properties: 
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
        {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Principal": {
                "AWS": "arn:aws:iam::123456789012:root"
              },
              "Action": "sts:AssumeRole"
            }
          ]
        }
      Description:
        Describe what you want
      Policies: 
        - PolicyName: AllowAllActions
          PolicyDocument:
            {
                "Version": "2012-10-17",
                "Statement": [
                    {
                        "Effect": "Allow",
                        "Action": "*",
                        "Resource": "*"
                    }
                ]
            }

yaml形式でPolicyドキュメントを指定する


AWSTemplateFormatVersion: '2010-09-09'
Description: Describe what you want.

Parameters:
  # Define what you want.

Resources:
  # AWS::IAM::Role - AWS CloudFormation
  # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html
  SampleAdminRole:
    Type: AWS::IAM::Role
    Properties: 
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: "Allow"
            Principal:
              AWS: "arn:aws:iam::123456789012:root"
            Action: "sts:AssumeRole"
      Description:
        Describe what you want
      Policies: 
        - PolicyName: AllowAllActions
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: "Allow"
                Action: "*"
                Resource: "*"

AssumeRolePolicyDocumentのPrincipalでCFn関数を使う

上記のように、TypeとしてJsonが指定されているPropertyをyamlに変換したことで、CFn関数を利用しやすくなります。
先ほどの例ですと、AssumeRoleする主体となるPrincipalのAWSアカウントIDを、Parameterとして渡したくなると思います。
この場合、以下のように!Sub関数を利用することが可能です。

cfn-iam-role-policy-with-function.yml
AWSTemplateFormatVersion: '2010-09-09'
Description: Describe what you want.

Parameters:
  # Define what you want.
  PrincipalAwsAccountId:
    Description:
      An AWS account id will be a principal to invoke the AssumeRole API.
    Type: Number
    Default: 123456789012

Resources:
  # AWS::IAM::Role - AWS CloudFormation
  # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html
  SampleAdminRole:
    Type: AWS::IAM::Role
    Properties: 
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: "Allow"
            Principal:
              AWS: !Sub arn:aws:iam::${PrincipalAwsAccountId}:root
            Action: "sts:AssumeRole"
      Description:
        Describe what you want
      Policies: 
        - PolicyName: AllowAllActions
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: "Allow"
                Action: "*"
                Resource: "*"

Fn::Sub - AWS CloudFormation
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-sub.html

CFnスタック作成時に、下記のようにPrincipalAwsAccountIdパラメータを指定することで、任意のAWSアカウントIDに対応することができるようになります。

$ aws cloudformation create-stack \
  --stack-name iam-role-policy-with-function \
  --template-body file://cfn-iam-role-policy-with-function.yml \
  --capabilities CAPABILITY_NAMED_IAM \
  --parameters ParameterKey=PrincipalAwsAccountId,ParameterValue=987654321098,UsePreviousValue=true

おわりに

CDKが出たので、今後はCDKを使うことでこのような用途はProgrammaticに解決できるようになると思います。
しかしながら、いきなり全て移行することは難しいため、このようなテクニックはまだ暫く必要になるでしょう。

7
7
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
7
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?