Skip to content

Commit d26329f

Browse files
ajschmidt8dekobon
authored andcommitted
Add documentation for using ECS with CloudFormation
1 parent d9b2aef commit d26329f

File tree

3 files changed

+309
-0
lines changed

3 files changed

+309
-0
lines changed

deployments/ecs/cloudformation/s3gateway.cf

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
AWSTemplateFormatVersion: '2010-09-09'
2+
Parameters:
3+
NewBucketName:
4+
Default: <ENTER_RANDOM_BUCKET_NAME_HERE>
5+
Description: S3 Bucket Name
6+
Type: String
7+
Subnet1:
8+
Default: <ENTER_YOUR_VALUE_HERE>
9+
Description: ID of the first subnet to be used for resources
10+
Type: String
11+
Subnet2:
12+
Default: <ENTER_YOUR_VALUE_HERE>
13+
Description: ID of the second subnet to be used for resources
14+
Type: String
15+
VpcId:
16+
Default: <ENTER_YOUR_VALUE_HERE>
17+
Description: ID of the VPC to be used for resources
18+
Type: String
19+
ContainerName:
20+
Default: s3gateway
21+
Description: Name of the NGINX Container. No need to change this
22+
Type: String
23+
ResourceNamePrefix:
24+
Default: nginx-s3-gateway
25+
Description: Common prefix used for resource names. No need to change this
26+
Type: String
27+
Outputs:
28+
PublicDNS:
29+
Description: DNS name of load balancer
30+
Value: !GetAtt 'ALB.DNSName'
31+
Resources:
32+
ALB:
33+
Properties:
34+
Name: !Join
35+
- '-'
36+
- - !Ref 'ResourceNamePrefix'
37+
- alb
38+
SecurityGroups:
39+
- !GetAtt 'S3GatewaySG.GroupId'
40+
SubnetMappings:
41+
- SubnetId: !Ref 'Subnet1'
42+
- SubnetId: !Ref 'Subnet2'
43+
Type: application
44+
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
45+
ALBHttpListener:
46+
Properties:
47+
DefaultActions:
48+
- ForwardConfig:
49+
TargetGroups:
50+
- TargetGroupArn: !Ref 'ALBTargetGroup'
51+
Type: forward
52+
LoadBalancerArn: !Ref 'ALB'
53+
Port: 80
54+
Protocol: HTTP
55+
Type: AWS::ElasticLoadBalancingV2::Listener
56+
ALBTargetGroup:
57+
Properties:
58+
Name: !Join
59+
- '-'
60+
- - !Ref 'ResourceNamePrefix'
61+
- log-group
62+
Port: 80
63+
Protocol: HTTP
64+
ProtocolVersion: HTTP1
65+
TargetGroupAttributes:
66+
- Key: deregistration_delay.timeout_seconds
67+
Value: '150'
68+
TargetType: ip
69+
VpcId: !Ref 'VpcId'
70+
Type: AWS::ElasticLoadBalancingV2::TargetGroup
71+
Cluster:
72+
Properties:
73+
ClusterName: !Join
74+
- '-'
75+
- - !Ref 'ResourceNamePrefix'
76+
- cluster
77+
Type: AWS::ECS::Cluster
78+
ECSLogGroup:
79+
Properties:
80+
LogGroupName: !Join
81+
- '-'
82+
- - !Ref 'ResourceNamePrefix'
83+
- logs
84+
RetentionInDays: 14
85+
Type: AWS::Logs::LogGroup
86+
ECSTaskExecutionPolicy:
87+
Properties:
88+
PolicyDocument:
89+
Statement:
90+
- Action:
91+
- logs:CreateLogStream
92+
- logs:CreateLogGroup
93+
- logs:PutLogEvents
94+
Effect: Allow
95+
Resource:
96+
- '*'
97+
Version: '2012-10-17'
98+
PolicyName: !Join
99+
- '-'
100+
- - !Ref 'ResourceNamePrefix'
101+
- ecs-task-execution-policy
102+
Roles:
103+
- !Ref 'ECSTaskExecutionRole'
104+
Type: AWS::IAM::Policy
105+
ECSTaskExecutionRole:
106+
Properties:
107+
AssumeRolePolicyDocument:
108+
Statement:
109+
- Action:
110+
- sts:AssumeRole
111+
Effect: Allow
112+
Principal:
113+
Service:
114+
- ecs-tasks.amazonaws.com
115+
Version: '2012-10-17'
116+
Description: An IAM role to enable ECS agents to perform AWS operations such as creating CloudWatch logs.
117+
RoleName: !Join
118+
- '-'
119+
- - !Ref 'ResourceNamePrefix'
120+
- ecs-task-execution-role
121+
Type: AWS::IAM::Role
122+
ECSTaskPolicy:
123+
Properties:
124+
PolicyDocument:
125+
Statement:
126+
- Action:
127+
- s3:GetObject
128+
- s3:ListBucket
129+
Effect: Allow
130+
Resource:
131+
- !Sub
132+
- arn:aws:s3:::${bucketName}/*
133+
- bucketName: !Ref 'NewBucketName'
134+
- !Sub
135+
- arn:aws:s3:::${bucketName}
136+
- bucketName: !Ref 'NewBucketName'
137+
Version: '2012-10-17'
138+
PolicyName: !Join
139+
- '-'
140+
- - !Ref 'ResourceNamePrefix'
141+
- ecs-task-policy
142+
Roles:
143+
- !Ref 'ECSTaskRole'
144+
Type: AWS::IAM::Policy
145+
ECSTaskRole:
146+
Properties:
147+
AssumeRolePolicyDocument:
148+
Statement:
149+
- Action:
150+
- sts:AssumeRole
151+
Effect: Allow
152+
Principal:
153+
Service:
154+
- ecs-tasks.amazonaws.com
155+
Version: '2012-10-17'
156+
Description: An IAM role to enable ECS containers to perform AWS operations such as accessing S3 buckets.
157+
RoleName: !Join
158+
- '-'
159+
- - !Ref 'ResourceNamePrefix'
160+
- ecs-task-role
161+
Type: AWS::IAM::Role
162+
S3Bucket:
163+
Properties:
164+
BucketName: !Ref 'NewBucketName'
165+
Type: AWS::S3::Bucket
166+
S3GatewaySG:
167+
Properties:
168+
GroupDescription: Security group for NGINX S3 Gateway Infra
169+
GroupName: !Join
170+
- '-'
171+
- - !Ref 'ResourceNamePrefix'
172+
- sg
173+
SecurityGroupEgress:
174+
- CidrIp: '0.0.0.0/0'
175+
Description: Allow all outbound IPv4 traffic
176+
IpProtocol: '-1'
177+
- CidrIpv6: ::/0
178+
Description: Allow all outbound IPv6 traffic
179+
IpProtocol: '-1'
180+
SecurityGroupIngress:
181+
- CidrIp: '0.0.0.0/0'
182+
Description: Allow HTTP Traffic on 80
183+
FromPort: 80
184+
IpProtocol: tcp
185+
ToPort: 80
186+
- CidrIp: '0.0.0.0/0'
187+
Description: Allow HTTPS Traffic on 443
188+
FromPort: 443
189+
IpProtocol: tcp
190+
ToPort: 443
191+
VpcId: !Ref 'VpcId'
192+
Type: AWS::EC2::SecurityGroup
193+
S3GatewayService:
194+
DependsOn: ALBHttpListener
195+
Properties:
196+
Cluster: !Ref 'Cluster'
197+
DesiredCount: 1
198+
LaunchType: FARGATE
199+
LoadBalancers:
200+
- ContainerName: !Ref 'ContainerName'
201+
ContainerPort: 80
202+
TargetGroupArn: !Ref 'ALBTargetGroup'
203+
NetworkConfiguration:
204+
AwsvpcConfiguration:
205+
AssignPublicIp: ENABLED
206+
SecurityGroups:
207+
- !GetAtt 'S3GatewaySG.GroupId'
208+
Subnets:
209+
- !Ref 'Subnet1'
210+
- !Ref 'Subnet2'
211+
ServiceName: !Join
212+
- '-'
213+
- - !Ref 'ResourceNamePrefix'
214+
- service
215+
TaskDefinition: !Ref 'TaskDefinition'
216+
Type: AWS::ECS::Service
217+
TaskDefinition:
218+
DependsOn: S3Bucket
219+
Properties:
220+
ContainerDefinitions:
221+
- Environment:
222+
- Name: ALLOW_DIRECTORY_LIST
223+
Value: 'true'
224+
- Name: AWS_SIGS_VERSION
225+
Value: '4'
226+
- Name: S3_BUCKET_NAME
227+
Value: !Ref 'S3Bucket'
228+
- Name: S3_REGION
229+
Value: !Ref 'AWS::Region'
230+
- Name: S3_SERVER_PORT
231+
Value: '443'
232+
- Name: S3_SERVER_PROTO
233+
Value: https
234+
- Name: S3_SERVER
235+
Value: !Join
236+
- .
237+
- - s3
238+
- !Ref 'AWS::Region'
239+
- amazonaws.com
240+
- Name: S3_STYLE
241+
Value: default
242+
- Name: S3_DEBUG
243+
Value: 'false'
244+
Image: ghcr.io/nginxinc/nginx-s3-gateway/nginx-oss-s3-gateway:latest-njs-oss
245+
LogConfiguration:
246+
LogDriver: awslogs
247+
Options:
248+
awslogs-group: !Ref 'ECSLogGroup'
249+
awslogs-region: !Ref 'AWS::Region'
250+
awslogs-stream-prefix: ecs
251+
Name: !Ref 'ContainerName'
252+
PortMappings:
253+
- ContainerPort: 80
254+
HostPort: 80
255+
Cpu: '1024'
256+
ExecutionRoleArn: !GetAtt 'ECSTaskExecutionRole.Arn'
257+
Family: !Ref 'ContainerName'
258+
Memory: '2048'
259+
NetworkMode: awsvpc
260+
RequiresCompatibilities:
261+
- FARGATE
262+
TaskRoleArn: !GetAtt 'ECSTaskRole.Arn'
263+
Type: AWS::ECS::TaskDefinition

docs/getting_started.md

+46
Original file line numberDiff line numberDiff line change
@@ -200,3 +200,49 @@ aws ec2 modify-instance-metadata-options --instance-id <instance id> \
200200
After that has been run we can start the container normally and omit the
201201
`S3_ACCESS_KEY_ID` and `S3_SECRET_KEY` environment variables.
202202

203+
### Running in ECS with an IAM Policy
204+
205+
The commands below all reference the [`deployments/ecs/cloudformation/s3gateway.cf`](/deployments/ecs/cloudformation/s3gateway.yaml) file. This file will need to be
206+
modified.
207+
208+
- Update the following 4 parameters in the `Parameters` section of the CloudFormation file for your specific AWS account:
209+
- `NewBucketName` - any S3 bucket name. Remember that S3 bucket names must be globally unique
210+
- `VpcId` - Any VPC ID on your AWS account
211+
- `Subnet1` - Any subnet ID that's in the VPC used above
212+
- `Subnet2` - Any subnet ID that's in the VPC used above
213+
- Run the following command to deploy the stack (this assumes you have the AWS CLI & credentials setup correctly on your host machine and you are running in the project root directory):
214+
215+
```sh
216+
aws cloudformation create-stack \
217+
--stack-name nginx-s3-gateway \
218+
--capabilities CAPABILITY_NAMED_IAM \
219+
--template-body file://deployments/ecs/cloudformation/s3gateway.yaml
220+
```
221+
222+
- Wait for the CloudFormation Stack deployment to complete
223+
(can take about 3-5 minutes)
224+
- You can query the stack status with this command:
225+
```sh
226+
aws cloudformation describe-stacks \
227+
--stack-name nginx-s3-gateway \
228+
--query "Stacks[0].StackStatus"
229+
```
230+
- Wait until the query above shows `"CREATE_COMPLETE"`
231+
- Run the following command to get the URL used to access the service:
232+
```sh
233+
aws cloudformation describe-stacks \
234+
--stack-name nginx-s3-gateway \
235+
--query "Stacks[0].Outputs[0].OutputValue"
236+
```
237+
- Upload a file to the bucket first to prevent getting a `404` when visiting
238+
the URL in your browser
239+
```sh
240+
# i.e.
241+
aws s3 cp README.md s3://<bucket_name>
242+
```
243+
- View the container logs in CloudWatch from the AWS web console
244+
- Run the following command to delete the stack and all resources:
245+
```sh
246+
aws cloudformation delete-stack \
247+
--stack-name nginx-s3-gateway
248+
```

0 commit comments

Comments
 (0)