CloudFormation (CFN) is infrastructure as a code service of AWS. You just tell CFN your desired state of resources and it creates them in order while resolving dependencies. You mention these resources in a file called as template which can be written in YAML or JSON. YAML being bit more user readable, is widely used now. YAML is great but you have to be aware of its indentation.
Following is a step by step troubleshooting and validation of a simple CFN template by using aws cli from windows 10 command prompt.
Step 1: Create your template file. I am using ec2.yaml which just creates an EC2 instance and a security group with some parameters and outputs.
#####################################################################################################
# Template : Use to deploy simple T2.MICRO EC2 Instance with a security group
#
# Author : Fahd Mirza
#
# Created on : 23rd March, 2019
#
#####################################################################################################
---
AWSTemplateFormatVersion: "2010-09-09"
Description: Deploy EC2 Instance with a security group
######################################################################################################
Parameters:
######################################################################################################
InstanceType:
Type: String
Default: t2.micro
AllowedValues:
- t2.micro
- t2.2xlarge
MyRSAKey:
Type: String
Description: Supply your RSA Key Name
Mappings:
RegionMap:
us-east-1:
AMI: ami-1853ac65
us-west-1:
AMI: ami-bf5540df
eu-west-1:
AMI: ami-3bfab942
ap-southeast-1:
AMI: ami-e2adf99e
ap-southeast-2:
AMI: ami-43874721
######################################################################################################
Resources:
######################################################################################################
MySecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow SSH to EC2 Bastion Host
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: '22'
ToPort: '22'
CidrIp: 0.0.0.0/0
Tags:
- Key: Name
Value: MyBastionSG112
MyEc2Instance:
Type: AWS::EC2::Instance
Metadata:
AWS::CloudFormation::Init:
config:
files:
/etc/cfn/cfn-hup.conf:
content: !Sub |
[main]
stack=${AWS::StackId}
region=${AWS::Region}
interval=1
mode: '000744'
owner: root
group: root
/etc/cfn/hooks.d/cfn-auto-reloader.conf:
content: !Sub |
[cfn-auto-reloader-hook]
triggers=post.update
path=Resources.MyEc2Instance.Metadata.AWS::CloudFormation::Init
action=/opt/aws/bin/cfn-init -v --stack ${AWS::StackId} --region ${AWS::Region} --resource MyEc2Instance
runas=root
~/hello1.txt:
content: !Sub |
hello world, I am from files section of CFN Init metadata.
commands:
RunA:
command: cat "hello world, I am from command section of CFN Init metadata." > ~/hello.txt
ignoreErrors: "true"
services:
sysvinit:
cfn-hup:
enabled: true
ensureRunning: true
files: [/etc/cfn/cfn-hup.conf, /etc/cfn/hooks.d/cfn-auto-reloader.conf]
Properties:
Tags:
- Key: Name
Value: !Ref "AWS::StackName"
ImageId:
Fn::FindInMap:
- RegionMap
- !Ref AWS::Region
- AMI
InstanceType:
Ref: InstanceType
KeyName:
Ref: MyRSAKey
UserData:
Fn::Base64: !Sub |
#!/bin/bash -xe
yum install -y aws-cfn-bootstrap
chkconfig --add cfn-hup
/opt/aws/bin/cfn-init -v --stack ${AWS::StackId} --resource MyEc2Instance --region ${AWS::Region}
/opt/aws/bin/cfn-signal -e 0 --stack ${AWS::StackName} --resource MyEc2Instance --region ${AWS::Region}
CreationPolicy:
ResourceSignal:
Timeout: "PT15M"
######################################################################################################
Outputs:
######################################################################################################
MyEC2InstancePublicIP:
Description: My EC2 Instance Public IP
Value: !GetAtt MyEc2Instance.PublicIp
MyEC2InstanceID:
Description: My EC2 Instance ID
Value: !Ref MyEc2Instance
MyEC2SecGroup:
Description: My EC2 Security Group
Value: !Ref MySecurityGroup
Step 2: When I first ran the validation on this template, it gave me error about its indentation like following. I fixed the indentation by using simple editor. You can also use any online editor or Visual code studio.
C:\Users\mirza\Desktop\Cloud\AWS\Cloud\CloudFormation\templates>dir
Volume in drive C is Windows
Volume Serial Number is 5285-4635
Directory of C:\Users\mirza\Desktop\Cloud\AWS\Cloud\CloudFormation\templates
23/03/2019 12:54 PM .
23/03/2019 12:54 PM ..
23/03/2019 12:49 PM 4,360 ec2.yaml
23/03/2019 12:54 PM 2,461 my.yaml
2 File(s) 6,821 bytes
2 Dir(s) 807,032,090,624 bytes free
C:\Users\mirza\Desktop\Cloud\AWS\Cloud\CloudFormation\templates>aws cloudformation validate-template --template-body file://my.yaml
An error occurred (ValidationError) when calling the ValidateTemplate operation: [/Parameters/Mappings] 'null' values are not allowed in templates
C:\Users\mirza\Desktop\Cloud\AWS\Cloud\CloudFormation\templates>
C:\Users\mirza\Desktop\Cloud\AWS\Cloud\CloudFormation\templates>
C:\Users\mirza\Desktop\Cloud\AWS\Cloud\CloudFormation\templates>aws cloudformation validate-template --template-body file://ec2.yaml
An error occurred (ValidationError) when calling the ValidateTemplate operation: Invalid template parameter property 'RegionMap'
C:\Users\mirza\Desktop\Cloud\AWS\Cloud\CloudFormation\templates>aws cloudformation validate-template --template-body file://ec2.yaml
Step 3: Then I had declared a resource in resources section but it wasn't present in the Parameters section. So I removed it from parameters.
An error occurred (ValidationError) when calling the ValidateTemplate operation: Template format error: Unresolved resource dependencies [MyVPCId] in the Resources block of the template
Step 4: Now it works like a charm.
C:\Users\mirza\Desktop\Cloud\AWS\Cloud\CloudFormation\templates>
C:\Users\mirza\Desktop\Cloud\AWS\Cloud\CloudFormation\templates>
C:\Users\mirza\Desktop\Cloud\AWS\Cloud\CloudFormation\templates>
C:\Users\mirza\Desktop\Cloud\AWS\Cloud\CloudFormation\templates>aws cloudformation validate-template --template-body file://ec2.yaml
Deploy EC2 Instance with a security group
PARAMETERS Supply your RSA Key Name False MyRSAKey
PARAMETERS t2.micro False InstanceType
C:\Users\mirza\Desktop\Cloud\AWS\Cloud\CloudFormation\templates>
Following is a step by step troubleshooting and validation of a simple CFN template by using aws cli from windows 10 command prompt.
Step 1: Create your template file. I am using ec2.yaml which just creates an EC2 instance and a security group with some parameters and outputs.
#####################################################################################################
# Template : Use to deploy simple T2.MICRO EC2 Instance with a security group
#
# Author : Fahd Mirza
#
# Created on : 23rd March, 2019
#
#####################################################################################################
---
AWSTemplateFormatVersion: "2010-09-09"
Description: Deploy EC2 Instance with a security group
######################################################################################################
Parameters:
######################################################################################################
InstanceType:
Type: String
Default: t2.micro
AllowedValues:
- t2.micro
- t2.2xlarge
MyRSAKey:
Type: String
Description: Supply your RSA Key Name
Mappings:
RegionMap:
us-east-1:
AMI: ami-1853ac65
us-west-1:
AMI: ami-bf5540df
eu-west-1:
AMI: ami-3bfab942
ap-southeast-1:
AMI: ami-e2adf99e
ap-southeast-2:
AMI: ami-43874721
######################################################################################################
Resources:
######################################################################################################
MySecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow SSH to EC2 Bastion Host
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: '22'
ToPort: '22'
CidrIp: 0.0.0.0/0
Tags:
- Key: Name
Value: MyBastionSG112
MyEc2Instance:
Type: AWS::EC2::Instance
Metadata:
AWS::CloudFormation::Init:
config:
files:
/etc/cfn/cfn-hup.conf:
content: !Sub |
[main]
stack=${AWS::StackId}
region=${AWS::Region}
interval=1
mode: '000744'
owner: root
group: root
/etc/cfn/hooks.d/cfn-auto-reloader.conf:
content: !Sub |
[cfn-auto-reloader-hook]
triggers=post.update
path=Resources.MyEc2Instance.Metadata.AWS::CloudFormation::Init
action=/opt/aws/bin/cfn-init -v --stack ${AWS::StackId} --region ${AWS::Region} --resource MyEc2Instance
runas=root
~/hello1.txt:
content: !Sub |
hello world, I am from files section of CFN Init metadata.
commands:
RunA:
command: cat "hello world, I am from command section of CFN Init metadata." > ~/hello.txt
ignoreErrors: "true"
services:
sysvinit:
cfn-hup:
enabled: true
ensureRunning: true
files: [/etc/cfn/cfn-hup.conf, /etc/cfn/hooks.d/cfn-auto-reloader.conf]
Properties:
Tags:
- Key: Name
Value: !Ref "AWS::StackName"
ImageId:
Fn::FindInMap:
- RegionMap
- !Ref AWS::Region
- AMI
InstanceType:
Ref: InstanceType
KeyName:
Ref: MyRSAKey
UserData:
Fn::Base64: !Sub |
#!/bin/bash -xe
yum install -y aws-cfn-bootstrap
chkconfig --add cfn-hup
/opt/aws/bin/cfn-init -v --stack ${AWS::StackId} --resource MyEc2Instance --region ${AWS::Region}
/opt/aws/bin/cfn-signal -e 0 --stack ${AWS::StackName} --resource MyEc2Instance --region ${AWS::Region}
CreationPolicy:
ResourceSignal:
Timeout: "PT15M"
######################################################################################################
Outputs:
######################################################################################################
MyEC2InstancePublicIP:
Description: My EC2 Instance Public IP
Value: !GetAtt MyEc2Instance.PublicIp
MyEC2InstanceID:
Description: My EC2 Instance ID
Value: !Ref MyEc2Instance
MyEC2SecGroup:
Description: My EC2 Security Group
Value: !Ref MySecurityGroup
Step 2: When I first ran the validation on this template, it gave me error about its indentation like following. I fixed the indentation by using simple editor. You can also use any online editor or Visual code studio.
C:\Users\mirza\Desktop\Cloud\AWS\Cloud\CloudFormation\templates>dir
Volume in drive C is Windows
Volume Serial Number is 5285-4635
Directory of C:\Users\mirza\Desktop\Cloud\AWS\Cloud\CloudFormation\templates
23/03/2019 12:54 PM
23/03/2019 12:54 PM
23/03/2019 12:49 PM 4,360 ec2.yaml
23/03/2019 12:54 PM 2,461 my.yaml
2 File(s) 6,821 bytes
2 Dir(s) 807,032,090,624 bytes free
C:\Users\mirza\Desktop\Cloud\AWS\Cloud\CloudFormation\templates>aws cloudformation validate-template --template-body file://my.yaml
An error occurred (ValidationError) when calling the ValidateTemplate operation: [/Parameters/Mappings] 'null' values are not allowed in templates
C:\Users\mirza\Desktop\Cloud\AWS\Cloud\CloudFormation\templates>
C:\Users\mirza\Desktop\Cloud\AWS\Cloud\CloudFormation\templates>
C:\Users\mirza\Desktop\Cloud\AWS\Cloud\CloudFormation\templates>aws cloudformation validate-template --template-body file://ec2.yaml
An error occurred (ValidationError) when calling the ValidateTemplate operation: Invalid template parameter property 'RegionMap'
C:\Users\mirza\Desktop\Cloud\AWS\Cloud\CloudFormation\templates>aws cloudformation validate-template --template-body file://ec2.yaml
Step 3: Then I had declared a resource in resources section but it wasn't present in the Parameters section. So I removed it from parameters.
An error occurred (ValidationError) when calling the ValidateTemplate operation: Template format error: Unresolved resource dependencies [MyVPCId] in the Resources block of the template
Step 4: Now it works like a charm.
C:\Users\mirza\Desktop\Cloud\AWS\Cloud\CloudFormation\templates>
C:\Users\mirza\Desktop\Cloud\AWS\Cloud\CloudFormation\templates>
C:\Users\mirza\Desktop\Cloud\AWS\Cloud\CloudFormation\templates>
C:\Users\mirza\Desktop\Cloud\AWS\Cloud\CloudFormation\templates>aws cloudformation validate-template --template-body file://ec2.yaml
Deploy EC2 Instance with a security group
PARAMETERS Supply your RSA Key Name False MyRSAKey
PARAMETERS t2.micro False InstanceType
C:\Users\mirza\Desktop\Cloud\AWS\Cloud\CloudFormation\templates>
No comments:
Post a Comment