AWS-CloudFormation

CloudFormationで動的にセキュリティグループのインバウンドを追加する

はじめに

リソースの作成をできるだけCloudformationで完結したいと思っていて
今回はセキュリティグループのインバウンドルールの追加をできるだけCloudformation内で収めるよう試してみました。

結論

今回試してみてわかったのですが、
Cloudformationではfor文等が存在しないので、完全な動的処理は難しいです。
ただしTerraform等を使用すればそのような処理も可能だと思います。
今回はCloudformationのみでの結果を紹介してみます。

作成したyamlファイルの紹介

試した際に使用したyamlファイルです。
セキュリティグループを作成するだけの内容になっています。

AWSTemplateFormatVersion: '2010-09-09'
Description: Denet Blog

Parameters:
#セキュリティグループを作成するVPC
  VPC:
    Description: SelectVPC
    Type: AWS::EC2::VPC::Id

#インバウンドに追加するIP
  DynamicIP01:
    Type: String
  DynamicIP02:
    Type: String
  DynamicIP03:
    Type: String

#条件式
Conditions:
  IsInputDynamicIP01: !Not [!Equals [!Ref DynamicIP01, '']]
  IsInputDynamicIP02: !Not [!Equals [!Ref DynamicIP02, '']]
  IsInputDynamicIP03: !Not [!Equals [!Ref DynamicIP03, '']]

Resources:
  #作成するセキュリティグループの設定
  DenetSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      VpcId: !Ref VPC
      GroupName: Blog Group
      GroupDescription: This is hoge.
      #インバウンドルールの設定
      SecurityGroupIngress:
        - !If 
          - IsInputDynamicIP01
          - CidrIp: !Ref DynamicIP01
            Description: hoge
            FromPort: "-1"
            IpProtocol: "-1"
            ToPort: "-1"
          - !Ref AWS::NoValue
        - !If 
          - IsInputDynamicIP02
          - CidrIp: !Ref DynamicIP02
            Description: huga
            FromPort: "-1"
            IpProtocol: "-1"
            ToPort: "-1"
          - !Ref AWS::NoValue
        - !If 
          - IsInputDynamicIP03
          - CidrIp: !Ref DynamicIP03
            Description: piyo
            FromPort: "-1"
            IpProtocol: "-1"
            ToPort: "-1"
          - !Ref AWS::NoValue

短縮形のif文は以下の書式で作成することができます。

!If
- 条件式
- trueの場合の処理
- falseの場合の処理

Conditions欄に記載されている !Not [!Equals [!Ref DynamicIP01, '']] ではnullチェックを行っています。
ただ文字列さえ入力されていればtrueで通ってしまうので、それだけはしてはいけません。
一応入力できるフォーマットを正規表現を用いて制限することはできると思いますが今回は飛ばします。

また条件式がfalseの場合、!Ref AWS::NoValueでリソース作成の処理をなかったことにしています。

公式ドキュメントでは

Fn::If 組み込み関数の戻り値として指定すると、対応するリソースプロパティを削除します。たとえば、スナップショット ID が指定されている場合にのみ Amazon RDS DB インスタンスのスナップショットを使用する場合は、AWS::NoValue パラメータを使用できます。UseDBSnapshot 条件が true に評価された場合は、DBSnapshotIdentifier プロパティに DBSnapshotName パラメータ値が AWS CloudFormation で使用されます。条件が false に評価された場合は、DBSnapshotIdentifier プロパティが AWS CloudFormation で削除されます。

とされています。

コードの動作確認

実際にCloudformationにてテンプレートファイルを実行して動作するか確認してみます。

パラメータを入力した場合

Cloudformationで上記テンプレートファイルを読み込み、パラメータを入力します。
今回はお試しでインバウンドに追加するIPを2つだけにして動作するか検証してみます。

スタックが無事に実行できたのでセキュリティグループを確認します。

パラメータ設定で割り当てた2つのCiderIPが反映されていて、piyoの残留思念等が残っていないので問題なく動作したと思います。

パラメータを1つも入力しなかった場合

先ほど作成したスタックを削除して今度はパラメータにIPを入力しなかった場合の処理を試します。
同様の手順で作成しセキュリティグループを確認します。

セキュリティグループ自体は作成できていますが、エラーが発生しています。
処理的にはセキュリティグループを作成後のインバウンドルールの作成の処理で1つもtrueが通らずに処理が終了したのでハリボテになってしまっており、結果として歪なセキュリティグループが完成してしまいました。
対策としては、テンプレートのセキュリティグループ作成の箇所に分岐処理を挟むか
スタックを実行仕様と思っている段階でインバウンドルールを追加することは決まっているので1つめのインバウンドルールの分岐処理を抜けば良いかと思います。

おわりに

Cloudformation単体では限界があると思うので今後はそこから派生して色々試せればと思いました。
何かしらの参考になれば幸いです。

返信を残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA