diff --git a/README.md b/README.md index 80c6f29..76d9782 100644 --- a/README.md +++ b/README.md @@ -40,8 +40,9 @@ The goal of this effort is to provide tools/configuration files/scripts/other to - [x] Automatically deploy Docker containers when pushed to ECR - [x] Send container logs to CloudWatch - [x] Basic health information in CloudWatch Logs/Metrics +- [x] Optional NAT Gateway +- [ ] Optional Application Load Balancer - [ ] Auto Scaling group -- [ ] Development mode - No NAT Gateway, no Load Balancer - [ ] External Docker image deployment - No ECR registry for that service - [ ] Predefined alarms about container status - [ ] Predefined Docker images to simplify some aspects of deployment/runtime (ie. the image will be able to collect Node.js runtime metrics etc.) @@ -49,6 +50,7 @@ The goal of this effort is to provide tools/configuration files/scripts/other to ## Usage - [Basic][basic-usage] +- [HTTPS enabled][https-usage] ## LICENSE @@ -59,3 +61,4 @@ See the [LICENSE][license] file for information. [license]: LICENSE [diagram]: diagram.png [basic-usage]: examples/basic +[https-usage]: examples/https_enabled diff --git a/examples/basic/main.tf b/examples/basic/main.tf index 0e145dd..2c7d922 100644 --- a/examples/basic/main.tf +++ b/examples/basic/main.tf @@ -23,9 +23,6 @@ module "fargate" { registry_retention_count = 15 # Optional. 20 by default logs_retention_days = 14 # Optional. 30 by default - - # To activate SSL Listener (HTTPS) set the ARN of the ACM certificate here! 🔑 - # acm_certificate_arn = "arn:......" } } diff --git a/examples/https_enabled/Dockerfile b/examples/https_enabled/Dockerfile new file mode 100644 index 0000000..4ed9089 --- /dev/null +++ b/examples/https_enabled/Dockerfile @@ -0,0 +1,24 @@ +# Base +FROM node:alpine AS base +ENV HOME=/home/node +WORKDIR $HOME/app +RUN chown -R node:node $HOME/* +USER node +COPY package*.json ./ + +# Dependencies +FROM base AS dependencies +RUN npm set progress=false && npm config set depth 0 +RUN npm install --only=production +RUN cp -R node_modules prod_node_modules +RUN npm install + +# Release +FROM dependencies as release + +COPY --from=dependencies $HOME/app/prod_node_modules ./node_modules +COPY . . + +EXPOSE 3000 + +CMD ["node", "."] diff --git a/examples/https_enabled/README.md b/examples/https_enabled/README.md new file mode 100644 index 0000000..c407412 --- /dev/null +++ b/examples/https_enabled/README.md @@ -0,0 +1,27 @@ +# HTTPS enabled example + +## Usage + +To run this example you need to execute: + +```bash +$ terraform init +$ terraform plan +$ terraform apply +``` + +Also, you will need a valid ACM certificate (SSL/TLS) and associate it to the Fargate service you would like to enable HTTPS. + +Note that this example create resources which can cost money (AWS Fargate Services, for example). Run `terraform destroy` when you don't need these resources. + +## Outputs + +| Name | Description | +|------|-------------| +| vpc | VPC created for ECS cluster | +| ecr | ECR Docker registry for Docker images | +| ecs_cluster | ECS cluster | +| application_load_balancers | ALBs which expose ECS services | +| web_security_group | Security groups attached to ALBs | +| services_security_groups | Security groups attached to ECS services | +| cloudwatch_log_groups | CloudWatch groups for ECS services | diff --git a/examples/https_enabled/api.json b/examples/https_enabled/api.json new file mode 100644 index 0000000..e69de29 diff --git a/examples/https_enabled/index.js b/examples/https_enabled/index.js new file mode 100644 index 0000000..05ed74f --- /dev/null +++ b/examples/https_enabled/index.js @@ -0,0 +1,12 @@ +const express = require('express') +const os = require('os') + +const hostname = os.hostname() +const app = express() + +app.listen(3000, () => console.log(`Example app listening on port 3000! Host: ${hostname}`)) + +app.get('/', async (req, res) => res.json({ + hostname, + message: 'Look mommy, I\'m using HTTPS!' +})) diff --git a/examples/https_enabled/main.tf b/examples/https_enabled/main.tf new file mode 100644 index 0000000..e0775fc --- /dev/null +++ b/examples/https_enabled/main.tf @@ -0,0 +1,74 @@ +terraform { + required_version = "~> 0.11.11" +} + +provider "aws" { + version = "~> 1.54.0" + region = "us-east-1" + profile = "playground" +} + +## Domain Aliases and SSL config + +data "aws_route53_zone" "this" { + name = "https-example.dev." + private_zone = false +} + +resource "aws_acm_certificate" "this" { + domain_name = "this-is-my.https-example.dev" + validation_method = "DNS" +} + +resource "aws_route53_record" "cert_validation" { + name = "${aws_acm_certificate.this.domain_validation_options.0.resource_record_name}" + type = "${aws_acm_certificate.this.domain_validation_options.0.resource_record_type}" + zone_id = "${data.aws_route53_zone.this.id}" + records = ["${aws_acm_certificate.this.domain_validation_options.0.resource_record_value}"] + ttl = 60 +} + +resource "aws_acm_certificate_validation" "this" { + certificate_arn = "${aws_acm_certificate.this.arn}" + validation_record_fqdns = ["${aws_route53_record.cert_validation.fqdn}"] +} + +resource "aws_route53_record" "subdomain" { + name = "this-is-my.https-example.dev" + zone_id = "${data.aws_route53_zone.this.id}" + type = "A" + + alias { + name = "${module.fargate.application_load_balancers_dns_names[0]}" # Position 0 because we only have one Fargate service (api) + zone_id = "${module.fargate.application_load_balancers_zone_ids[0]}" # Same here + evaluate_target_health = true + } +} + +# Module definition here! + +module "fargate" { + source = "../../" + + name = "https-example" + + services = { + api = { + task_definition = "api.json" + container_port = 3000 + cpu = "256" + memory = "512" + replicas = 3 + + registry_retention_count = 15 # Optional. 20 by default + logs_retention_days = 14 # Optional. 30 by default + + # To activate SSL Listener (HTTPS) set the ARN of the ACM certificate here! 🔑 + acm_certificate_arn = "${aws_acm_certificate.this.arn}" + } + } +} + +## After all of this, you should be able to visit make requests to the service hitting https://this-is-my.https-example.dev +## Ofc, if you were the owner of "https-exampke.dev" domain 😅 + diff --git a/examples/https_enabled/outputs.tf b/examples/https_enabled/outputs.tf new file mode 100644 index 0000000..e508b66 --- /dev/null +++ b/examples/https_enabled/outputs.tf @@ -0,0 +1,33 @@ +# VPC +output "vpc" { + value = "${module.fargate.vpc}" +} + +# ECR +output "ecr" { + value = "${module.fargate.ecr_repository}" +} + +# ECS Cluster +output "ecs_cluster" { + value = "${module.fargate.ecs_cluster}" +} + +# ALBs +output "application_load_balancers" { + value = "${module.fargate.application_load_balancers}" +} + +# Security Groups +output "web_security_group" { + value = "${module.fargate.web_security_group}" +} + +output "services_security_groups" { + value = "${module.fargate.services_security_groups}" +} + +# CloudWatch +output "cloudwatch_log_groups" { + value = "${module.fargate.cloudwatch_log_groups}" +}