Skip to content
This repository was archived by the owner on Feb 11, 2020. It is now read-only.

Commit 979bb02

Browse files
author
Chris Mills
authored
Merge pull request #13 from TransformCore/feature/deployment
Update configuration so it works with 0.12
2 parents efbfd8c + f3c319a commit 979bb02

File tree

8 files changed

+215
-68
lines changed

8 files changed

+215
-68
lines changed

.github/actions/Dockerfile

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
FROM r.j3ss.co/terraform:latest
2+
3+
LABEL "com.github.actions.name"="AWS Fargate"
4+
LABEL "com.github.actions.description"="Deploy to AWS Fargate on push to the master branch"
5+
LABEL "com.github.actions.icon"="cloud"
6+
LABEL "com.github.actions.color"="red"
7+
8+
RUN apk add --no-cache \
9+
git \
10+
make
11+
12+
COPY ../../terraform /usr/src/terraform
13+
COPY Makefile /usr/src
14+
COPY deploy.sh /usr/local/bin/deploy
15+
16+
WORKDIR /usr/src
17+
18+
ENTRYPOINT ["deploy"]

.github/actions/Makefile

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
SHELL := /bin/bash
2+
AWS_REGION := ${AWS_REGION}
3+
AWS_ACCESS_KEY_ID := ${AWS_ACCESS_KEY_ID}
4+
AWS_SECRET_ACCESS_KEY := ${AWS_SECRET_ACCESS_KEY}
5+
IMAGE := ${IMAGE}
6+
PORT := ${PORT}
7+
COUNT := ${COUNT}
8+
CPU := ${CPU}
9+
MEMORY := ${MEMORY}
10+
BUCKET := ${BUCKET}
11+
12+
AWS_DIR=$(CURDIR)/terraform/amazon
13+
TERRAFORM_FLAGS :=
14+
AWS_TERRAFORM_FLAGS = -var "region=$(AWS_REGION)" \
15+
-var "access_key=$(AWS_ACCESS_KEY_ID)" \
16+
-var "secret_key=$(AWS_SECRET_ACCESS_KEY)" \
17+
-var "image=$(IMAGE)" \
18+
-var "port=$(PORT)" \
19+
-var "count=$(COUNT)" \
20+
-var "cpu=$(CPU)" \
21+
-var "memory=$(MEMORY)" \
22+
-var "bucket=$(BUCKET)"
23+
24+
.PHONY: aws-init
25+
aws-init:
26+
@:$(call check_defined, AWS_REGION, Amazon Region)
27+
@:$(call check_defined, AWS_ACCESS_KEY_ID, Amazon Access Key ID)
28+
@:$(call check_defined, AWS_SECRET_ACCESS_KEY, Amazon Secret Access Key)
29+
@:$(call check_defined, IMAGE, Docker image to run)
30+
@:$(call check_defined, PORT, Port to expose)
31+
@:$(call check_defined, COUNT, Number of containers to run)
32+
@:$(call check_defined, CPU, Fargate instance CPU units to provision (1 vCPU = 1024 CPU units))
33+
@:$(call check_defined, MEMORY, Fargate instance memory to provision (in MiB))
34+
@:$(call check_defined, BUCKET, s3 bucket name to store the terraform state)
35+
@cd $(AWS_DIR) && terraform init \
36+
-backend-config "bucket=$(BUCKET)" \
37+
-backend-config "region=$(AWS_REGION)" \
38+
$(AWS_TERRAFORM_FLAGS)
39+
40+
.PHONY: terraform-validate
41+
terraform-validate: ## Validate terraform scripts.
42+
@cd $(AWS_DIR) && echo "$$(docker run --rm -it --entrypoint bash -w '/mnt' -v $$(pwd):/mnt r.j3ss.co/terraform -c 'terraform validate -check-variables=false . && echo [OK] terraform')"
43+
44+
.PHONY: aws-plan
45+
aws-plan: aws-init ## Run terraform plan for Amazon.
46+
@cd $(AWS_DIR) && terraform plan \
47+
$(AWS_TERRAFORM_FLAGS)
48+
49+
.PHONY: aws-apply
50+
aws-apply: aws-init ## Run terraform apply for Amazon.
51+
@cd $(AWS_DIR) && terraform apply \
52+
$(AWS_TERRAFORM_FLAGS) \
53+
$(TERRAFORM_FLAGS)
54+
55+
.PHONY: aws-destroy
56+
aws-destroy: aws-init ## Run terraform destroy for Amazon.
57+
@cd $(AWS_DIR) && terraform destroy \
58+
$(AWS_TERRAFORM_FLAGS)
59+
60+
check_defined = \
61+
$(strip $(foreach 1,$1, \
62+
$(call __check_defined,$1,$(strip $(value 2)))))
63+
__check_defined = \
64+
$(if $(value $1),, \
65+
$(error Undefined $1$(if $2, ($2))$(if $(value @), \
66+
required by target `$@')))
67+
68+
.PHONY: update
69+
update: update-terraform ## Update terraform binary locally.
70+
71+
TERRAFORM_BINARY:=$(shell which terraform || echo "/usr/local/bin/terraform")
72+
TMP_TERRAFORM_BINARY:=/tmp/terraform
73+
.PHONY: update-terraform
74+
update-terraform: ## Update terraform binary locally from the docker container.
75+
@echo "Updating terraform binary..."
76+
$(shell docker run --rm --entrypoint bash r.j3ss.co/terraform -c "cd \$\$$(dirname \$\$$(which terraform)) && tar -Pc terraform" | tar -xvC $(dir $(TMP_TERRAFORM_BINARY)) > /dev/null)
77+
sudo mv $(TMP_TERRAFORM_BINARY) $(TERRAFORM_BINARY)
78+
sudo chmod +x $(TERRAFORM_BINARY)
79+
@echo "Update terraform binary: $(TERRAFORM_BINARY)"
80+
@terraform version
81+
82+
.PHONY: test
83+
test: terraform-validate shellcheck ## Runs the tests on the repository.
84+
85+
# if this session isn't interactive, then we don't want to allocate a
86+
# TTY, which would fail, but if it is interactive, we do want to attach
87+
# so that the user can send e.g. ^C through.
88+
INTERACTIVE := $(shell [ -t 0 ] && echo 1 || echo 0)
89+
ifeq ($(INTERACTIVE), 1)
90+
DOCKER_FLAGS += -t
91+
endif
92+
93+
.PHONY: shellcheck
94+
shellcheck: ## Runs the shellcheck tests on the scripts.
95+
docker run --rm -i $(DOCKER_FLAGS) \
96+
--name shellcheck \
97+
-v $(CURDIR):/usr/src:ro \
98+
--workdir /usr/src \
99+
r.j3ss.co/shellcheck ./test.sh
100+
101+
.PHONY: help
102+
help:
103+
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
104+

.github/actions/deploy.sh

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#!/bin/bash
2+
set -e
3+
set -o pipefail
4+
5+
if [[ "$GITHUB_REF" != "refs/heads/master" ]]; then
6+
echo "$GITHUB_REF was not master, exiting..."
7+
exit 0
8+
fi
9+
10+
echo "On branch ${GITHUB_REF}, deploying..."
11+
12+
(
13+
cd /usr/src
14+
make aws-apply TERRAFORM_FLAGS=-auto-approve
15+
)

.github/main.workflow

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ action "Deploy to Fargate" {
4646
COUNT = "2"
4747
CPU = "256"
4848
MEMORY = "512"
49-
BUCKET = "et-dash-action"
49+
BUCKET = "et-dash-actions"
5050
}
5151
secrets = ["AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY"]
5252
}

terraform/ecs.tf

Lines changed: 36 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## Most of this is taken from https://github.com/jessfraz/aws-fargate-action
2+
## Because I am super lazy and stuck for time
3+
## Updated it so it's not old and doesn't work.
4+
15
### Network
26

37
# Fetch availability zones in the current region.
@@ -9,63 +13,63 @@ resource "aws_vpc" "main" {
913

1014
# Create var.az_count private subnets, each in a different availability zone.
1115
resource "aws_subnet" "private" {
12-
count = "${var.az_count}"
13-
cidr_block = "${cidrsubnet(aws_vpc.main.cidr_block, 8, count.index)}"
14-
availability_zone = "${data.aws_availability_zones.available.names[count.index]}"
15-
vpc_id = "${aws_vpc.main.id}"
16+
count = var.az_count
17+
cidr_block = cidrsubnet(aws_vpc.main.cidr_block, 8, count.index)
18+
availability_zone = data.aws_availability_zones.available.names[count.index]
19+
vpc_id = aws_vpc.main.id
1620
}
1721

1822
# Create var.az_count public subnets, each in a different availability zone.
1923
resource "aws_subnet" "public" {
20-
count = "${var.az_count}"
21-
cidr_block = "${cidrsubnet(aws_vpc.main.cidr_block, 8, var.az_count + count.index)}"
22-
availability_zone = "${data.aws_availability_zones.available.names[count.index]}"
23-
vpc_id = "${aws_vpc.main.id}"
24+
count = var.az_count
25+
cidr_block = cidrsubnet(aws_vpc.main.cidr_block, 8, var.az_count + count.index)
26+
availability_zone = data.aws_availability_zones.available.names[count.index]
27+
vpc_id = aws_vpc.main.id
2428
map_public_ip_on_launch = true
2529
}
2630

2731
# Internet gateway for the public subnet.
2832
resource "aws_internet_gateway" "gw" {
29-
vpc_id = "${aws_vpc.main.id}"
33+
vpc_id = aws_vpc.main.id
3034
}
3135

3236
# Route the public subnet traffic through the internet gateway.
3337
resource "aws_route" "internet_access" {
34-
route_table_id = "${aws_vpc.main.main_route_table_id}"
38+
route_table_id = aws_vpc.main.main_route_table_id
3539
destination_cidr_block = "0.0.0.0/0"
36-
gateway_id = "${aws_internet_gateway.gw.id}"
40+
gateway_id = aws_internet_gateway.gw.id
3741
}
3842

3943
# Create a NAT gateway with an EIP for each private subnet to get internet connectivity.
4044
resource "aws_eip" "gw" {
41-
count = "${var.az_count}"
45+
count = var.az_count
4246
vpc = true
43-
depends_on = ["aws_internet_gateway.gw"]
47+
depends_on = aws_internet_gateway.gw
4448
}
4549

4650
resource "aws_nat_gateway" "gw" {
47-
count = "${var.az_count}"
48-
subnet_id = "${element(aws_subnet.public.*.id, count.index)}"
49-
allocation_id = "${element(aws_eip.gw.*.id, count.index)}"
51+
count = var.az_count
52+
subnet_id = element(aws_subnet.public.*.id, count.index)
53+
allocation_id = element(aws_eip.gw.*.id, count.index)
5054
}
5155

5256
# Create a new route table for the private subnets.
5357
# And make it route non-local traffic through the NAT gateway to the internet.
5458
resource "aws_route_table" "private" {
55-
count = "${var.az_count}"
56-
vpc_id = "${aws_vpc.main.id}"
59+
count = var.az_count
60+
vpc_id = aws_vpc.main.id
5761

5862
route {
5963
cidr_block = "0.0.0.0/0"
60-
nat_gateway_id = "${element(aws_nat_gateway.gw.*.id, count.index)}"
64+
nat_gateway_id = element(aws_nat_gateway.gw.*.id, count.index)
6165
}
6266
}
6367

6468
# Explicitely associate the newly created route tables to the private subnets (so they don't default to the main route table).
6569
resource "aws_route_table_association" "private" {
66-
count = "${var.az_count}"
67-
subnet_id = "${element(aws_subnet.private.*.id, count.index)}"
68-
route_table_id = "${element(aws_route_table.private.*.id, count.index)}"
70+
count = var.az_count
71+
subnet_id = element(aws_subnet.private.*.id, count.index)
72+
route_table_id = element(aws_route_table.private.*.id, count.index)
6973
}
7074

7175
### Security
@@ -75,7 +79,7 @@ resource "aws_route_table_association" "private" {
7579
resource "aws_security_group" "ecs_lb" {
7680
name = "ecs-lb"
7781
description = "controls access to the ALB"
78-
vpc_id = "${aws_vpc.main.id}"
82+
vpc_id = aws_vpc.main.id
7983

8084
ingress {
8185
protocol = "tcp"
@@ -96,13 +100,13 @@ resource "aws_security_group" "ecs_lb" {
96100
resource "aws_security_group" "ecs_tasks" {
97101
name = "ecs-tasks"
98102
description = "allow inbound access from the ALB only"
99-
vpc_id = "${aws_vpc.main.id}"
103+
vpc_id = aws_vpc.main.id
100104

101105
ingress {
102106
protocol = "tcp"
103-
from_port = "${var.port}"
104-
to_port = "${var.port}"
105-
security_groups = ["${aws_security_group.ecs_lb.id}"]
107+
from_port = var.port
108+
to_port = var.port
109+
security_groups = [aws_security_group.ecs_lb.id]
106110
}
107111

108112
egress {
@@ -116,26 +120,26 @@ resource "aws_security_group" "ecs_tasks" {
116120
### Load balancer.
117121
resource "aws_alb" "main" {
118122
name = "github-actions-deploy"
119-
subnets = ["${aws_subnet.public.*.id}"]
120-
security_groups = ["${aws_security_group.ecs_lb.id}"]
123+
subnets = [aws_subnet.public.*.id]
124+
security_groups = [aws_security_group.ecs_lb.id]
121125
}
122126

123127
resource "aws_alb_target_group" "app" {
124128
name = "github-actions-deploy"
125129
port = 80
126130
protocol = "HTTP"
127-
vpc_id = "${aws_vpc.main.id}"
131+
vpc_id = aws_vpc.main.id
128132
target_type = "ip"
129133
}
130134

131135
# Redirect all traffic from the load balancer to the target group.
132136
resource "aws_alb_listener" "front_end" {
133-
load_balancer_arn = "${aws_alb.main.id}"
137+
load_balancer_arn = aws_alb.main.id
134138
port = "80"
135139
protocol = "HTTP"
136140

137141
default_action {
138-
target_group_arn = "${aws_alb_target_group.app.id}"
142+
target_group_arn = aws_alb_target_group.app.id
139143
type = "forward"
140144
}
141145
}

terraform/outputs.tf

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
output "alb_hostname" {
2-
value = "${aws_alb.main.dns_name}"
2+
value = aws_alb.main.dns_name
33
}
44

55
output "container_definitions" {
6-
value = "${local.container_definitions}"
6+
value = local.container_definitions
77
}

terraform/service.tf

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@ locals {
22
container_definitions = <<DEFINITION
33
[
44
{
5-
"cpu": ${var.cpu},
6-
"image": "${var.image}",
7-
"memory": ${var.memory},
5+
"cpu": var.cpu
6+
"image": var.image,
7+
"memory": var.memory,
88
"name": "app",
99
"networkMode": "awsvpc",
1010
"pseudoTerminal": true,
1111
"portMappings": [
1212
{
13-
"containerPort": ${var.port},
14-
"hostPort": ${var.port}
13+
"containerPort": var.port,
14+
"hostPort": var.port
1515
}
1616
]
1717
}
@@ -20,33 +20,33 @@ DEFINITION
2020
}
2121

2222
resource "aws_ecs_task_definition" "app" {
23-
family = "app"
24-
network_mode = "awsvpc"
23+
family = "app"
24+
network_mode = "awsvpc"
2525
requires_compatibilities = ["FARGATE"]
26-
cpu = "${var.cpu}"
27-
memory = "${var.memory}"
28-
task_role_arn = "arn:aws:iam::445220836204:role/ecsInstanceRole"
29-
execution_role_arn = "arn:aws:iam::445220836204:role/ecsInstanceRole"
26+
cpu = var.cpu
27+
memory = var.memory
28+
task_role_arn = "arn:aws:iam::445220836204:role/ecsInstanceRole"
29+
execution_role_arn = "arn:aws:iam::445220836204:role/ecsInstanceRole"
3030

31-
container_definitions = "${local.container_definitions}"
31+
container_definitions = local.container_definitions
3232
}
3333

3434
resource "aws_ecs_service" "main" {
35-
name = "tf-ecs-service"
36-
cluster = "${aws_ecs_cluster.main.id}"
37-
task_definition = "${aws_ecs_task_definition.app.arn}"
38-
desired_count = "${var.desired_count}"
39-
launch_type = "FARGATE"
35+
name = "tf-ecs-service"
36+
cluster = aws_ecs_cluster.main.id
37+
task_definition = aws_ecs_task_definition.app.arn
38+
desired_count = var.desired_count
39+
launch_type = "FARGATE"
4040

4141
network_configuration {
42-
security_groups = ["${aws_security_group.ecs_tasks.id}"]
43-
subnets = ["${aws_subnet.private.*.id}"]
42+
security_groups = [aws_security_group.ecs_tasks.id]
43+
subnets = [aws_subnet.private.*.id]
4444
}
4545

4646
load_balancer {
47-
target_group_arn = "${aws_alb_target_group.app.id}"
48-
container_name = "app"
49-
container_port = "${var.port}"
47+
target_group_arn = aws_alb_target_group.app.id
48+
container_name = "app"
49+
container_port = var.port
5050
}
5151

5252
depends_on = [

0 commit comments

Comments
 (0)