I'm looking for a way to refactor repeated value imports in my Cloud Formation template.
I have the following template which configures a simple app:
Parameters:
KeyName:
Description: Name of an existing EC2 KeyPair to enable SSH access into the server
Type: AWS::EC2::KeyPair::KeyName
S3StackName:
Description: Name of S3 Stack
Type: String
Resources:
EC2Instance:
Type: AWS::EC2::Instance
Metadata:
AWS::CloudFormation::Init:
config:
packages:
yum:
httpd: []
php: []
files:
/var/www/html/index.html:
source:
Fn::Sub:
- https://s3.amazonaws.com/${bucketName}/index.html
- bucketName:
Fn::ImportValue:
!Sub "${S3StackName}-s3Bucket"
/var/www/html/styles.css:
source:
Fn::Sub:
- https://s3.amazonaws.com/${bucketName}/styles.css
- bucketName:
Fn::ImportValue:
!Sub "${S3StackName}-s3Bucket"
/var/www/html/script.js:
source:
Fn::Sub:
- https://s3.amazonaws.com/${bucketName}/script.js
- bucketName:
Fn::ImportValue:
!Sub "${S3StackName}-s3Bucket"
services:
sysvinit:
httpd:
enabled: true
ensureRunning: true
AWS::CloudFormation::Authentication:
S3AccessCreds:
type: S3
roleName: !Ref EC2InstanceRole
buckets:
-
Fn::ImportValue:
!Sub "${S3StackName}-s3Bucket"
Properties:
IamInstanceProfile: !Ref EC2InstanceProfile
InstanceType: t2.micro
ImageId: ami-1853ac65
SecurityGroupIds:
- !Ref MySecurityGroup
KeyName: !Ref KeyName
UserData:
'Fn::Base64':
!Sub |
#!/bin/bash -xe
# Ensure AWS CFN Bootstrap is the latest
yum install -y aws-cfn-bootstrap
# Install the files and packages from the metadata
/opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource EC2Instance --region ${AWS::Region}
MySecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Open Ports 22 and 80
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: '22'
ToPort: '22'
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: '80'
ToPort: '80'
CidrIp: 0.0.0.0/0
Outputs:
Website:
Description: The Public DNS for the EC2 Instance
Value: !Sub 'http://${EC2Instance.PublicDnsName}'
You'll notice that there's quite a bit of repetition, particularly importing a value that has been exported from an already existing stack, e.g:
Fn::Sub:
- https://s3.amazonaws.com/${bucketName}/index.html
- bucketName:
Fn::ImportValue:
!Sub "${S3StackName}-s3Bucket"
This pattern is used a grand total of 4 times in the template that I posted above. I want to simplify this some I'm not repeating the same block of YAML over and over again.
My first thought was adding a value to the Metadata section of the template, but that didn't work, as the resources section cannot !Ref
from the metadata section.
How can I reduce the amount of repeated YAML in this template?
You can use Parameters:
Example:
Then you can reuse this block wherever you like.
Example:
For more information you can go to: