前回のまでのおさらい
前回のNetwork編ではベースとなるVPC、Subnet,IGW、RouteTなどを作成した。今回は次のステップとして重要なセキュリティ構成をテンプレートで構築していく。
概要
テンプレートと言われる構築環境をコード化させたファイルに記載し、スタックと呼ばれる作業を行うことでGUI上で作成した状況と同じ環境が自動的に作成される。1つのテンプレートに全ての環境を記載することも可能だが、AWSからは各レイヤー別に分けることがベストプラクティスと言われている。
今回は以下3つのLayerに分けて作成する。
- Network Layer
- Security Layer 今回はここ!
- Application Layer
クロススタック参照
各レイヤー別にテンプレートを作成し1つの環境構築を行うためには、テンプレート間の互換性が必要になる。そのためにはクロススタック参照
を使用して他レイヤーの値を参照できるようにコードに'組込関数'と呼ばれる関数を活用していく作業がポイント。
構成図
このセクションではセキュリティグループをポート別に作成し構成図のここまで進める。
Security Layer
今回はEC2,RDS,ALB用として合計3つのセキュリティグループを作成する。VPC、Subnetなどの値は前回作成したNetwork-Layerから引用するため、組込関数の!Importvalueを使用する(Network-Layerのスタック名を今回は自分のスタック名としている)
※Ref、Subなどの関数は同じテンプレート内でなければ引用することができない。
AWSTemplateFormatVersion: 2010-09-09
Description:
Creation of SecurityRayer Related
Resources:
#EC2用のセキュリティグループの作成
EC2SeculityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: EC2SeculityGroup
GroupDescription: Connection to Public ports
VpcId: !ImportValue (スタック名)-VPCID
Tags:
- Key: Name
Value: CfnSecurityGroupForWEB
# Rule
SecurityGroupIngress:
- IpProtocol: tcp # for ssh
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
- IpProtocol: tcp # for ELB(Nginx)
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
#RDS用のセキュリティグループの作成
RDSSecurityGroup:
Type: "AWS::EC2::SecurityGroup"
Properties:
VpcId: !ImportValue (スタック名)-VPCID
GroupName: RDS Security Group
GroupDescription: "-"
Tags:
- Key: Name
Value: RDS Security Group
# Rule
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 3306
ToPort: 3306
CidrIp: "0.0.0.0/0"
#ALB用のセキュリティグループの作成
ALBSecurityGroup:
Type: "AWS::EC2::SecurityGroup"
Properties:
GroupDescription: for load balancer
VpcId: !ImportValue (スタック名)-VPCID
GroupName: ALBSecurityGroup
Tags:
- Key: Name
Value: ALBSecurityGroup
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: "0.0.0.0/0"
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: "0.0.0.0/0"
OUTPuts
Application-Layerで使用するため、OutputsのExportで引用する値を設定
Outputs:
StackSgWEB:
Description: SG's for WEB ID
Value: !Ref EC2SeculityGroup
Export:
Name: !Sub "${AWS::StackName}-Sg-WEB"
StackSgRDS:
Description: SG's for RDS ID
Value: !Ref RDSSecurityGroup
Export:
Name: !Sub "${AWS::StackName}-Sg-RDS"
StackSgALB:
Value: !Ref ALBSecurityGroup
Export:
Name: !Sub "${AWS::StackName}-Sg-ALB"
Application-Layerに続く
続きはこちらから。
AWS CloudFormationのテンプレートをLayer別に作成してクロススタック参照を作ってみた。
その3 [ Application-Layer編 ]
エラー事例
テンプレートを構築していく中で、多くのエラーに遭遇。
備忘録を兼ねて事象と解決方法をメモとして残しておく。
テンプレート作成を行う段階で遭遇したエラーと解決方法[主にcfn-lintで事前に検知]
[事象1] cfn-lint E1001: Top level template section VPCEndpoint is not valid
[解決法] 作成したコードの深さの設定ミス:論理IDなどを設定するTOPの位置の深さに設定ミスがあり。
[事象2] cfn-lint E0000: Duplicate resource found "ParameterLabels"
[解決法] コード内容が重複していると検出されるエラー。1つ削除して解消させる。
[事象3] cfn-lint E2015: Default should be allowed by AllowedPattern
[解決法] インプットパラメーターで設定している値の表記ミス、正しく表記できていない。
[事象4] cfn-lint E1012: Ref CfnEC2 not found as a resource or parameter
[解決法] インプットパラメーターで設定している値の表記ミス、正しく表記できていない。
[事象5] Unresolved resource dependencies [ALBSecurityGroup] in the Outputs block of the template
[解決法] !Ref関数で指定している引用元の論ID名に相違がある。
[事象6] No export named sstack-PrivateSubnet1a found. Rollback requested by user
[解決法] クロススタックで参照している値のtypoミス
[事象7] Bucket name should not contain uppercase characters
[解決法] Paraetersに記載しているS3のバケット名に大文字を使用していたため(大文字禁止)