-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathcfn-application.yaml
146 lines (130 loc) · 4.89 KB
/
cfn-application.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
AWSTemplateFormatVersion: 2010-09-09
Description: |
CloudFormation stack of an application with web servers running in private
subnets as an autoscaling group (ASG), behind an application load balancer
(ELB) running in public subnets. Also has a Bastion server running in public
subnet as a SSH jump server to web servers in private subnets.
# References & Resources:
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/quickref-autoscaling.html
Parameters:
networkStack:
Description: Name of the Network CloudFormation stack
Type: String
Default: demoVpc
ec2Key:
Description: PEM key to access EC2 instances
Type: AWS::EC2::KeyPair::KeyName
Default: demoKey
# This EC2 key has to be created before creating this stack
Mappings:
amisByRegion:
us-east-1:
amzlinux2: ami-0c2b8ca1dad447f8a
# Add appropriate AMI ids to run build this stack in other regions
Resources:
bastionLaunchTemplate:
Type: AWS::EC2::LaunchTemplate
Properties:
LaunchTemplateName: !Sub ${AWS::StackName}-lt-bastion
LaunchTemplateData:
ImageId: !FindInMap [amisByRegion, us-east-1, amzlinux2]
InstanceType: t3.nano
KeyName: !Ref ec2Key
DisableApiTermination: true
NetworkInterfaces:
- AssociatePublicIpAddress: true
Groups:
- Fn::ImportValue: !Sub ${networkStack}-sg-bastion
DeviceIndex: 0
bastionAutoScaledInstance:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
AutoScalingGroupName: !Sub ${AWS::StackName}-asi-bastion
VPCZoneIdentifier:
- Fn::ImportValue: !Sub ${networkStack}-sn-public1
LaunchTemplate:
LaunchTemplateId: !Ref bastionLaunchTemplate
Version: !GetAtt bastionLaunchTemplate.LatestVersionNumber
DesiredCapacity: "1"
MinSize: "1"
MaxSize: "1"
HealthCheckGracePeriod: 300
webserverLaunchTemplate:
Type: AWS::EC2::LaunchTemplate
Properties:
LaunchTemplateName: !Sub ${AWS::StackName}-lt-webserver
LaunchTemplateData:
ImageId: !FindInMap [amisByRegion, us-east-1, amzlinux2]
InstanceType: t3.nano
KeyName: !Ref ec2Key
# ⚠️ Warning: Don't use the bastion key for app servers in production.
# You may even avoid bastions & EC2 keys using alternatives like SSM.
SecurityGroupIds:
- Fn::ImportValue: !Sub ${networkStack}-sg-admin
- Fn::ImportValue: !Sub ${networkStack}-sg-web
UserData: !Base64 |
#!/bin/bash
sudo su
yum update -y
yum install -y httpd.x86_64
curl -o /var/www/html/index.html https://httpbin.org/ip
cat <<-ENDOFHEREFILE >>/var/www/html/index.html
Above is the source IP address of requests from private SNs.
This IP address is the Elastic IP of the NAT Gateway.
ENDOFHEREFILE
echo "Hostname: $(hostname -f)" >>/var/www/html/index.html
systemctl enable httpd.service
systemctl start httpd.service
webserverElasticLoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Name: !Sub ${AWS::StackName}-elb-webserver
SecurityGroups:
- Fn::ImportValue: !Sub ${networkStack}-sg-web
Subnets:
- Fn::ImportValue: !Sub ${networkStack}-sn-public1
- Fn::ImportValue: !Sub ${networkStack}-sn-public2
webserverElbTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
Name: !Sub ${AWS::StackName}-elb-tg-webserver
HealthCheckIntervalSeconds: 300
Port: 80
Protocol: HTTP
TargetGroupAttributes:
- Key: load_balancing.algorithm.type
Value: round_robin # This is default.
# The other algorithm is least_outstanding_requests.
VpcId:
Fn::ImportValue: !Sub ${networkStack}-custVpcId
webserversAutoScalingGroup:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
AutoScalingGroupName: !Sub ${AWS::StackName}-asg-webserver
VPCZoneIdentifier:
- Fn::ImportValue: !Sub ${networkStack}-sn-private1
- Fn::ImportValue: !Sub ${networkStack}-sn-private2
LaunchTemplate:
LaunchTemplateId: !Ref webserverLaunchTemplate
Version: !GetAtt webserverLaunchTemplate.LatestVersionNumber
DesiredCapacity: "2"
MinSize: "2"
MaxSize: "2"
HealthCheckGracePeriod: 300
MaxInstanceLifetime: 2592000
TargetGroupARNs:
- !Ref webserverElbTargetGroup
webserverElbListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
LoadBalancerArn: !Ref webserverElasticLoadBalancer
Port: 80
Protocol: HTTP
DefaultActions:
- Type: forward
TargetGroupArn: !Ref webserverElbTargetGroup
Outputs:
webserverElbDnsName:
Value: !GetAtt webserverElasticLoadBalancer.DNSName
Export:
Name: !Sub ${AWS::StackName}-elb-webserver-dnsname