Compare commits
22 Commits
master
...
home-rds-r
| Author | SHA1 | Date | |
|---|---|---|---|
| 1bde508461 | |||
| f8f0e9a688 | |||
| b16b747414 | |||
| bae738ad98 | |||
| 331643fbf7 | |||
| 12a967b92e | |||
| 2281dd34fd | |||
| ab6d220f8c | |||
| 3d58f2c5d6 | |||
| f5a5dc4410 | |||
| 16058e296d | |||
| aaae536003 | |||
| c97321790b | |||
| 3fc49078ab | |||
| 9ba7de1ad2 | |||
| 008aa708bf | |||
| c1e515d28b | |||
| ea12dc3827 | |||
| 31936a6729 | |||
| bea77bf9fa | |||
| b60bebbddc | |||
| 67951f21f4 |
@@ -7,6 +7,77 @@ Resources:
|
|||||||
CidrBlock: "172.31.0.0/16"
|
CidrBlock: "172.31.0.0/16"
|
||||||
EnableDnsHostnames: true
|
EnableDnsHostnames: true
|
||||||
EnableDnsSupport: true
|
EnableDnsSupport: true
|
||||||
|
ELBSecurityGroup:
|
||||||
|
Type: AWS::EC2::SecurityGroup
|
||||||
|
Properties:
|
||||||
|
GroupName: !Sub "${AWS::StackName}-ELBSecurityGroup"
|
||||||
|
GroupDescription: Security group for the Elastic Load Balancer.
|
||||||
|
This permits inbound 80/443 from any IP, to 80/443 to the
|
||||||
|
Auto Scaling security group.
|
||||||
|
VpcId: !Ref PublicVPC
|
||||||
|
ELBSecurityGroupIngressHttp:
|
||||||
|
Type: AWS::EC2::SecurityGroupIngress
|
||||||
|
Properties:
|
||||||
|
Description: Ingress for ELBSecurityGroup for HTTP.
|
||||||
|
GroupId: !Ref ELBSecurityGroup
|
||||||
|
IpProtocol: tcp
|
||||||
|
FromPort: 80
|
||||||
|
ToPort: 80
|
||||||
|
CidrIp: 0.0.0.0/0
|
||||||
|
ELBSecurityGroupIngressHttps:
|
||||||
|
Type: AWS::EC2::SecurityGroupIngress
|
||||||
|
Properties:
|
||||||
|
Description: Ingress for ELBSecurityGroup for HTTPS.
|
||||||
|
GroupId: !Ref ELBSecurityGroup
|
||||||
|
IpProtocol: tcp
|
||||||
|
FromPort: 443
|
||||||
|
ToPort: 443
|
||||||
|
CidrIp: 0.0.0.0/0
|
||||||
|
ELBSecurityGroupEgressHttp:
|
||||||
|
Type: AWS::EC2::SecurityGroupEgress
|
||||||
|
Properties:
|
||||||
|
Description: Egress for ELBSecurityGroup for HTTP.
|
||||||
|
GroupId: !Ref ELBSecurityGroup
|
||||||
|
IpProtocol: tcp
|
||||||
|
FromPort: 80
|
||||||
|
ToPort: 80
|
||||||
|
SourceSecurityGroupId: !Ref ASSecurityGroup
|
||||||
|
ELBSecurityGroupEgressHttps:
|
||||||
|
Type: AWS::EC2::SecurityGroupEgress
|
||||||
|
Properties:
|
||||||
|
Description: Egress for ELBSecurityGroup for HTTPS.
|
||||||
|
GroupId: !Ref ELBSecurityGroup
|
||||||
|
IpProtocol: tcp
|
||||||
|
FromPort: 443
|
||||||
|
ToPort: 443
|
||||||
|
SourceSecurityGroupId: !Ref ASSecurityGroup
|
||||||
|
ASSecurityGroup:
|
||||||
|
Type: AWS::EC2::SecurityGroup
|
||||||
|
Properties:
|
||||||
|
GroupName: !Sub "${AWS::StackName}-ASSecurityGroup"
|
||||||
|
GroupDescription: Security group for the Auto Scaler. This security group
|
||||||
|
will be applied to any EC2 instances that the Auto Scaler creates. This
|
||||||
|
group permits inbound 80/443 from the Elastic Load Balancer security
|
||||||
|
group.
|
||||||
|
VpcId: !Ref PublicVPC
|
||||||
|
ASSecurityGroupIngressHttp:
|
||||||
|
Type: AWS::EC2::SecurityGroupIngress
|
||||||
|
Properties:
|
||||||
|
Description: Ingress for ASSecurityGroup for HTTP.
|
||||||
|
GroupId: !Ref ASSecurityGroup
|
||||||
|
IpProtocol: tcp
|
||||||
|
FromPort: 80
|
||||||
|
ToPort: 80
|
||||||
|
SourceSecurityGroupId: !Ref ELBSecurityGroup
|
||||||
|
ASSecurityGroupIngressHttps:
|
||||||
|
Type: AWS::EC2::SecurityGroupIngress
|
||||||
|
Properties:
|
||||||
|
Description: Ingress for ASSecurityGroup for HTTPS.
|
||||||
|
GroupId: !Ref ASSecurityGroup
|
||||||
|
IpProtocol: tcp
|
||||||
|
FromPort: 443
|
||||||
|
ToPort: 443
|
||||||
|
SourceSecurityGroupId: !Ref ELBSecurityGroup
|
||||||
PublicSubnet0:
|
PublicSubnet0:
|
||||||
Type: AWS::EC2::Subnet
|
Type: AWS::EC2::Subnet
|
||||||
Properties:
|
Properties:
|
||||||
@@ -72,27 +143,37 @@ Resources:
|
|||||||
RouteTableId: !Ref PublicRouteTable
|
RouteTableId: !Ref PublicRouteTable
|
||||||
Outputs:
|
Outputs:
|
||||||
PublicVPCID:
|
PublicVPCID:
|
||||||
Description: The VPC ID.
|
Description: The VPC for the environment.
|
||||||
Value: !Ref PublicVPC
|
Value: !Ref PublicVPC
|
||||||
Export:
|
Export:
|
||||||
Name: !Sub "${AWS::StackName}-PublicVPC"
|
Name: !Sub "${AWS::StackName}-PublicVPC"
|
||||||
PublicVPCIDDefaultSecurityGroup:
|
ELBSecurityGroupOutput:
|
||||||
Description: The VPC default security group.
|
Description: ELB Security Group
|
||||||
Value: !GetAtt PublicVPC.DefaultSecurityGroup
|
Value: !Ref ELBSecurityGroup
|
||||||
Export:
|
Export:
|
||||||
Name: !Sub "${AWS::StackName}-PublicVPCIDDefaultSecurityGroup"
|
Name: !Sub "${AWS::StackName}-ELBSecurityGroup"
|
||||||
|
ASSecurityGroupOutput:
|
||||||
|
Description: AS Security Group
|
||||||
|
Value: !Ref ASSecurityGroup
|
||||||
|
Export:
|
||||||
|
Name: !Sub "${AWS::StackName}-ASSecurityGroup"
|
||||||
|
# PublicVPCIDDefaultSecurityGroup:
|
||||||
|
# Description: The VPC default security group.
|
||||||
|
# Value: !GetAtt PublicVPC.DefaultSecurityGroup
|
||||||
|
# Export:
|
||||||
|
# Name: !Sub "${AWS::StackName}-PublicVPCIDDefaultSecurityGroup"
|
||||||
PublicSubnet0ID:
|
PublicSubnet0ID:
|
||||||
Description: The ID of the subnet.
|
Description: The public subnet 0.
|
||||||
Value: !Ref PublicSubnet0
|
Value: !Ref PublicSubnet0
|
||||||
Export:
|
Export:
|
||||||
Name: !Sub "${AWS::StackName}-PublicSubnet0"
|
Name: !Sub "${AWS::StackName}-PublicSubnet0"
|
||||||
PublicSubnet1ID:
|
PublicSubnet1ID:
|
||||||
Description: The ID of the subnet.
|
Description: The public subnet 1.
|
||||||
Value: !Ref PublicSubnet1
|
Value: !Ref PublicSubnet1
|
||||||
Export:
|
Export:
|
||||||
Name: !Sub "${AWS::StackName}-PublicSubnet1"
|
Name: !Sub "${AWS::StackName}-PublicSubnet1"
|
||||||
PublicSubnet2ID:
|
PublicSubnet2ID:
|
||||||
Description: The ID of the subnet.
|
Description: The public subnet 2.
|
||||||
Value: !Ref PublicSubnet2
|
Value: !Ref PublicSubnet2
|
||||||
Export:
|
Export:
|
||||||
Name: !Sub "${AWS::StackName}-PublicSubnet2"
|
Name: !Sub "${AWS::StackName}-PublicSubnet2"
|
||||||
|
|||||||
@@ -11,15 +11,6 @@ Parameters:
|
|||||||
to prepend the name of other resources in other templates.
|
to prepend the name of other resources in other templates.
|
||||||
Type: String
|
Type: String
|
||||||
Resources:
|
Resources:
|
||||||
# VPCSecurityGroupIngress:
|
|
||||||
# Type: AWS::EC2::SecurityGroupIngress
|
|
||||||
# Properties:
|
|
||||||
# GroupId:
|
|
||||||
# Fn::ImportValue: !Sub "${StackName}-PublicVPCIDDefaultSecurityGroup"
|
|
||||||
# IpProtocol: tcp
|
|
||||||
# FromPort: 5432
|
|
||||||
# ToPort: 5432
|
|
||||||
# CidrIp: 0.0.0.0/0
|
|
||||||
RDSSubnetGroup:
|
RDSSubnetGroup:
|
||||||
Type: AWS::RDS::DBSubnetGroup
|
Type: AWS::RDS::DBSubnetGroup
|
||||||
Properties:
|
Properties:
|
||||||
@@ -36,10 +27,15 @@ Resources:
|
|||||||
VpcId:
|
VpcId:
|
||||||
Fn::ImportValue: !Sub "${StackName}-PublicVPC"
|
Fn::ImportValue: !Sub "${StackName}-PublicVPC"
|
||||||
SecurityGroupIngress:
|
SecurityGroupIngress:
|
||||||
IpProtocol: tcp
|
- IpProtocol: tcp
|
||||||
FromPort: 5432
|
FromPort: 5432
|
||||||
ToPort: 5432
|
ToPort: 5432
|
||||||
CidrIp: 0.0.0.0/0
|
CidrIp: 82.6.205.148/32
|
||||||
|
- IpProtocol: tcp
|
||||||
|
FromPort: 5432
|
||||||
|
ToPort: 5432
|
||||||
|
SourceSecurityGroupId:
|
||||||
|
Fn::ImportValue: !Sub "${StackName}-ASSecurityGroup"
|
||||||
RDSDBInstance:
|
RDSDBInstance:
|
||||||
Type: AWS::RDS::DBInstance
|
Type: AWS::RDS::DBInstance
|
||||||
Properties:
|
Properties:
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
# Resources:
|
||||||
|
# ElasticLoadBalancer:
|
||||||
|
# Type: AWS::ElasticLoadBalancingV2::TargetGroup
|
||||||
|
# Properties:
|
||||||
|
# VpcId: vpc-029d232726cbf591d
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
option_settings:
|
option_settings:
|
||||||
aws:elasticbeanstalk:environment:
|
# aws:elasticbeanstalk:environment:
|
||||||
EnvironmentType: SingleInstance
|
# EnvironmentType: SingleInstance
|
||||||
aws:rds:dbinstance:
|
# aws:rds:dbinstance:
|
||||||
DBEngine: postgres
|
# DBEngine: postgres
|
||||||
DBInstanceClass: "db.t2.micro"
|
# DBInstanceClass: "db.t2.micro"
|
||||||
DBAllocatedStorage: 5
|
# DBAllocatedStorage: 5
|
||||||
DBUser: strapi
|
# DBUser: strapi
|
||||||
aws:ec2:instances:
|
aws:ec2:instances:
|
||||||
InstanceTypes: "t2.micro"
|
InstanceTypes: "t2.micro"
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ option_settings:
|
|||||||
- option_name: STRAPI_S3_BUCKET
|
- option_name: STRAPI_S3_BUCKET
|
||||||
value: "elb-example-bucket-cf"
|
value: "elb-example-bucket-cf"
|
||||||
- option_name: RDS_HOSTNAME
|
- option_name: RDS_HOSTNAME
|
||||||
value: srdtnvn77v7rqd.chgwfe43ss59.eu-west-1.rds.amazonaws.com
|
value: src2ziuj8oxjct.chgwfe43ss59.eu-west-1.rds.amazonaws.com
|
||||||
- option_name: RDS_PORT
|
- option_name: RDS_PORT
|
||||||
value: 5432
|
value: 5432
|
||||||
- option_name: RDS_NAME
|
- option_name: RDS_NAME
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
Resources:
|
# Resources:
|
||||||
sslSecurityGroupIngress:
|
# sslSecurityGroupIngress:
|
||||||
Type: AWS::EC2::SecurityGroupIngress
|
# Type: AWS::EC2::SecurityGroupIngress
|
||||||
Properties:
|
# Properties:
|
||||||
GroupId: { "Fn::GetAtt": ["AWSEBSecurityGroup", "GroupId"] }
|
# GroupId: { "Fn::GetAtt": ["AWSEBSecurityGroup", "GroupId"] }
|
||||||
IpProtocol: tcp
|
# IpProtocol: tcp
|
||||||
ToPort: 443
|
# ToPort: 443
|
||||||
FromPort: 443
|
# FromPort: 443
|
||||||
CidrIp: 0.0.0.0/0
|
# CidrIp: 0.0.0.0/0
|
||||||
|
|||||||
@@ -1,5 +1,14 @@
|
|||||||
option_settings:
|
option_settings:
|
||||||
aws:ec2:vpc:
|
aws:ec2:vpc:
|
||||||
VPCId: vpc-029d232726cbf591d
|
VPCId: vpc-02f98fa754899162c
|
||||||
Subnets: "subnet-051fe56dc37d8396d,subnet-0ea9f2f165a57be27,subnet-09b28d722f41b2dde"
|
Subnets: "subnet-0b17872a2b9315fad,subnet-0342e8a0a77b30e23,subnet-0eacb84d238279a58"
|
||||||
DBSubnets: "subnet-051fe56dc37d8396d,subnet-0ea9f2f165a57be27,subnet-09b28d722f41b2dde"
|
DBSubnets: "subnet-0b17872a2b9315fad,subnet-0342e8a0a77b30e23,subnet-0eacb84d238279a58"
|
||||||
|
ELBSubnets: "subnet-0b17872a2b9315fad,subnet-0342e8a0a77b30e23,subnet-0eacb84d238279a58"
|
||||||
|
aws:autoscaling:launchconfiguration:
|
||||||
|
SecurityGroups: sg-07a97fc88ba143f26
|
||||||
|
aws:elbv2:loadbalancer:
|
||||||
|
ManagedSecurityGroup: sg-0e6f91df2ed07050a
|
||||||
|
SecurityGroups: sg-0e6f91df2ed07050a
|
||||||
|
aws:autoscaling:asg:
|
||||||
|
MinSize: 1
|
||||||
|
MaxSize: 4
|
||||||
|
|||||||
4
.ebextensions/08-loadbalancer.config
Normal file
4
.ebextensions/08-loadbalancer.config
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
option_settings:
|
||||||
|
aws:elbv2:listener:443:
|
||||||
|
Protocol: HTTPS
|
||||||
|
SSLCertificateArns: arn:aws:acm:eu-west-1:745437999005:certificate/218876af-7f8d-4022-97af-ad982aa540bc
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
* [Fix Version Numbers](#FixVersionNumbers)
|
* [Fix Version Numbers](#FixVersionNumbers)
|
||||||
* [Strapi in git](#Strapiingit)
|
* [Strapi in git](#Strapiingit)
|
||||||
* [Cloudformation](#Cloudformation)
|
* [Cloudformation](#Cloudformation)
|
||||||
|
* [Output naming convention](#Outputnamingconvention)
|
||||||
* [Creating templates](#Creatingtemplates)
|
* [Creating templates](#Creatingtemplates)
|
||||||
* [Adding resources](#Addingresources)
|
* [Adding resources](#Addingresources)
|
||||||
* [Using parameters](#Usingparameters)
|
* [Using parameters](#Usingparameters)
|
||||||
@@ -225,6 +226,23 @@ You can then run Strapi with `npm run develop` or `NODE_ENV=production npm run s
|
|||||||
|
|
||||||
<https://adamtheautomator.com/aws-cli-cloudformation/> (example of deploying an S3 bucket with static site `index.html`.)
|
<https://adamtheautomator.com/aws-cli-cloudformation/> (example of deploying an S3 bucket with static site `index.html`.)
|
||||||
|
|
||||||
|
### <a name='Outputnamingconvention'></a>Output naming convention
|
||||||
|
|
||||||
|
You should follow a standard naming convention for your CF outputs.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
Outputs:
|
||||||
|
PublicVPCOutput:
|
||||||
|
Description: The VPC ID.
|
||||||
|
Value: !Ref PublicVPC
|
||||||
|
Export:
|
||||||
|
Name: !Sub "${AWS::StackName}-EBStrapiPublicVPC"
|
||||||
|
```
|
||||||
|
|
||||||
|
Defines a VPC. We can then pass in the stackname to another CF template and it can reference this VPC. The VPC names are static between projects (they don't have to be but here they are).
|
||||||
|
|
||||||
### <a name='Creatingtemplates'></a>Creating templates
|
### <a name='Creatingtemplates'></a>Creating templates
|
||||||
|
|
||||||
To create a cloudformation template you should create a `template.yaml`. This yaml file should have at the top:
|
To create a cloudformation template you should create a `template.yaml`. This yaml file should have at the top:
|
||||||
|
|||||||
210
tempnotes.md
210
tempnotes.md
@@ -11,9 +11,23 @@
|
|||||||
_ [AWS::EC2::RouteTable](#AWS::EC2::RouteTable)
|
_ [AWS::EC2::RouteTable](#AWS::EC2::RouteTable)
|
||||||
_ [AWS::EC2::Route](#AWS::EC2::Route)
|
_ [AWS::EC2::Route](#AWS::EC2::Route)
|
||||||
_ [AWS::EC2::SubnetRouteTableAssociation](#AWS::EC2::SubnetRouteTableAssociation)
|
_ [AWS::EC2::SubnetRouteTableAssociation](#AWS::EC2::SubnetRouteTableAssociation)
|
||||||
- [Running notes](#Runningnotes)
|
- [Running notes](#Runningnotes) \* [Database](#Database)
|
||||||
- [Reference an input parameter, or a resource ID from inside current template](#ReferenceaninputparameteroraresourceIDfrominsidecurrenttemplate) \* [Using `Fn::Sub`](#UsingFn::Sub)
|
- [Work Commands](#WorkCommands)
|
||||||
- [Dynamically referencing resources from another stack.](#Dynamicallyreferencingresourcesfromanotherstack.)
|
_ [tags](#tags)
|
||||||
|
_ [deploy](#deploy)
|
||||||
|
_ [delete](#delete)
|
||||||
|
_ [describe-stack-resources](#describe-stack-resources)
|
||||||
|
- [Adding SSL to ELB](#AddingSSLtoELB) \* [With load balancer](#Withloadbalancer)
|
||||||
|
- [EB Templates/Resources](#EBTemplatesResources)
|
||||||
|
- [Configuring security groups](#Configuringsecuritygroups)
|
||||||
|
- [Elastic Load Balancer](#ElasticLoadBalancer)
|
||||||
|
_ [Elastic Scaler](#ElasticScaler)
|
||||||
|
_ [RDS](#RDS) \* [Security group to allow EC2 instances to talk to each other](#SecuritygrouptoallowEC2instancestotalktoeachother)
|
||||||
|
- [Custom VPC + Subnets in EB](#CustomVPCSubnetsinEB)
|
||||||
|
- [Using cloudformation functions in EB config files](#UsingcloudformationfunctionsinEBconfigfiles)
|
||||||
|
- [Creating a read replica RDS](#CreatingareadreplicaRDS)
|
||||||
|
- [Multiple security groups on the same resource](#Multiplesecuritygroupsonthesameresource)
|
||||||
|
- [Private subnets](#Privatesubnets)
|
||||||
|
|
||||||
<!-- vscode-markdown-toc-config
|
<!-- vscode-markdown-toc-config
|
||||||
numbering=false
|
numbering=false
|
||||||
@@ -25,7 +39,7 @@
|
|||||||
|
|
||||||
## <a name='Decoupling'></a>Decoupling
|
## <a name='Decoupling'></a>Decoupling
|
||||||
|
|
||||||
When creating an ELB instance with `--single` and `--database` the following is created as part of the ELB deployment:
|
When creating an EB instance with `--single` and `--database` the following is created as part of the EB deployment:
|
||||||
|
|
||||||
- security group
|
- security group
|
||||||
- EIP
|
- EIP
|
||||||
@@ -41,15 +55,15 @@ Export these in the CF template with stackname (<https://docs.aws.amazon.com/AWS
|
|||||||
|
|
||||||
A security group is a resource that defines what IPs/Ports are allowed on inbound/outbound for an AWS resource. You can have one for EC2 instance, or RDS among others.
|
A security group is a resource that defines what IPs/Ports are allowed on inbound/outbound for an AWS resource. You can have one for EC2 instance, or RDS among others.
|
||||||
|
|
||||||
ELB will create a VPC for your EC2 instances.
|
EB will create a VPC for your EC2 instances.
|
||||||
|
|
||||||
You should use this VPC for you RDS instance.
|
You should use this VPC for you RDS instance.
|
||||||
|
|
||||||
Creating a VPC for ELB (with RDS) <https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/vpc-rds.html>
|
Creating a VPC for EB (with RDS) <https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/vpc-rds.html>
|
||||||
|
|
||||||
## <a name='Singleinstancenoloadbalancer'></a>Single instance (no load balancer)
|
## <a name='Singleinstancenoloadbalancer'></a>Single instance (no load balancer)
|
||||||
|
|
||||||
Example cloudformation template that ELB uses: <https://raw.githubusercontent.com/awslabs/elastic-beanstalk-samples/master/cfn-templates/vpc-public.yaml>.
|
Example cloudformation template that EB uses: <https://raw.githubusercontent.com/awslabs/elastic-beanstalk-samples/master/cfn-templates/vpc-public.yaml>.
|
||||||
|
|
||||||
Create a VPC - this is an object that spans all availability zones in a region. You assign a VPC a CIDR block. This is a set of IP addresses that this VPC has access to.
|
Create a VPC - this is an object that spans all availability zones in a region. You assign a VPC a CIDR block. This is a set of IP addresses that this VPC has access to.
|
||||||
|
|
||||||
@@ -125,7 +139,7 @@ Database needs a security group creating
|
|||||||
EC2 security groups automatically created and associated with the VPC.
|
EC2 security groups automatically created and associated with the VPC.
|
||||||
Use aws:ec2:vpc (https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/command-options-general.html#command-options-general-ec2vpc)
|
Use aws:ec2:vpc (https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/command-options-general.html#command-options-general-ec2vpc)
|
||||||
|
|
||||||
### Database
|
### <a name='Database'></a>Database
|
||||||
|
|
||||||
Needs:
|
Needs:
|
||||||
|
|
||||||
@@ -143,30 +157,190 @@ Default ports:
|
|||||||
| SQL Server | 1433 |
|
| SQL Server | 1433 |
|
||||||
| DynamoDB | 8000 |
|
| DynamoDB | 8000 |
|
||||||
|
|
||||||
|
## <a name='WorkCommands'></a>Work Commands
|
||||||
|
|
||||||
|
### <a name='tags'></a>tags
|
||||||
|
|
||||||
## Work Commands
|
`--tags git=web-dev owner=home project=strapi-eb test=true deployment=cloudformation`
|
||||||
|
|
||||||
### deploy
|
### <a name='deploy'></a>deploy
|
||||||
|
|
||||||
`aws --profile admin cloudformation deploy --template-file ./02-stack-vpc.yaml --stack-name strapi-vpc --tags git=web-dev owner=home project=strapi-elb test=true deployment=cloudformation`
|
`aws --profile admin cloudformation deploy --template-file ./02-stack-vpc.yaml --stack-name strapi-vpc --tags git=web-dev owner=home project=strapi-eb test=true deployment=cloudformation`
|
||||||
|
|
||||||
`aws --profile admin cloudformation deploy --template-file ./02-stack-vpc.yaml --stack-name new-temp-vpc --tags git=web-dev owner=home project=strapi-elb test=true deployment=cloudformation`
|
`aws --profile admin cloudformation deploy --template-file ./03-stack-rdsinstance.yaml --stack-name strapi-rds --parameter-overrides StackName=strapi-vpc --tags git=web-dev owner=home project=strapi-eb test=true deployment=cloudformation`
|
||||||
|
|
||||||
`aws --profile admin cloudformation deploy --template-file ./03-stack-rdsinstance.yaml --stack-name strapi-rds --parameter-overrides StackName=strapi-vpc`
|
### <a name='delete'></a>delete
|
||||||
|
|
||||||
### delete
|
`aws --profile admin cloudformation delete-stack --stack-name strapi-vpc`
|
||||||
|
|
||||||
`aws --profile admin cloudformation delete-stack --stack-name temp-vpc`
|
`aws --profile admin cloudformation delete-stack --stack-name strapi-rds`
|
||||||
|
|
||||||
`aws --profile admin cloudformation delete-stack --stack-name new-temp-vpc`
|
|
||||||
|
|
||||||
`aws --profile admin cloudformation delete-stack --stack-name temp`
|
`aws --profile admin cloudformation delete-stack --stack-name temp`
|
||||||
|
|
||||||
List of all RDS Engines available under "Engine" header: <https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_CreateDBInstance.html>.
|
List of all RDS Engines available under "Engine" header: <https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_CreateDBInstance.html>.
|
||||||
|
|
||||||
### descrive-stack-resources
|
### <a name='describe-stack-resources'></a>describe-stack-resources
|
||||||
|
|
||||||
Will print a json list of all resources in the stack
|
Will print a json list of all resources in the stack
|
||||||
|
|
||||||
`aws --profile admin cloudformation describe-stack-resources --stack-name strapi-vpc`
|
`aws --profile admin cloudformation describe-stack-resources --stack-name strapi-vpc`
|
||||||
|
|
||||||
|
Using `jq` for formatting:
|
||||||
|
|
||||||
|
`aws --profile admin cloudformation describe-stack-resources --stack-name strapi-vpc | jq -r '.StackResources[] | .ResourceType + ": " + .PhysicalResourceId'`
|
||||||
|
|
||||||
|
## <a name='AddingSSLtoELB'></a>Adding SSL to ELB
|
||||||
|
|
||||||
|
You should generate an SSL Certificate in Certificate Manager for your domain. To do this you will need to create a CNAME record to verify you have access to the DNS settings.
|
||||||
|
|
||||||
|
At the same time you should create a CNAME record that maps your subdomain (<strapi.panaetius.co.uk>) to the DNS name AWS has given your load balancer (<awseb-AWSEB-68CXGV0UTROU-1492520139.eu-west-1.elb.amazonaws.com>).
|
||||||
|
|
||||||
|
### <a name='Withloadbalancer'></a>With load balancer
|
||||||
|
|
||||||
|
A load balancer is not free! It costs ~£15 a month.
|
||||||
|
|
||||||
|
- Configure the load balancer listener in a EB `.config` file:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
option_settings:
|
||||||
|
aws:elbv2:listener:443:
|
||||||
|
Protocol: HTTPS
|
||||||
|
SSLCertificateArns: arn:aws:acm:eu-west-1:745437999005:certificate/218876af-7f8d-4022-97af-ad982aa540bc
|
||||||
|
```
|
||||||
|
|
||||||
|
## <a name='EBTemplatesResources'></a>EB Templates/Resources
|
||||||
|
|
||||||
|
Good repo for examples: <https://github.com/awsdocs/elastic-beanstalk-samples>
|
||||||
|
|
||||||
|
Creating a VPC for RDS in EB: <https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/vpc-rds.html>
|
||||||
|
|
||||||
|
CF RDS EB template: <https://github.com/garystafford/aws-rds-postgres/blob/master/cfn-templates/rds.template>
|
||||||
|
|
||||||
|
Decouple an exisitng RDS instance from ELB to RDS: <https://aws.amazon.com/premiumsupport/knowledge-center/decouple-rds-from-beanstalk/>
|
||||||
|
|
||||||
|
## <a name='Configuringsecuritygroups'></a>Configuring security groups
|
||||||
|
|
||||||
|
## <a name='ElasticLoadBalancer'></a>Elastic Load Balancer
|
||||||
|
|
||||||
|
Should set: inbound/outbound 80/443 on 0.0.0.0/0
|
||||||
|
|
||||||
|
The option_settings: aws:elbv2:loadbalancer has two options for security groups.
|
||||||
|
|
||||||
|
| Option | Description |
|
||||||
|
| -------------------- | --------------------------------------------------------------------- |
|
||||||
|
| ManagedSecurityGroup | Defines the security group that is used for the load balancer itself. |
|
||||||
|
| SecurityGroups | Is a list of additional security groups you want to attach. |
|
||||||
|
|
||||||
|
If you define a ManagedSecurityGroup you should set SecurityGroups as well to the same one.
|
||||||
|
|
||||||
|
Load balancer needs a security group that allows incoming 80 + 443 from anywhere
|
||||||
|
It should also set the same for outbound as well
|
||||||
|
|
||||||
|
This security group should be set in `aws:elbv2:loadbalancer` under
|
||||||
|
`ManagedSecurityGroup` and `SecurityGroups`
|
||||||
|
|
||||||
|
### <a name='ElasticScaler'></a>Elastic Scaler
|
||||||
|
|
||||||
|
Should set inbound 80/443 from LBSG.
|
||||||
|
|
||||||
|
EB will create a security group for the EC2 instances. In addition to this, you can create a new security group that will be applied to EC2 instances the elastic scaler creates.
|
||||||
|
|
||||||
|
This is set under `aws:autoscaling:launchconfiguration`.
|
||||||
|
|
||||||
|
### <a name='RDS'></a>RDS
|
||||||
|
|
||||||
|
Should set: inbound 5432 from Scaling SG + home ip (change port and home ip).
|
||||||
|
|
||||||
|
The database should have a security group creating that allows incoming connections from the EC2 instances only.
|
||||||
|
|
||||||
|
### <a name='SecuritygrouptoallowEC2instancestotalktoeachother'></a>Security group to allow EC2 instances to talk to each other
|
||||||
|
|
||||||
|
Security group rule to allow instances in the same security group to talk to one another: <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/security-group-rules-reference.html#sg-rules-other-instances>.
|
||||||
|
|
||||||
|
## <a name='CustomVPCSubnetsinEB'></a>Custom VPC + Subnets in EB
|
||||||
|
|
||||||
|
In a `.config` file specify the subnets for each tier of your app:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
option_settings:
|
||||||
|
aws:ec2:vpc:
|
||||||
|
VPCId: "vpc-003597eb63a0a3efe"
|
||||||
|
Subnets: "subnet-02cd8f7981ddfe345,subnet-02d9e1338e8d92d09,subnet-0e07d4d35394db524"
|
||||||
|
DBSubnets: "subnet-02cd8f7981ddfe345,subnet-02d9e1338e8d92d09,subnet-0e07d4d35394db524"
|
||||||
|
```
|
||||||
|
|
||||||
|
## <a name='UsingcloudformationfunctionsinEBconfigfiles'></a>Using cloudformation functions in EB config files
|
||||||
|
|
||||||
|
Only certain CF functions can be used in EB config files. For anything more advanced you should use Terraform to deploy additional resources alongside an EB template.
|
||||||
|
|
||||||
|
Reddit discussion on the topic: <https://www.reddit.com/r/aws/comments/a2uoae/is_there_a_way_to_reference_an_elastic_beanstalk/>.
|
||||||
|
|
||||||
|
EB documentaion on what functions are supported: <https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/ebextensions-functions.html#ebextensions-functions-getatt>.
|
||||||
|
|
||||||
|
You cannot use `FN::ImportValue` to reference a resource in another Cloudformation stack.
|
||||||
|
|
||||||
|
You can use join for resources that EB creates itself: `!Join [ ":", [ !Ref "AWS::StackName", AccountVPC ] ]`.
|
||||||
|
|
||||||
|
## <a name='CreatingareadreplicaRDS'></a>Creating a read replica RDS
|
||||||
|
|
||||||
|
To have a replica database you should create a new DB instance with same AllocatedStorage size and DBInstanceClass. You should set the SourceDBInstanceIdentifier to be a `!Ref` of your primary DB. You should also set the SourceRegion.
|
||||||
|
|
||||||
|
Read replica CF docs: <https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-rds-database-instance.html#cfn-rds-dbinstance-sourcedbinstanceidentifier>
|
||||||
|
|
||||||
|
## <a name='Multiplesecuritygroupsonthesameresource'></a>Multiple security groups on the same resource
|
||||||
|
|
||||||
|
Multiple security groups get squashed to determine what is and isn't allowed: <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html>.
|
||||||
|
|
||||||
|
## <a name='Privatesubnets'></a>Private subnets
|
||||||
|
|
||||||
|
You can create private subnets that do not have an internet gateway attached to them. An example of CF template is <https://github.com/awsdocs/elastic-beanstalk-samples/blob/master/cfn-templates/vpc-privatepublic.yaml>.
|
||||||
|
|
||||||
|
You need a nat gateway to allow private subnets to go out to the internet.
|
||||||
|
|
||||||
|
If you use private subnets, the nat gateway is not cheap - £30 a month.
|
||||||
|
|
||||||
|
You dont need the nat gateway, you can achieve the same thing with security groups (block all incoming) (explained <https://www.reddit.com/r/aws/comments/75bjei/private_subnets_nats_vs_simply_only_allowing/>).
|
||||||
|
|
||||||
|
An advantage to NAT is all outgoing requests to the internet come from a single IP.
|
||||||
|
|
||||||
|
## Using certbot CLI to generate SSL
|
||||||
|
|
||||||
|
### Wildcard certificate
|
||||||
|
|
||||||
|
In a new virtualenv install certbot:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install certbot
|
||||||
|
```
|
||||||
|
|
||||||
|
Run the `certbot` command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo certbot certonly --manual --preferred-challenges=dns --email dtomlinson@panaetius.co.uk --server https://acme-v02.api.letsencrypt.org/directory --agree-tos -d "*.panaetius.co.uk"
|
||||||
|
```
|
||||||
|
|
||||||
|
Follow the instructions to add a `TXT` record to your DNS server for validation.
|
||||||
|
|
||||||
|
When finished you should see:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
- Congratulations! Your certificate and chain have been saved at:
|
||||||
|
/etc/letsencrypt/live/panaetius.co.uk/fullchain.pem
|
||||||
|
Your key file has been saved at:
|
||||||
|
/etc/letsencrypt/live/panaetius.co.uk/privkey.pem
|
||||||
|
Your cert will expire on 2020-08-01. To obtain a new or tweaked
|
||||||
|
version of this certificate in the future, simply run certbot
|
||||||
|
again. To non-interactively renew _all_ of your certificates, run
|
||||||
|
"certbot renew"
|
||||||
|
- Your account credentials have been saved in your Certbot
|
||||||
|
configuration directory at /etc/letsencrypt. You should make a
|
||||||
|
secure backup of this folder now. This configuration directory will
|
||||||
|
also contain certificates and private keys obtained by Certbot so
|
||||||
|
making regular backups of this folder is ideal.
|
||||||
|
```
|
||||||
|
|
||||||
|
## Terraform
|
||||||
|
|
||||||
|
### Elastic Beanstalk
|
||||||
|
|
||||||
|
Editing the EB default resources in Terraform: <https://github.com/cloudposse/terraform-aws-elastic-beanstalk-environment/issues/98#issuecomment-620677233>.
|
||||||
|
|||||||
121
todo.md
121
todo.md
@@ -1,111 +1,72 @@
|
|||||||
# To Do
|
# To Do
|
||||||
|
|
||||||
~~Finish S3 config for env vars~~
|
## Immediate
|
||||||
~~Deploy to AWS and ensure vars are working~~
|
|
||||||
|
|
||||||
~~Use cloudformation to deploy bucket instead of tieing it to the RDS instance.~~
|
Merge the CF templates into one, make sure all the importing and other snippets are documented.
|
||||||
Use <https://strapi.io/documentation/3.0.0-beta.x/deployment/amazon-aws.html#_2-create-the-bucket> for bucket options for the template.
|
|
||||||
|
|
||||||
~~Strapi documentation - build and host~~
|
- Create single instance deployment + https (document)
|
||||||
|
- For https: use letsencrypt to generate ssl, configure the eb config to use this.
|
||||||
|
- Final git branch for each version of the app (load balanced https/http, single http/https).
|
||||||
|
- Terraform it all up (excluding single + https).
|
||||||
|
|
||||||
## RDS Cloudformation
|
## Long term
|
||||||
|
|
||||||
Use <http://blog.blackninjadojo.com/aws/elastic-beanstalk/2019/01/28/adding-a-database-to-your-rails-application-on-elastic-beanstalk-using-rds.html> to create an RDS for ELB.
|
|
||||||
|
|
||||||
- RDS cloudformation template
|
|
||||||
- Use the GUI to go through options and create cloudformation template
|
|
||||||
- Create an RDS db before deployment
|
|
||||||
- Configure Strapi to use this RDS db
|
|
||||||
- VPC + Security Group needs creating in template
|
|
||||||
|
|
||||||
Compare the `--database option` to without and make sure you create everything in the Cloudformation template.
|
|
||||||
|
|
||||||
Look at how to have multiple environments in the same elb app
|
|
||||||
|
|
||||||
Deploy strapi as load balanced rather than single instance
|
|
||||||
|
|
||||||
Deploy strapi with a custom domain with HTTPS as a single instance + load balanced.
|
|
||||||
|
|
||||||
Combine ELB Documentations (strapi, ELB etc)
|
|
||||||
|
|
||||||
Use codebuild to update strapi
|
Use codebuild to update strapi
|
||||||
|
|
||||||
Use circle CI instead
|
Use circle CI instead
|
||||||
|
|
||||||
Finish the backgrounds for the demo website
|
|
||||||
|
|
||||||
Cloudformation template to deploy an S3 bucket
|
Cloudformation template to deploy an S3 bucket
|
||||||
|
|
||||||
## Links
|
## Documentation
|
||||||
|
|
||||||
Decouple an exisitng RDS instance from ELB to RDS: <https://aws.amazon.com/premiumsupport/knowledge-center/decouple-rds-from-beanstalk/>
|
Summarise the flow -> VPC, internet gateway, attachment + route tables, subnets etc. Mention the nat gateway but show how it can be replaced with security groups. Document each individual resource needed bullet point and link to the git repo for the TF/CF templates.
|
||||||
|
|
||||||
Deploy the ELB environment referencing the VPC + Subnets created with Cloudformation. Use https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/vpc-rds.html as a reference.
|
## Running Notes
|
||||||
|
|
||||||
This works! Create all the VPC + Subnet resources using Cloudformation and specify them in option settings:
|
Various deployments:
|
||||||
|
|
||||||
```yaml
|
- Single instance with EBCLI
|
||||||
option_settings:
|
- Load balanced with EBCLI
|
||||||
aws:ec2:vpc:
|
|
||||||
VPCId: "vpc-003597eb63a0a3efe"
|
|
||||||
Subnets: "subnet-02cd8f7981ddfe345,subnet-02d9e1338e8d92d09,subnet-0e07d4d35394db524"
|
|
||||||
DBSubnets: "subnet-02cd8f7981ddfe345,subnet-02d9e1338e8d92d09,subnet-0e07d4d35394db524"
|
|
||||||
```
|
|
||||||
|
|
||||||
Recreate env with database, check the DB subnets - are they the same as the EC2 subnets? If so we can reference them in https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/command-options-general.html#command-options-general-ec2vpc with ELBSubnets
|
- Single instance with terraform
|
||||||
|
- Load balanced with terraform
|
||||||
|
|
||||||
Can we use cloudformation functions (imports) in .config files under option_settings? (reference a VPC that already exists?) (https://www.reddit.com/r/aws/comments/a2uoae/is_there_a_way_to_reference_an_elastic_beanstalk/) Yes?
|
HTTP + HTTPS
|
||||||
Yes but only certain functions: <https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/ebextensions-functions.html#ebextensions-functions-getatt>. You cannot use FN::ImportValue to reference a resource in another Cloudformation stack.
|
|
||||||
|
|
||||||
Use join for subnets Name: !Join [ ":", [ !Ref "AWS::StackName", AccountVPC ] ]
|
Single instance with terraform isn't possible with HTTPS - this is because you can't edit `Resources` or `Files` (and the other advanced EB configs). A workaround would be to create a docker image.
|
||||||
|
|
||||||
Updating 07 config to accept a parameter
|
Single instance with EBCLI isn't possible with HTTPS if you're using Certificate Manager to generate the certificates - this is because you need to edit the nginx proxy config locally on the instance to allow https. You don't have access to the private certificate with Cerficiate Manager.
|
||||||
|
One solution would be to generate your SSL using letsencrypt - then configure the instance with this.
|
||||||
|
|
||||||
For DB
|
Another solution would be to use Docker and build a custom image. In this image you could install and configure nginx, (using lets encrypt as multistage build to get your certificate).
|
||||||
|
|
||||||
Follow <https://github.com/garystafford/aws-rds-postgres/blob/master/cfn-templates/rds.template>
|
HTTPS for load balanced environment just requires pointing a domain to the EB endpoint. You can tell the load balancer to forward 443 in the security group without using it.
|
||||||
|
|
||||||
Create a subnet group (add each subnet to this group)
|
For final deployment - use an EC2 instance (deploy with TF).
|
||||||
Create a security Group for DB
|
|
||||||
Create a SecurityGroupIngress
|
|
||||||
Use existing public VPC and subnet
|
|
||||||
|
|
||||||
What is the RDS hostname inside the container?
|
### Other
|
||||||
|
|
||||||
Follow a naming convention for likewise cloudformation templates
|
Work:
|
||||||
|
Can we use APIGateway + Fargate to run an API containerised?
|
||||||
|
|
||||||
E.g.
|
Fargate documentation: <https://aws.amazon.com/fargate/>.
|
||||||
|
Fargate option in ECS terraform: <https://www.terraform.io/docs/providers/aws/r/ecs_service.html#launch_type>.
|
||||||
|
Lambda vs Fargate differences: <https://www.learnaws.org/2019/09/14/deep-dive-aws-fargate/>.
|
||||||
|
Fargate vs EC2 pricing: <https://www.reddit.com/r/aws/comments/8reem9/fargate_t2small_cost_comparison_dollar_to_dollar/>.
|
||||||
|
Reddit thread on using API Gateway + Fargate: <https://www.reddit.com/r/aws/comments/bgqz4g/can_api_gateway_route_to_a_container_in_fargate/>.
|
||||||
|
Using API Gateway + Private endpoints (in a VPC): <https://aws.amazon.com/blogs/compute/introducing-amazon-api-gateway-private-endpoints/>.
|
||||||
|
|
||||||
```yaml
|
Fargate is just running containers serverless - but it isn't a direct replacement to lambda. The spin up times can be long, but if you need to run a task on a schedule and this doesn't matter, you can save money and time as you don't need to manage and run an EC2 instance for docker containers. It's not ideal for tasks that need to be running 24/7.
|
||||||
Outputs:
|
|
||||||
PublicVPCID:
|
|
||||||
Description: The VPC ID.
|
|
||||||
Value: !Ref PublicVPC
|
|
||||||
Export:
|
|
||||||
Name: !Sub "${AWS::StackName}-ELBStrapiPublicVPC"
|
|
||||||
```
|
|
||||||
|
|
||||||
Defines a VPC. We can then pass in the stackname to another CF template and it can reference this VPC. The VPC names are static between projects (they don't have to be but here they are).
|
Have a seperate repos for Terraform + Ansible. Split them inside by project. One central place for all TF and Ansible will make things easier to reference from later.
|
||||||
|
|
||||||
Do we need a seperate security group for the database? - The answer should be that there is a seperate security group for RDS, and one for EC2. EC2 one should be created by ELB automatically. - This is true. The RDS one is created in CF.
|
Generate SSH keys for EC2.
|
||||||
|
Provision EC2 using TF - set SG to allow SSH from your IP.
|
||||||
|
Configure EC2 with an Ansible playbook.
|
||||||
|
|
||||||
Does the db and the ec2 instances share the same VPC? - Yes. They have different security groups.
|
## Single options
|
||||||
|
|
||||||
To Do
|
- Dockerise it + run on EC2/ECS/Fargate
|
||||||
|
- Use EBCLI + Config options for https. Generate SSL using lets encrypt.
|
||||||
|
Using certbot with docker: <https://certbot.eff.org/docs/install.html#running-with-docker>
|
||||||
|
|
||||||
To have a replica database you should create a new DB instance with same AllocatedStorage size and DBInstanceClass. You should set the SourceDBInstanceIdentifier to be a `!Ref` of your primary DB. You should also set the SourceRegion.
|
Forcing http > https redirection: <https://github.com/awsdocs/elastic-beanstalk-samples/tree/master/configuration-files/aws-provided/security-configuration/https-redirect/nodejs>.
|
||||||
|
|
||||||
CF RDS ELB template:
|
|
||||||
https://github.com/garystafford/aws-rds-postgres/blob/master/cfn-templates/rds.template
|
|
||||||
|
|
||||||
Read replica CF docs:
|
|
||||||
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-rds-database-instance.html#cfn-rds-dbinstance-sourcedbinstanceidentifier
|
|
||||||
|
|
||||||
Doc the CF changes for both
|
|
||||||
Combine them into a single CF stack
|
|
||||||
Deploy
|
|
||||||
|
|
||||||
Deploy strapi with LB + scaling
|
|
||||||
Enable HTTPS
|
|
||||||
|
|
||||||
Codebuild
|
|
||||||
|
|||||||
Reference in New Issue
Block a user