A Handy Guide to AWS CloudFormation Snippets
AWS CloudFormation is a robust service that allows users to model and set up their Amazon Web Services resources. This article provides handy CloudFormation snippets for quick reference.
Table of Contents
EC2:
Launch an EC2 Instance with an IAM Role:
AWSTemplateFormatVersion: 2010-09-09
Parameters:
VpcId:
Type: AWS::EC2::VPC::Id
Description: Select a VPC for the instance
SubnetId:
Type: AWS::EC2::Subnet::Id
Description: Select a subnet for the instance
ImageId:
Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
Description: ID of the AMI to use for the instance
Default: Default: '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2'
InstanceType:
Type: String
Description: EC2 instance type
Default: t2.medium
AllowedValues:
- t2.micro
- t2.small
- t2.medium
KeyName:
Type: AWS::EC2::KeyPair::KeyName
Description: Name of an existing EC2 KeyPair to enable SSH access to the instance
ConstraintDescription: Must be the name of an existing EC2 KeyPair
AllowedIp:
Type: String
Description: Your public IP address
Default: 10.0.0.0/8
Resources:
EC2Instance:
Type: AWS::EC2::Instance
Properties:
ImageId: !Ref ImageId
InstanceType: !Ref InstanceType
KeyName: !Ref KeyName
SubnetId: !Ref SubnetId
SecurityGroupIds:
- !Ref InstanceSecurityGroup
IamInstanceProfile: !Ref EC2InstanceProfile
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}-ec2"
UserData:
Fn::Base64:
!Sub |
#!/bin/bash
yum update -y
#pip3 install boto3
#pip3 install requests
EC2InstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
Path: "/"
Roles:
- !Ref EC2InstanceRole
EC2InstanceRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub "${AWS::StackName}-role"
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service:
- ec2.amazonaws.com
Action:
- sts:AssumeRole
Path: "/"
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
Policies:
- PolicyName: EC2InstancePolicy
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource: "*"
InstanceSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: "Enable SSH access and HTTP access on the inbound port"
VpcId: !Ref VpcId
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: !Ref AllowedIp
IAM:
Basic Role with Policy:
AWSTemplateFormatVersion: 2010-09-09
Resources:
MyRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub "${AWS::StackName}-role"
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service:
- ec2.amazonaws.com
Action:
- sts:AssumeRole
Path: "/"
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
Policies:
- PolicyName: EC2InstancePolicy
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource: "*"
S3:
Create an S3 Bucket with SSE:
AWSTemplateFormatVersion: 2010-09-09
Parameters:
DeliveryBucketName:
Description: 'Bucket name'
Type: String
Default: 'my-bucket'
Resources:
MyBucket:
Type: "AWS::S3::Bucket"
Properties:
BucketName: !Ref BucketName
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
Lambda:
Lambda With Inline Code:
AWSTemplateFormatVersion: 2010-09-09
Parameters:
Environment:
Type: String
Default: 'Development'
AllowedValues:
- 'Development'
- 'Production'
Resources:
LambdaRole:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- 'sts:AssumeRole'
Path: /
Policies:
- PolicyName: root
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- logs:*
Resource: '*'
LambdaFunction:
Type: AWS::Lambda::Function
Properties:
Role: !GetAtt LambdaRole.Arn
Runtime: python3.9
Timeout: 900
MemorySize: 128
Handler: index.lambda_handler
Code:
ZipFile: |
def lambda_handler(event, context):
return "Hello world!"
Environment:
Variables:
Environment: !Ref Environment
Tags:
- Key: Lambda
Value: MyLambdaFunction
- Key: Environment
Value: !Ref Environment
Kinesis:
Kinesis Data Stream:
AWSTemplateFormatVersion: 2010-09-09
Parameters:
KinesisStreamName:
Description: This will be used to name the Kinesis DataStream
Type: String
Default: 'data-stream'
KinesisStreamRetensionHours:
Description: This will be used to set the retension hours
Type: Number
Default: 24
KinesisStreamShardCount:
Description: This will be used to set the shard count
Type: Number
Default: 1
Environment:
Type: String
Default: 'Development'
AllowedValues:
- 'Development'
- 'Production'
Resources:
KinesisDataStream:
Type: AWS::Kinesis::Stream
Properties:
Name: !Sub ${AWS::StackName}-${KinesisStreamName}
RetentionPeriodHours: !Ref KinesisStreamRetensionHours
ShardCount: !Ref KinesisStreamShardCount
StreamEncryption:
EncryptionType: KMS
KeyId: alias/aws/kinesis
Tags:
- Key: Environment
Value: !Ref Environment
Kinesis Firehose with Direct Put:
AWSTemplateFormatVersion: 2010-09-09
Parameters:
DeliveryStreamName:
Description: This will be used to name the Kinesis delivery stream
Type: String
Default: 'delivery-stream'
DeliveryBucketName:
Description: 'Bucket where kinesis delivery stream will store data. It should be a name, not Arn'
Type: String
Default: 'delivery-data'
Resources:
KinesisDeliveryStreamIAMRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Sid: ''
Effect: Allow
Principal:
Service: firehose.amazonaws.com
Action: sts:AssumeRole
KinesisDeliveryStreamIAMPolicy:
Type: AWS::IAM::Policy
Properties:
PolicyName: !Sub ${AWS::StackName}-${DeliveryStreamName}
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- s3:PutObject
Resource: !Join [ '', ['arn:aws:s3:::', !Ref DeliveryBucketName, '/*'] ]
Roles:
- !Ref KinesisDeliveryStreamIAMRole
KinesisDeliveryStreamDirectPut:
Type: AWS::KinesisFirehose::DeliveryStream
Properties:
DeliveryStreamName: !Ref DeliveryStreamName
DeliveryStreamType: DirectPut
ExtendedS3DestinationConfiguration:
BucketARN: !Join [ '', ['arn:aws:s3:::', !Ref DeliveryBucketName] ]
BufferingHints:
SizeInMBs: 128
IntervalInSeconds: 900
CompressionFormat: UNCOMPRESSED
ErrorOutputPrefix: table/error/!{firehose:error-output-type}/dt=!{timestamp:yyyy'-'MM'-'dd}/h=!{timestamp:HH}/
Prefix: YYYY=!{partitionKeyFromQuery:YYYY}/MM=!{partitionKeyFromQuery:MM}//DD=!{partitionKeyFromQuery:DD}/HH=!{partitionKeyFromQuery:HH}/REGION=!{partitionKeyFromQuery:REGION}/SITEID=!{partitionKeyFromQuery:SITEID}/
RoleARN: !GetAtt KinesisDeliveryStreamIAMRole.Arn
DynamicPartitioningConfiguration:
Enabled: true
RetryOptions:
DurationInSeconds: 300
ProcessingConfiguration:
Enabled: true
Processors:
- Type: MetadataExtraction
Parameters:
- ParameterName: MetadataExtractionQuery
ParameterValue: '{YYYY : (.ts/1000) | strftime("%Y"), MM : (.ts/1000)
| strftime("%m"), DD : (.ts/1000) | strftime("%d"), HH: (.ts/1000)
| strftime("%H")}'
- ParameterName: JsonParsingEngine
ParameterValue: JQ-1.6
- Type: AppendDelimiterToRecord
Parameters:
- ParameterName: Delimiter
ParameterValue: "\\n"
Kinesis Firehose with Kinesis Stream as Source:
AWSTemplateFormatVersion: 2010-09-09
Parameters:
DeliveryStreamName:
Description: This will be used to name the Kinesis delivery stream
Type: String
Default: 'delivery-stream'
DeliveryBucketName:
Description: 'Bucket where kinesis delivery stream will store data. It should be a name, not Arn'
Type: String
Default: 'delivery-data'
KinesisDataStream:
Description: Kinesis data stream ARN where from data will be read'
Resources:
KinesisDeliveryStreamIAMRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Sid: ''
Effect: Allow
Principal:
Service: firehose.amazonaws.com
Action: sts:AssumeRole
KinesisDeliveryStreamIAMPolicy:
Type: AWS::IAM::Policy
Properties:
PolicyName: !Sub ${AWS::StackName}-${DeliveryStreamName}
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- s3:PutObject
Resource: !Join [ '', ['arn:aws:s3:::', !Ref DeliveryBucketName, '/*'] ]
- Effect: Allow
Action:
- kinesis:DescribeStream
- kinesis:GetShardIterator
- kinesis:GetRecords
Resource:
- !GetAtt KinesisDataStream.Arn
Roles:
- !Ref KinesisDeliveryStreamIAMRole
KinesisDeliveryStreamWithSource:
Type: AWS::KinesisFirehose::DeliveryStream
Properties:
DeliveryStreamName: !Ref DeliveryStreamName
DeliveryStreamType: KinesisStreamAsSource
KinesisStreamSourceConfiguration:
KinesisStreamARN: !GetAtt KinesisDataStream.Arn
RoleARN: !GetAtt KinesisDeliveryStreamIAMRole.Arn
ExtendedS3DestinationConfiguration:
BucketARN: !Join [ '', ['arn:aws:s3:::', !Ref DeliveryBucketName] ]
BufferingHints:
IntervalInSeconds: 60
SizeInMBs: 50
CompressionFormat: UNCOMPRESSED
Prefix: !Ref DeliveryBucketPrefix
ErrorOutputPrefix: !Join [ '', ['error/', "!{firehose:error-output-type}/"] ]
RoleARN: !GetAtt KinesisDeliveryStreamIAMRole.Arn
DependsOn:
- KinesisDeliveryStreamIAMRole
Glue:
Glue Database:
AWSTemplateFormatVersion: 2010-09-09
Parameters:
GlueDatabaseName:
Description: 'Name of Glue database'
Type: String
Default: 'data-db'
Resources:
GlueDatabase:
Type: AWS::Glue::Database
Properties:
CatalogId: !Ref AWS::AccountId
DatabaseInput:
Name: !Ref GlueDatabaseName
Description: !Sub Database to hold tables for ${AWS::StackName}
Glue Crawler:
AWSTemplateFormatVersion: 2010-09-09
Parameters:
GlueDatabaseName:
Description: 'Name of Glue database'
Type: String
Default: 'data-db'
CrawlerName:
Description: 'Name of Glue crawler'
Type: String
Default: 'raw-data-crawler'
CrawlerPath:
Description: 'Bucket path where crawler will run'
Type: String
Default: 's3://my-bucket/raw/'
TablePrefix:
Description: 'Prefix for table created by crawler'
Type: String
Default: 'tbl_'
Resources:
CrawlerRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
-
Effect: "Allow"
Principal:
Service:
- "glue.amazonaws.com"
Action:
- "sts:AssumeRole"
Path: "/"
Policies:
-
PolicyName: "root"
PolicyDocument:
Version: "2012-10-17"
Statement:
-
Effect: "Allow"
Action: "*"
Resource: "*"
RawDataCrawlerWithBucket:
Type: AWS::Glue::Crawler
Properties:
Name: !Sub ${AWS::StackName}-${CrawlerName}
Role: !GetAtt CrawlerRole.Arn
Description: AWS Glue crawler to crawl raw data
#Schedule: none, use default run-on-demand
DatabaseName: !Ref GlueDatabaseName
Targets:
S3Targets:
- Path: !Ref CrawlerPath
TablePrefix: !Ref TablePrefix
SchemaChangePolicy:
UpdateBehavior: "UPDATE_IN_DATABASE"
DeleteBehavior: "LOG"
Configuration: "{\"Version\":1.0,\"CrawlerOutput\":{\"Partitions\":{\"AddOrUpdateBehavior\":\"InheritFromTable\"},\"Tables\":{\"AddOrUpdateBehavior\":\"MergeNewColumns\"}}}"
© Waqar Ahmed.RSS