Security Groupはファイアウォールの役割を持つリソースです。新しい通信を許可・拒否する場合、Security Groupの内容を更新する必要があります。
これをCloudFormationで更新する場合、Security GroupのIDが新しく採番されてしまわないか、事前に確認しておく必要があります。
理由は、Security GroupがEC2などの外部リソースから参照されているためです。もしIDが変わってしまうと、参照元のリソースには古いIDのSecurity Groupが設定されたままになり、意図した通信許可・拒否が適用されなくなってしまいます。最悪の場合、通信が止まってしまう可能性があります。
検証内容
今回は、FTPの通信を許可する行を1行追記し、更新前後でIDが変わるかを検証します。
あわせて注目したいのが `UpdateReplacePolicy: Delete` です。これは、更新によってリソースが置き換えられる際に、旧世代のリソースを残さず削除する設定です。
Ec2SecurityGroup: # Security Group の論理名
Type: AWS::EC2::SecurityGroup # Security Group リソースタイプ
DeletionPolicy: Retain # スタック/リソース削除時もSecurity Groupを残す
UpdateReplacePolicy: Delete # 更新で置き換えが発生した場合、旧Security Groupは削除する
Properties: # Security Group のプロパティ
GroupDescription: !Sub "${Env} Ec2 ingress security group" # コンソールに表示される説明
VpcId: # このSecurity Groupが属するVPC
Fn::ImportValue: !Sub "${Env}-VPCId" # ベースVPCスタックからインポートしたVPC ID
SecurityGroupIngress: # インバウンドルール
- IpProtocol: tcp # HTTP
FromPort: 80
ToPort: 80
CidrIp: 10.0.0.0/8
- IpProtocol: tcp # RDP
FromPort: 3389
ToPort: 3389
CidrIp: 10.0.0.0/8
- IpProtocol: tcp # SSH
FromPort: 22
ToPort: 22
CidrIp: 10.0.0.0/8
- IpProtocol: tcp # FTP(今回追記した行)
FromPort: 21
ToPort: 21
CidrIp: 10.0.0.0/8変更セットで比較する
更新したYAMLをそのまま適用するのではなく、CloudFormationの変更セット機能を使って、現行のスタックと新しいテンプレートの差分を確認します。内容に問題がなければ、変更セットを適用します。

検証結果
適用後、Security GroupのIDが変わっているかを確認します。
結果として、IDは変わっていませんでした。以下のコマンドでIDを比較しました。
~ $ aws ec2 describe-security-groups --filters Name=vpc-id,Values=vpc-097f3e806c40d9476 --query "SecurityGroups[].[GroupId,GroupName]" --output table
--------------------------------------------------------------------------------------------------------------
| DescribeSecurityGroups |
+----------------------+-------------------------------------------------------------------------------------+
| sg-023b7f9a503123456| xxxxxxxxx-myapp-cmn-ec2-sg-Ec2SecurityGroup-FLmpKRsbmFFk |
+----------------------+-------------------------------------------------------------------------------------+まとめ
`SecurityGroupIngress` にルールを1行追加するだけの更新であれば、Security Group自体は置き換えられず、IDはそのまま維持されることが確認できました。既存リソースからの参照を壊さずに通信ルールを更新できるため、安心して運用に組み込める変更と言えそうです。