- 公開日
- 最終更新日
【CloudFormation】スタック更新したらSecurityGroupルールが消えました
この記事を共有する
はじめに
CloudFormation(以下、CFn) で スタック更新をした際に SecurityGroup(以下、SG)のルールが消える事象が発生しました。
今回はその事象の詳細と注意点を共有します。とてもマイナーな事象なのですが、何かの役に立てれば幸いです。
背景
- CFn スタックでVPCとSG、インバウンドルールを作成
- 実際使っていたものとは違いますが、以下のテンプレートを利用します
template.yml
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
Cidr:
Type: String
Default: 10.17.0.0/15
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
InstanceTenancy: default
EnableDnsSupport: 'true'
EnableDnsHostnames: 'true'
Tags:
- Key: Name
Value: tmp-VPC
SecurityGroup:
Type: "AWS::EC2::SecurityGroup"
Properties:
GroupDescription: test-sg
GroupName: test-sg
VpcId: !Ref VPC
SecurityGroupIngress:
Type: AWS::EC2::SecurityGroupIngress
Properties:
CidrIp: !Ref Cidr
GroupId: !Ref SecurityGroup
IpProtocol: "-1"
- インバウンドルールとして 10.17.0.0/15 からの通信を許可するようにパラメータを指定
- 実際の画面ではAWSが自動で変換しているため 10.16.0.0/15 となっています。10.17.0.0/15 で使用可能な IP アドレスの範囲は 10.16.0.0 - 10.17.255.255 ですので同じものとなります
実行したこと
- インバウンドルールで指定した 10.17.0.0/15 を 10.16.0.0/15 に変更
- 今回はテンプレートのパラメータの値を変更してスタック更新しています
- 実際のルールは変わらないのですが 10.16.0.0/15 とした方が混乱しないため行いました
- スタック更新が完了したことを確認
事象の詳細
実際のリソースを見てみるとインバウンドルールが消えていました。
CloudTrailを見てみるとイベント名 AuthorizeSecurityGroupIngress
にて以下のエラーが出ていました。
"errorCode": "Client.InvalidPermission.Duplicate",
"errorMessage": "the specified rule \"peer: 10.16.0.0/15, ALL, ALLOW\" already exists",
既にルールがあるというエラーですね。
CFnの置換は 新しいリソースを作成 → 旧リソース削除 の流れなのでこのようなエラーが出ています。
CFnの仕様として、現在の状態と求められる状態が見かけ上同じ(インバウンドルールが既に存在する)場合はスタック更新をそのまま継続してしまいます。そのため新しいルールが作成されないまま、旧ルールが削除されてしまったということのようです。
事象を整理すると以下のような流れになります。
- すでにあるルールと同じルールを作成しようとしたためエラー発生
- しかし既に求められている状態にはなっているためスタック更新はそのまま継続
- 新ルールが作成されないまま旧ルールが削除された
因みにこの状態になったあとに元の状態に戻すにはパラメータの値を10.17.0.0/15にしてスタック更新することで可能です。
なおパラメータを変更せず10.16.0.0/15のままスタック更新しようとすると、以下のエラーが出て更新できません。
The submitted information didn't contain changes. Submit different information to create a change set.
対策
いくつか方法はあるかと思いますが今後同じようなトラブルに合わないように、AWS::EC2::SecurityGroupの中に直接書き込むのが良いかと思います。
これであればインバウンドルールを更新する際に置換えることなく直接変更されるため事象が発生しません。
AWS::EC2::SecurityGroup Ingress - AWS CloudFormation
今回のテンプレートでは以下の様に記載すればOKです。
SecurityGroup:
Type: "AWS::EC2::SecurityGroup"
Properties:
GroupDescription: test-sg
GroupName: test-sg
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: "-1"
CidrIp: !Ref Cidr
循環参照や自己参照するときは AWS::EC2::SecurityGroupIngress
や AWS::EC2::SecurityGroupEgress
を使う必要があるのですが、CIDRを指定する場合は AWS::EC2::SecurityGroup
内に直接書いたほうがトラブルが少ないかもしれません。
まとめ
AWS::EC2::SecurityGroupIngress
や AWS::EC2::SecurityGroupEgress
でSGルールを記載している場合に実質同じCIDRを指定して更新や追加をするとルールが消えることがあります。
今回のような理由でのスタック更新は稀かと思いますが、条件分岐などでテンプレートが複雑になると意図せずこの事象が発生する可能性がありますのでご注意ください。
この記事は私が書きました
渡邉 和貴
CCoEをやってます。あと森と山に出没します。 好きなAWSサービスは CloudFormation