create sub stack vpc.yml
$ cat vpc.yml
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
CidrBlock:
Type: String
Default: "10.0.0.0/16"
NameTag :
Type: String
Default: "nested stack"
Resources:
VPC:
Properties:
CidrBlock: !Ref CidrBlock
Tags:
- Key: Name
Value: !Ref NameTag
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: !Ref NameTag
AttachGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId:
Ref: VPC
InternetGatewayId:
Ref: InternetGateway
Outputs:
VpcId:
Value: !Ref VPC
IgwId:
Value: !Ref InternetGateway
aws cloudformation validate-template --template-body file://vpc.yml
create another sub stack subnet.yml
$ cat subnet.yml [5/1860]
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
NameTag:
Type: String
Default: "subnetnesting"
VPC:
Type: AWS::EC2::VPC::Id
CidrBlock1:
Type: String
Default: "10.0.0.0/24"
CidrBlock2:
Type: String
Default: "10.0.1.0/24"
Resources:
Subnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: !Ref CidrBlock1
AvailabilityZone:
Fn::Select:
- '0'
- Fn::GetAZs:
Ref: AWS::Region
Subnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: !Ref CidrBlock2
AvailabilityZone:
Fn::Select:
- '1'
- Fn::GetAZs:
Ref: AWS::Region
Outputs:
SubnetId1:
Value: !Ref Subnet1
SubnetAz1:
Value: !GetAtt Subnet1.AvailabilityZone
SubnetId2:
Value: !Ref Subnet2
SubnetAz2:
Value: !GetAtt Subnet2.AvailabilityZone
aws cloudformation validate-template --template-body file://subnet.yml
create parent stack parent.yml
$ cat parent.yml
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
NameTag:
Default: nested stack test
Type: String
CidrBlock:
Default: 10.1.0.0/16
Type: String
CidrBlock1:
Default: 10.1.0.0/24
Type: String
CidrBlock2:
Default: 10.1.1.0/24
Type: String
Resources:
VPC:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: vpc.yml
Parameters:
NameTag : !Ref NameTag
CidrBlock: !Ref CidrBlock
SUBNET:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: subnet.yml
Parameters:
NameTag : !Ref NameTag
VPC: !GetAtt VPC.Outputs.VpcId
CidrBlock1: !Ref CidrBlock1
CidrBlock2: !Ref CidrBlock2
Outputs:
VpcId:
Value: !GetAtt VPC.Outputs.VpcId
SubnetId1:
Value: !GetAtt SUBNET.Outputs.SubnetId1
SubnetId2:
Value: !GetAtt SUBNET.Outputs.SubnetId2
aws cloudformation validate-template --template-body file://parent.yml
create or update stack
aws cloudformation package --template-file parent.yml --s3-bucket your-s3bucket-name --output-template-file parent_packaged.yml
aws cloudformation deploy --template-file parent_packaged.yml --stack-name nestedstack --tags Name=testnestedstack
confirm
$ aws cloudformation describe-stacks --query 'Stacks[?Tags[?Key == `Name` && Value == `testnestedstack`]]' | less
$ aws cloudformation describe-stacks --query 'Stacks[?Tags[?Key == `Name` && Value == `testnestedstack`]].StackName' | jq -r .[] | while read stackname; do
> aws cloudformation describe-stack-events --stack-name ${stackname}
> done | less
$ aws cloudformation describe-stacks --query 'Stacks[?Tags[?Key == `Name` && Value == `testnestedstack`]].StackName' | jq -r .[] | while read stackname; do
> aws cloudformation describe-stack-resources --stack-name ${stackname}
> done | less
delete stack
aws cloudformation delete-stack --stack-name nestedstack