🔖

[CloudFormation] リソースの作成を選択制にしてみる

2021/08/10に公開

やりたいこと

1.リソースを作成有無を選択できるようにする

2.リソース内のプロパティの有無を選択できるようにする

実装方法

1.Conditions セクションを使用する
 → リソース毎に作成するかしないかを選択できるようにする

2.組み込み関数と疑似パラメータを使用する
 → 組み込み関数の !If と疑似パラメータの AWS::NoValue を使用し、
  Conditions と組み合わせることでリソース内、プロパティの有無を選択できるようにする

使用するテンプレート

AWSTemplateFormatVersion: 2010-09-09

Parameters:
  ImageId:
    Type: String
  PrivateSubnetId:
    Type: String
+  NeedSSMAccess:
+    Type: String
+    AllowedValues: [true, false]

+Conditions:
+  NeedSSM: 
+    !Equals [true, !Ref NeedSSMAccess]

Resources:
  EC2Role:
+    Condition: NeedSSM
    Type: AWS::IAM::Role
    Properties:
      Path: /
      RoleName: !Sub ${AWS::StackName}-EC2Role
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - ec2.amazonaws.com
            Action:
              - sts:AssumeRole
      MaxSessionDuration: 3600
      ManagedPolicyArns: 
        - arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM

  InstanceProfile:
+    Condition: NeedSSM
    Type: AWS::IAM::InstanceProfile
    Properties:
      Path: /
      Roles:
        - !Ref EC2Role

  EC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref ImageId
      InstanceType: t2.micro
+      IamInstanceProfile: !If
+        - NeedSSM
+        - !Ref InstanceProfile
+        - !Ref AWS::NoValue
      SubnetId: !Ref PrivateSubnetId
      Tags:
        - Key: Name
          Value: !Sub ${AWS::StackName}-EC2

※ Parameters セクションの値はハードコードしても問題ありません
 このテンプレートではテンプレートの汎用性のために Paramaters セクションにしてます

上記テンプレートでは SSM Session Manager で EC2 インスタンスに対して
アクセス出来るようにするかをユーザが選択することができるようになっています

緑でハイライトされた部分が今回のテーマの箇所のため下記で説明を記載します
その他の説明は[CloudFormation] SSM アクセスができる EC2 インスタンスを作成を参照ください

各設定の説明

Conditions

条件によってリソースの作成有無を制御したいときに使用する
組み込み関数を利用し条件判定をし、true または false を返す

参考:https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/conditions-section-structure.html

組み込み関数 !If

Conditions を参照し、true または false で異なる値を返すことができる
構文: !If [Conditions Name, True Value, False Value]

参考:https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-conditions.html#intrinsic-function-reference-conditions-if

疑似パラメータ AWS::NoValue

!If と組み合わせて使用することでプロパティを定義しないという設定が行える

参考:https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/pseudo-parameter-reference.html

テンプレートの説明

Parameters:
  NeedSSMAccess:
    Type: String
    AllowedValues: [true, false]

Conditions:
  NeedSSM: 
    !Equals [true, !Ref NeedSSMAccess]
    
Resources:
  EC2Role:
    Condition: NeedSSM
~~ 省略 ~~
  InstanceProfile:
    Condition: NeedSSM
~~ 省略 ~~

・Parameters セクション:ユーザが SSM でのアクセスを使用するかを選択する
 → 使用する場合、NeedSSMAccess のパラメータで true を選択

・Conditions セクション:組み込み関数 !Equals で値を判定し NeedSSM に変数を代入する
 → 上記 NeedSSMAccess のパラメータが true の場合、true を返す

・Resources セクション:Condition プロパティが true の場合、リソースを作成する
 → NeedSSM の値を確認し true の場合、IAM ロールとインスタンスプロファイルを作成する

IamInstanceProfile: !If
  - NeedSSM
  - !Ref InstanceProfile
  - !Ref AWS::NoValue

組み込み関数 !If を使用し、NeedSSM が true の場合、インスタンスプロファイル名を使用
NeedSSM が false の場合、疑似パラメータ AWS::NoValue を使用し
IamInstanceProfile プロパティを未定義な状態にする

Discussion