Last active
October 25, 2017 13:10
Star
You must be signed in to star a gist
cfn
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
AWSTemplateFormatVersion: 2010-09-09 | |
Description: VPC + EB + RDS (MySQL) + Rails (Puma) | |
Parameters: | |
KeyName: | |
Description: Name of an existing EC2 KeyPair to enable SSH access to the bastion host and Elastic Beanstalk hosts | |
Type: AWS::EC2::KeyPair::KeyName | |
SSHLocation: | |
Description: Lockdown SSH access to the bastion host (default can be accessed from anywhere) | |
Type: String | |
Default: 0.0.0.0/0 | |
BastionInstanceType: | |
Description: Bastion Host EC2 instance type | |
Type: String | |
Default: t2.micro | |
BastionImageId: | |
Description: Bastion Host AMI ID | |
Type: String | |
Default: ami-6b96400d | |
NATInstanceType: | |
Description: NAT Device EC2 instance type | |
Type: String | |
Default: t2.micro | |
NATImageId: | |
Description: NAT Device AMI ID | |
Type: String | |
Default: ami-17944271 | |
RootVolumeSize: | |
Description: Root Volume Size | |
Type: Number | |
Default: 32 | |
DBName: | |
Description: Database Name | |
Type: String | |
Default: application | |
DBUser: | |
NoEcho: true | |
Description: The database admin account username | |
Type: String | |
Default: application | |
MinLength: 1 | |
MaxLength: 16 | |
AllowedPattern: "[a-zA-Z][a-zA-Z0-9]*" | |
ConstraintDescription: must begin with a letter and contain only alphanumeric characters. | |
DBPassword: | |
NoEcho: true | |
Description: The database admin account password | |
Type: String | |
Default: application | |
MinLength: 1 | |
MaxLength: 41 | |
AllowedPattern: "[a-zA-Z0-9]+" | |
ConstraintDescription: must contain only alphanumeric characters. | |
DB1llocatedStorage: | |
Description: The size of the database (Gb) | |
Type: Number | |
Default: 5 | |
MinValue: 5 | |
MaxValue: 1024 | |
ConstraintDescription: must be between 5 and 1024Gb. | |
DBInstanceClass: | |
Description: The database instance type | |
Type: String | |
Default: db.t2.micro | |
DBMultiAZ: | |
Description: Multi-AZ master database | |
Type: String | |
Default: "false" | |
AllowedValues: | |
- "true" | |
- "false" | |
ConstraintDescription: must be true or false. | |
DBAutoMinorVersionUpgrade: | |
Description: Apply minor engine upgrades automatically | |
Type: String | |
Default: "true" | |
AllowedValues: | |
- "true" | |
- "false" | |
ConstraintDescription: must be true or false. | |
Resources: | |
VPC: | |
Type: AWS::EC2::VPC | |
Properties: | |
CidrBlock: 10.0.0.0/16 | |
Tags: | |
- Key: Application | |
Value: !Ref AWS::StackId | |
- Key: Network | |
Value: Public | |
PublicSubnet1: | |
Type: AWS::EC2::Subnet | |
Properties: | |
VpcId: !Ref VPC | |
AvailabilityZone: ap-northeast-1a | |
CidrBlock: 10.0.0.0/24 | |
Tags: | |
- Key: Application | |
Value: !Ref AWS::StackId | |
- Key: Network | |
Value: Public | |
PublicSubnet2: | |
Type: AWS::EC2::Subnet | |
Properties: | |
VpcId: !Ref VPC | |
AvailabilityZone: ap-northeast-1c | |
CidrBlock: 10.0.1.0/24 | |
Tags: | |
- Key: Application | |
Value: !Ref AWS::StackId | |
- Key: Network | |
Value: Public | |
InternetGateway: | |
Type: AWS::EC2::InternetGateway | |
Properties: | |
Tags: | |
- Key: Application | |
Value: !Ref AWS::StackId | |
- Key: Network | |
Value: Public | |
GatewayToInternet: | |
Type: AWS::EC2::VPCGatewayAttachment | |
Properties: | |
VpcId: !Ref VPC | |
InternetGatewayId: !Ref InternetGateway | |
PublicRouteTable: | |
Type: AWS::EC2::RouteTable | |
Properties: | |
VpcId: !Ref VPC | |
Tags: | |
- Key: Application | |
Value: !Ref AWS::StackId | |
- Key: Network | |
Value: Public | |
PublicRoute: | |
Type: AWS::EC2::Route | |
DependsOn: GatewayToInternet | |
Properties: | |
RouteTableId: !Ref PublicRouteTable | |
DestinationCidrBlock: 0.0.0.0/0 | |
GatewayId: !Ref InternetGateway | |
PublicSubnet1RouteTableAssociation: | |
Type: AWS::EC2::SubnetRouteTableAssociation | |
Properties: | |
SubnetId: !Ref PublicSubnet1 | |
RouteTableId: !Ref PublicRouteTable | |
PublicSubnet2RouteTableAssociation: | |
Type: AWS::EC2::SubnetRouteTableAssociation | |
Properties: | |
SubnetId: !Ref PublicSubnet2 | |
RouteTableId: !Ref PublicRouteTable | |
PublicNetworkAcl: | |
Type: AWS::EC2::NetworkAcl | |
Properties: | |
VpcId: !Ref VPC | |
Tags: | |
- Key: Application | |
Value: !Ref AWS::StackId | |
- Key: Network | |
Value: Public | |
InboundHTTPPublicNetworkAclEntry: | |
Type: AWS::EC2::NetworkAclEntry | |
Properties: | |
NetworkAclId: !Ref PublicNetworkAcl | |
RuleNumber: 100 | |
Protocol: 6 | |
RuleAction: allow | |
Egress: false | |
CidrBlock: 0.0.0.0/0 | |
PortRange: | |
From: 80 | |
To: 80 | |
InboundHTTPSPublicNetworkAclEntry: | |
Type: AWS::EC2::NetworkAclEntry | |
Properties: | |
NetworkAclId: !Ref PublicNetworkAcl | |
RuleNumber: 101 | |
Protocol: 6 | |
RuleAction: allow | |
Egress: false | |
CidrBlock: 0.0.0.0/0 | |
PortRange: | |
From: 443 | |
To: 443 | |
InboundSSHPublicNetworkAclEntry: | |
Type: AWS::EC2::NetworkAclEntry | |
Properties: | |
NetworkAclId: !Ref PublicNetworkAcl | |
RuleNumber: 102 | |
Protocol: 6 | |
RuleAction: allow | |
Egress: false | |
CidrBlock: !Ref SSHLocation | |
PortRange: | |
From: 22 | |
To: 22 | |
InboundNTPPublicNetworkAclEntry: | |
Type: AWS::EC2::NetworkAclEntry | |
Properties: | |
NetworkAclId: !Ref PublicNetworkAcl | |
RuleNumber: 103 | |
Protocol: 17 | |
RuleAction: allow | |
Egress: false | |
CidrBlock: 0.0.0.0/0 | |
PortRange: | |
From: 123 | |
To: 123 | |
InboundEphemeralPublicNetworkAclEntry: | |
Type: AWS::EC2::NetworkAclEntry | |
Properties: | |
NetworkAclId: !Ref PublicNetworkAcl | |
RuleNumber: 104 | |
Protocol: 6 | |
RuleAction: allow | |
Egress: false | |
CidrBlock: 0.0.0.0/0 | |
PortRange: | |
From: 1024 | |
To: 65535 | |
OutboundPublicNetworkAclEntry: | |
Type: AWS::EC2::NetworkAclEntry | |
Properties: | |
NetworkAclId: !Ref PublicNetworkAcl | |
RuleNumber: 100 | |
Protocol: -1 | |
RuleAction: allow | |
Egress: true | |
CidrBlock: 0.0.0.0/0 | |
PublicSubnet1NetworkAclAssociation: | |
Type: AWS::EC2::SubnetNetworkAclAssociation | |
Properties: | |
SubnetId: !Ref PublicSubnet1 | |
NetworkAclId: !Ref PublicNetworkAcl | |
PublicSubnet2NetworkAclAssociation: | |
Type: AWS::EC2::SubnetNetworkAclAssociation | |
Properties: | |
SubnetId: !Ref PublicSubnet2 | |
NetworkAclId: !Ref PublicNetworkAcl | |
PrivateSubnetApp1: | |
Type: AWS::EC2::Subnet | |
Properties: | |
VpcId: !Ref VPC | |
AvailabilityZone: ap-northeast-1a | |
CidrBlock: 10.0.10.0/24 | |
Tags: | |
- Key: Application | |
Value: !Ref AWS::StackId | |
- Key: Network | |
Value: Private | |
PrivateSubnetApp2: | |
Type: AWS::EC2::Subnet | |
Properties: | |
VpcId: !Ref VPC | |
AvailabilityZone: ap-northeast-1c | |
CidrBlock: 10.0.11.0/24 | |
Tags: | |
- Key: Application | |
Value: !Ref AWS::StackId | |
- Key: Network | |
Value: Private | |
PrivateSubnetDB1: | |
Type: AWS::EC2::Subnet | |
Properties: | |
VpcId: !Ref VPC | |
AvailabilityZone: ap-northeast-1a | |
CidrBlock: 10.0.100.0/24 | |
Tags: | |
- Key: Application | |
Value: !Ref AWS::StackId | |
- Key: Network | |
Value: Private | |
PrivateSubnetDB2: | |
Type: AWS::EC2::Subnet | |
Properties: | |
VpcId: !Ref VPC | |
AvailabilityZone: ap-northeast-1c | |
CidrBlock: 10.0.101.0/24 | |
Tags: | |
- Key: Application | |
Value: !Ref AWS::StackId | |
- Key: Network | |
Value: Private | |
DBSubnetGroup: | |
Type: AWS::RDS::DBSubnetGroup | |
Properties: | |
DBSubnetGroupDescription: DB subnet group | |
SubnetIds: | |
- !Ref PrivateSubnetDB1 | |
- !Ref PrivateSubnetDB2 | |
Tags: | |
- Key: Application | |
Value: !Ref AWS::StackId | |
- Key: Network | |
Value: Private | |
PrivateRouteTable: | |
Type: AWS::EC2::RouteTable | |
Properties: | |
VpcId: !Ref VPC | |
Tags: | |
- Key: Application | |
Value: !Ref AWS::StackId | |
- Key: Network | |
Value: Private | |
PrivateSubnetRouteTableAssociationApp1: | |
Type: AWS::EC2::SubnetRouteTableAssociation | |
Properties: | |
SubnetId: !Ref PrivateSubnetApp1 | |
RouteTableId: !Ref PrivateRouteTable | |
PrivateSubnetRouteTableAssociationApp2: | |
Type: AWS::EC2::SubnetRouteTableAssociation | |
Properties: | |
SubnetId: !Ref PrivateSubnetApp2 | |
RouteTableId: !Ref PrivateRouteTable | |
PrivateSubnetRouteTableAssociationDB1: | |
Type: AWS::EC2::SubnetRouteTableAssociation | |
Properties: | |
SubnetId: !Ref PrivateSubnetDB1 | |
RouteTableId: !Ref PrivateRouteTable | |
PrivateSubnetRouteTableAssociationDB2: | |
Type: AWS::EC2::SubnetRouteTableAssociation | |
Properties: | |
SubnetId: !Ref PrivateSubnetDB2 | |
RouteTableId: !Ref PrivateRouteTable | |
PrivateRoute: | |
Type: AWS::EC2::Route | |
Properties: | |
RouteTableId: !Ref PrivateRouteTable | |
DestinationCidrBlock: 0.0.0.0/0 | |
InstanceId: !Ref NATDevice | |
PrivateNetworkAcl: | |
Type: AWS::EC2::NetworkAcl | |
Properties: | |
VpcId: !Ref VPC | |
Tags: | |
- Key: Application | |
Value: !Ref AWS::StackId | |
- Key: Network | |
Value: Private | |
InboundPrivateNetworkAclEntry: | |
Type: AWS::EC2::NetworkAclEntry | |
Properties: | |
NetworkAclId: !Ref PrivateNetworkAcl | |
RuleNumber: 100 | |
Protocol: -1 | |
RuleAction: allow | |
Egress: false | |
CidrBlock: 0.0.0.0/0 | |
OutboundPrivateNetworkAclEntry: | |
Type: AWS::EC2::NetworkAclEntry | |
Properties: | |
NetworkAclId: !Ref PrivateNetworkAcl | |
RuleNumber: 100 | |
Protocol: -1 | |
RuleAction: allow | |
Egress: true | |
CidrBlock: 0.0.0.0/0 | |
PrivateSubnetNetworkAclAssociationApp1: | |
Type: AWS::EC2::SubnetNetworkAclAssociation | |
Properties: | |
SubnetId: !Ref PrivateSubnetApp1 | |
NetworkAclId: !Ref PrivateNetworkAcl | |
PrivateSubnetNetworkAclAssociationApp2: | |
Type: AWS::EC2::SubnetNetworkAclAssociation | |
Properties: | |
SubnetId: !Ref PrivateSubnetApp2 | |
NetworkAclId: !Ref PrivateNetworkAcl | |
PrivateSubnetNetworkAclAssociationDB1: | |
Type: AWS::EC2::SubnetNetworkAclAssociation | |
Properties: | |
SubnetId: !Ref PrivateSubnetDB1 | |
NetworkAclId: !Ref PrivateNetworkAcl | |
PrivateSubnetNetworkAclAssociationDB2: | |
Type: AWS::EC2::SubnetNetworkAclAssociation | |
Properties: | |
SubnetId: !Ref PrivateSubnetDB2 | |
NetworkAclId: !Ref PrivateNetworkAcl | |
NATIPAddress: | |
Type: AWS::EC2::EIP | |
DependsOn: GatewayToInternet | |
Properties: | |
Domain: vpc | |
InstanceId: !Ref NATDevice | |
NATDevice: | |
Type: AWS::EC2::Instance | |
Properties: | |
InstanceType: !Ref NATInstanceType | |
SubnetId: !Ref PublicSubnet1 | |
SourceDestCheck: false | |
ImageId: !Ref NATImageId | |
SecurityGroupIds: | |
- !Ref NATSecurityGroup | |
Tags: | |
- Key: Application | |
Value: !Ref AWS::StackId | |
NATSecurityGroup: | |
Type: AWS::EC2::SecurityGroup | |
Properties: | |
GroupDescription: Enable internal access to the NAT device | |
VpcId: !Ref VPC | |
SecurityGroupIngress: | |
- IpProtocol: -1 | |
FromPort: 0 | |
ToPort: 65535 | |
CidrIp: 10.0.0.0/16 | |
SecurityGroupEgress: | |
- IpProtocol: -1 | |
FromPort: 0 | |
ToPort: 65535 | |
CidrIp: 0.0.0.0/0 | |
BastionIPAddress: | |
Type: AWS::EC2::EIP | |
DependsOn: GatewayToInternet | |
Properties: | |
Domain: vpc | |
InstanceId: !Ref Bastion | |
Bastion: | |
Type: AWS::EC2::Instance | |
Properties: | |
InstanceType: !Ref BastionInstanceType | |
KeyName: !Ref KeyName | |
SubnetId: !Ref PublicSubnet1 | |
ImageId: !Ref BastionImageId | |
SecurityGroupIds: | |
- !Ref BastionSecurityGroup | |
Tags: | |
- Key: Application | |
Value: !Ref AWS::StackId | |
BastionSecurityGroup: | |
Type: AWS::EC2::SecurityGroup | |
Properties: | |
GroupDescription: Enable access to the Bastion host | |
VpcId: !Ref VPC | |
SecurityGroupIngress: | |
- IpProtocol: tcp | |
FromPort: 22 | |
ToPort: 22 | |
CidrIp: !Ref SSHLocation | |
SecurityGroupEgress: | |
- IpProtocol: -1 | |
FromPort: 0 | |
ToPort: 65535 | |
CidrIp: 0.0.0.0/0 | |
BeanstalkSecurityGroup: | |
Type: AWS::EC2::SecurityGroup | |
Properties: | |
GroupDescription: Allow the Elastic Beanstalk instances to access the NAT device | |
VpcId: !Ref VPC | |
WebServerPolicy: | |
Type: AWS::IAM::ManagedPolicy | |
Properties: | |
Description: Web server policy | |
PolicyDocument: | |
Version: 2012-10-17 | |
Statement: | |
- Effect: Allow | |
NotAction: iam:* | |
Resource: "*" | |
WebServerRole: | |
Type: AWS::IAM::Role | |
Properties: | |
AssumeRolePolicyDocument: | |
Version: 2012-10-17 | |
Statement: | |
- Effect: Allow | |
Principal: | |
Service: ec2.amazonaws.com | |
Action: | |
- sts:AssumeRole | |
ManagedPolicyArns: | |
- !Ref WebServerPolicy | |
WebServerInstanceProfile: | |
Type: AWS::IAM::InstanceProfile | |
Properties: | |
Path: / | |
Roles: | |
- !Ref WebServerRole | |
Application: | |
Type: AWS::ElasticBeanstalk::Application | |
Properties: | |
Description: AWS Elastic Beanstalk Application | |
ApplicationEnvironment: | |
Type: AWS::ElasticBeanstalk::Environment | |
Properties: | |
ApplicationName: !Ref Application | |
Description: AWS Elastic Beanstalk Environment running Application | |
SolutionStackName: 64bit Amazon Linux 2017.09 v2.6.0 running Ruby 2.4 (Puma) | |
Tags: | |
- Key: Application | |
Value: !Ref AWS::StackId | |
OptionSettings: | |
- Namespace: aws:elasticbeanstalk:application | |
OptionName: Application Healthcheck URL | |
Value: / | |
- Namespace: aws:elasticbeanstalk:application:environment | |
OptionName: SECRET_KEY_BASE | |
Value: UPDATE ME | |
- Namespace: aws:elasticbeanstalk:application:environment | |
OptionName: DATABASE_USERNAME | |
Value: !Ref DBUser | |
- Namespace: aws:elasticbeanstalk:application:environment | |
OptionName: DATABASE_PASSWORD | |
Value: !Ref DBPassword | |
- Namespace: aws:elasticbeanstalk:application:environment | |
OptionName: DATABASE_HOST | |
Value: !GetAtt ["Database", "Endpoint.Address"] | |
- Namespace: aws:elasticbeanstalk:command | |
OptionName: DeploymentPolicy | |
Value: RollingWithAdditionalBatch | |
- Namespace: aws:elasticbeanstalk:environment | |
OptionName: EnvironmentType | |
Value: LoadBalanced | |
- Namespace: aws:autoscaling:asg | |
OptionName: MinSize | |
Value: 2 | |
- Namespace: aws:autoscaling:asg | |
OptionName: MaxSize | |
Value: 4 | |
- Namespace: aws:autoscaling:launchconfiguration | |
OptionName: SSHSourceRestriction | |
Value: !Sub tcp, 22, 22, ${BastionSecurityGroup} | |
- Namespace: aws:autoscaling:launchconfiguration | |
OptionName: SecurityGroups | |
Value: !Ref BeanstalkSecurityGroup | |
- Namespace: aws:autoscaling:launchconfiguration | |
OptionName: EC2KeyName | |
Value: !Ref KeyName | |
- Namespace: aws:autoscaling:launchconfiguration | |
OptionName: IamInstanceProfile | |
Value: !Ref WebServerInstanceProfile | |
- Namespace: aws:autoscaling:launchconfiguration | |
OptionName: RootVolumeSize | |
Value: !Ref RootVolumeSize | |
- Namespace: aws:autoscaling:updatepolicy:rollingupdate | |
OptionName: RollingUpdateEnabled | |
Value: true | |
- Namespace: aws:autoscaling:updatepolicy:rollingupdate | |
OptionName: RollingUpdateType | |
Value: Health | |
- Namespace: aws:ec2:vpc | |
OptionName: VPCId | |
Value: !Ref VPC | |
- Namespace: aws:ec2:vpc | |
OptionName: Subnets | |
Value: !Sub ${PrivateSubnetApp1}, ${PrivateSubnetApp2} | |
- Namespace: aws:ec2:vpc | |
OptionName: ELBSubnets | |
Value: !Sub ${PublicSubnet1}, ${PublicSubnet2} | |
DBSecurityGroup: | |
Type: AWS::EC2::SecurityGroup | |
Properties: | |
GroupDescription: DB security group | |
VpcId: !Ref VPC | |
SecurityGroupIngress: | |
- IpProtocol: tcp | |
FromPort: 3306 | |
ToPort: 3306 | |
SourceSecurityGroupId: !Ref BeanstalkSecurityGroup | |
SecurityGroupEgress: | |
- IpProtocol: -1 | |
FromPort: 0 | |
ToPort: 65535 | |
CidrIp: 0.0.0.0/0 | |
DBParameterGroup: | |
Type: AWS::RDS::DBParameterGroup | |
Properties: | |
Family: MySQL5.7 | |
Description: Database Parameter Group | |
Parameters: | |
character_set_client: utf8mb4 | |
character_set_connection: utf8mb4 | |
character_set_database: utf8mb4 | |
character_set_results: utf8mb4 | |
character_set_server: utf8mb4 | |
collation_connection: utf8mb4_bin | |
collation_server: utf8mb4_bin | |
Tags: | |
- Key: Application | |
Value: !Ref AWS::StackId | |
DBOptionGroup: | |
Type: AWS::RDS::OptionGroup | |
DeletionPolicy: Retain | |
Properties: | |
EngineName: mysql | |
MajorEngineVersion: "5.7" | |
OptionGroupDescription: Database Option Group | |
OptionConfigurations: [] | |
Tags: | |
- Key: Application | |
Value: !Ref AWS::StackId | |
Database: | |
Type: AWS::RDS::DBInstance | |
DeletionPolicy: Snapshot | |
Properties: | |
DBName: !Ref DBName | |
AllocatedStorage: !Ref DB1llocatedStorage | |
DBInstanceClass: !Ref DBInstanceClass | |
Engine: MySQL | |
EngineVersion: "5.7" | |
MasterUsername: !Ref DBUser | |
MasterUserPassword: !Ref DBPassword | |
MultiAZ: !Ref DBMultiAZ | |
AutoMinorVersionUpgrade: !Ref DBAutoMinorVersionUpgrade | |
DBParameterGroupName: !Ref DBParameterGroup | |
DBSubnetGroupName: !Ref DBSubnetGroup | |
OptionGroupName: !Ref DBOptionGroup | |
VPCSecurityGroups: | |
- !Ref DBSecurityGroup | |
Tags: | |
- Key: Application | |
Value: !Ref AWS::StackId | |
Outputs: | |
Bastion: | |
Description: IP Address of the Bastion host | |
Value: !Ref BastionIPAddress | |
URL: | |
Description: The URL of the Elastic Beanstalk environment | |
Value: !Sub ["http://${Endpoint}", { Endpoint: { "Fn::GetAtt": ["ApplicationEnvironment", "EndpointURL"] }}] | |
DBEndpoint: | |
Description: Database endpoint | |
Value: !Sub ["${Address}:${Port}", { Address: { "Fn::GetAtt": ["Database", "Endpoint.Address"] }, Port: { "Fn::GetAtt": ["Database", "Endpoint.Port"] }}] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment