Skip to content

Instantly share code, notes, and snippets.

@walokra
Last active October 14, 2020 19:58
Show Gist options
  • Select an option

  • Save walokra/278053fbde4ee73cba555897132753b0 to your computer and use it in GitHub Desktop.

Select an option

Save walokra/278053fbde4ee73cba555897132753b0 to your computer and use it in GitHub Desktop.
TimescaleDB CloudFormation stack with EBS VolumeAttachment
AWSTemplateFormatVersion: "2010-09-09"
Description: "TimescaleDB stack"
Parameters:
KeyName:
Description: Name of an existing EC2 KeyPair to enable SSH access to the instance
Type: "AWS::EC2::KeyPair::KeyName"
ConstraintDescription: must be the name of an existing EC2 KeyPair.
InstanceAZ:
Description: EC2 AZ.
Type: AWS::EC2::AvailabilityZone::Name
ConstraintDescription: "Must be the name of an availabity zone."
Default: "eu-central-1a"
InstanceType:
Description: EC2 instance type
Type: String
Default: r5.xlarge
AllowedValues: [t2.micro, r4.xlarge, r5.large, r5.xlarge, r5.2xlarge]
ConstraintDescription: Please choose a valid instance type.
LinuxAMIID:
Description: The Latest Amazon Linux 2 AMI taken from the public Systems Manager Parameter Store
Type: AWS::SSM::Parameter::Value<String>
Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2
VolumeId:
Description: Volume Id to attach
Type: String
Resources:
SSHSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Enable SSH access via port 22
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
Tags:
- Key: Name
Value: !Ref "AWS::StackName"
# EC2 Instance with a custom security group
# and an externally created EBS volume attached
Instance:
Type: AWS::EC2::Instance
Metadata:
AWS::CloudFormation::Init:
configSets:
default:
- install_packages
- configure_docker
- configure_volume
install_packages:
packages:
yum:
xfsprogs: []
docker: []
configure_docker:
commands:
1_start_service:
command: service docker start
2_mod_user:
command: usermod -a -G docker ec2-user
3_enable:
command: chkconfig docker on
4_create_network:
command: docker network create timescaledb-network
configure_volume:
commands:
1_mkdir:
command: mkdir /var/timescaledb
2_fstab:
command: echo "/dev/mapper/vg0-timescaledb /var/timescaledb xfs defaults,auto,noatime,noexec 0 0" | tee -a /etc/fstab
3_mount:
command: mount -a
Properties:
InstanceType: !Ref InstanceType
ImageId: !Ref LinuxAMIID
AvailabilityZone: !Ref InstanceAZ
Monitoring: false # Enable Enhanced Monitoring
KeyName: !Ref KeyName
IamInstanceProfile: !Ref InstanceProfile
SecurityGroupIds:
- !Ref SSHSecurityGroup
Tags:
- Key: Name
Value: !Ref "AWS::StackName"
UserData:
# See: https://github.com/1Strategy/blog-add-ebs-volume
Fn::Base64: !Sub |
#!/bin/bash -xe
yum -y update
yum update -y aws-cfn-bootstrap
yum install -y postgresql
/opt/aws/bin/cfn-init -v --stack ${AWS::StackId} --resource Instance --configsets default --region ${AWS::Region}
docker run -d --name timescaledb --network="timescaledb-network" -p 5432:5432 -e TIMESCALEDB_TELEMETRY=off -e POSTGRES_PASSWORD=postgres -v /var/timescaledb/data:/var/lib/postgresql/data timescale/timescaledb:latest-pg11
/opt/aws/bin/cfn-signal --exit-code $? --stack ${AWS::StackId} --resource Instance --region ${AWS::Region}
VolumeAttachment:
Type: AWS::EC2::VolumeAttachment
Properties:
Device: "/dev/xvdf"
InstanceId: !Ref Instance
VolumeId: !Ref VolumeId
InstanceProfile:
Type: "AWS::IAM::InstanceProfile"
Properties:
Path: "/"
Roles:
- !Ref IamRole
IamRole:
Type: "AWS::IAM::Role"
Properties:
Description: Permissions the DB Instance requires to get / put data
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- ec2.amazonaws.com
Action:
- "sts:AssumeRole"
Path: /
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
RoleName: Ec2RoleForSSM
Description: EC2 IAM role for SSM and CloudWatchAgent access
# Permissions for EC2 Instance to access S3 Bucket
#
RolePolicies:
Type: AWS::IAM::Policy
DependsOn:
- Instance
Properties:
PolicyName: InstancePolicy
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- "s3:List*"
- "s3:ListBucket"
- "s3:GetObject"
- "s3:PutObject"
Resource:
- "arn:aws:s3:::some-s3-bucket-name"
- "arn:aws:s3:::some-s3-bucket-name/*"
Roles:
- !Ref IamRole
Outputs:
InstanceId:
Description: InstanceId of the newly created EC2 instance
Value: !Ref Instance
AZ:
Description: Availability Zone of the newly created EC2 instance
Value: !GetAtt Instance.AvailabilityZone
HostDNS:
Description: Host public DNS
Value: !GetAtt Instance.PublicDnsName
PublicIPAddress:
Description: Host public IP
Value: !GetAtt Instance.PublicIp
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment