├── .editorconfig ├── .gitignore ├── Makefile ├── README.md ├── alb-acme.tf ├── alb.tf ├── alert-manager.tf ├── ami ├── main.tf ├── output.tf └── variables.tf ├── data └── iam │ ├── ecs-task-assumerole.json │ └── log-policy.json ├── debug.tf ├── dns.tf ├── docker ├── alertmanager │ ├── Dockerfile │ └── alertmanager.yml ├── nats-streaming │ └── Dockerfile └── prometheus │ ├── Dockerfile │ ├── alert.rules.yml │ └── prometheus.yml ├── docs ├── architecture.png └── architecture.xml ├── ecs.tf ├── gateway.tf ├── keys └── .gitignore ├── main.tf ├── nats.tf ├── network.tf ├── output.tf ├── prometheus.tf ├── security.tf ├── service-internal-no-task ├── main.tf ├── output.tf └── variables.tf ├── service-internal-with-lb ├── main.tf ├── output.tf └── variables.tf ├── service-internal ├── main.tf ├── output.tf └── variables.tf ├── terraform.tfstate.1541875947.backup └── variables.tf /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | ; Unix-style newlines with a newline ending every file 4 | [*] 5 | end_of_line = lf 6 | indent_size = 4 7 | indent_style = space 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | charset = utf-8 12 | 13 | ; Golang 14 | [*.go] 15 | indent_style = tab 16 | indent_size = 4 17 | 18 | ; YAML 19 | [*.{yaml,yml}] 20 | indent_style = space 21 | indent_size = 2 22 | 23 | [{Makefile,GNUmakefile}] 24 | indent_style = tab 25 | indent_size = 4 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | state.tf 3 | .terraform 4 | *.tfstate 5 | *.tfvars 6 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | alertmanager_version := "v0.15.1" 2 | prometheus_version := "v2.3.1" 3 | nats_streaming_version := "0.11.2" 4 | default: install 5 | 6 | install: init apply 7 | 8 | init: 9 | @terraform init 10 | 11 | apply: 12 | @terraform apply 13 | 14 | destroy: 15 | @terraform destroy 16 | 17 | keys: 18 | @ssh-keygen -t rsa -f ./keys/openfaas 19 | @chmod 400 ./keys/openfaas 20 | @chmod 400 ./keys/openfaas.pub 21 | 22 | docker-publish: docker-build 23 | @docker push ewilde/alertmanager:${alertmanager_version} 24 | @docker push ewilde/prometheus:${prometheus_version} 25 | @docker push ewilde/nats-streaming:${nats_streaming_version} 26 | 27 | docker-build: 28 | @docker build ./docker/alertmanager/ -t ewilde/alertmanager:${alertmanager_version} 29 | @docker build ./docker/prometheus/ -t ewilde/prometheus:${prometheus_version} 30 | @docker build --build-arg NATS_VERSION=${nats_streaming_version} ./docker/nats-streaming/ -t ewilde/nats-streaming:${nats_streaming_version} 31 | uninstall: destroy 32 | 33 | .PHONY: install uninstall keys init apply destroy 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Overview 2 | Openfaas for fargate overview 3 | 4 | * [Installing](#installing) 5 | * [Uninstalling](#uninstalling) 6 | 7 | ## Installing 8 | 1. **Install terraform** 9 | 10 | **_Mac_**: `brew install terraform` 11 | 12 | **_Linux_**: 13 | ``` 14 | wget https://releases.hashicorp.com/terraform/0.11.7/terraform_0.11.7_linux_amd64.zip 15 | unzip terraform_0.11.7_linux_amd64.zip 16 | sudo mv terraform /usr/local/bin 17 | terraform --version 18 | ``` 19 | 20 | 2. **Create terraform.tfvars** 21 | 22 | You will need to create a new file in the root of this repo called `terraform.tfvars` 23 | which configures variables used to install `faas-ecs` 24 | 25 | | Name | Description | 26 | |---------------------|----------------------------------------------------------------------------------------------------------------------------------| 27 | | acme_enabled | (Recommend)`1` to use the official [acme]() terraform provider to create TLS certificates. Defaults to `0` | 28 | | acme_email_address | (Recommend) Email address used to register TLS account, used in conjunction with `acme_enabled` | 29 | | aws_region | (Required) The aws region to create the openfaas ecs cluster in | 30 | | alb_logs_bucket | (Required) S3 bucket to store alb logs | 31 | | debug | (Optional) `1` to create an ec2 bastion in the external subnet and a test instance in the internal subnet. Defaults to `0` | 32 | | developer_ip | your ip address, used to whitelist incoming ssh to the bastion, debug is enabled | 33 | | route53_zone_name | (Recommended) a route 53 zone to create DNS records for the OpenFaaS gateway, i.e. openfaas.example.com, requires `acme_enabled` | 34 | | self_signed_enabled | (Not recommended) Use a self-signed TLS certificate for the OpenFaaS gateway if not using `acme_enabled`. Defaults to `0` | 35 | 36 | 37 | 38 | **_Example file_** 39 | ``` 40 | cat > ./terraform.tfvars < Ssh access is only required if `debug = "1"`, however the ssh key is still required for the 54 | install to work even if debug disabled. To create the key run: 55 | 56 | `make keys` 57 | 58 | 4. Create bucket for alb logs 59 | If you don't already have a bucket, please create the bucket you listed in your `terraform.tfvars` in the variable 60 | `alb_logs_bucket` 61 | 62 | i.e. `aws s3api create-bucket --bucket ewilde-logs --region eu-west-1 --create-bucket-configuration LocationConstraint=eu-west-1` 63 | 64 | 4. **Run terraform** 65 | 66 | `make` 67 | 68 | ### Known issue 69 | If you get the following error: 70 | ``` 71 | Error: Error applying plan: 72 | 73 | 2 error(s) occurred: 74 | 75 | * module.ecs_provider.aws_ecs_service.main: 1 error(s) occurred: 76 | 77 | * aws_ecs_service.main: InvalidParameterException: Unable to assume the service linked role. Please verify that the ECS service linked role exists. 78 | status code: 400, request id: d967b493-82f9-11e8-9d63-f5180ba0fbef "ecs-provider" 79 | * module.nats.aws_ecs_service.main: 1 error(s) occurred: 80 | 81 | * aws_ecs_service.main: InvalidParameterException: Unable to assume the service linked role. Please verify that the ECS service linked role exists. 82 | status code: 400, request id: dab962b7-82f9-11e8-8cc5-29d47e720a04 "nats" 83 | 84 | Terraform does not automatically rollback in the face of errors. 85 | Instead, your Terraform state file has been partially updated with 86 | any resources that successfully completed. Please address the error 87 | above and apply again to incrementally change your infrastructure. 88 | 89 | ``` 90 | 91 | Please just re-run `make`, this is an eventual consistency problem see #4 92 | 93 | ## Uninstalling 94 | 95 | 1. Run `make uninstall` 96 | 2. Patiently wait about `5-10 minutes` 97 | 98 | ### Known issue 99 | ```Error applying plan: 100 | 101 | 1 error(s) occurred: 102 | 103 | * aws_service_discovery_private_dns_namespace.openfaas (destroy): 1 error(s) occurred: 104 | ``` 105 | 106 | To resolve this problem manually delete all the service registrations 107 | 108 | `aws servicediscovery list-services | jq '.Services[].Id' -r | xargs -L 1 aws servicediscovery delete-service --id` 109 | 110 | 111 | -------------------------------------------------------------------------------- /alb-acme.tf: -------------------------------------------------------------------------------- 1 | resource "tls_private_key" "private_key" { 2 | algorithm = "RSA" 3 | count = "${var.acme_enabled}" 4 | } 5 | 6 | resource "acme_registration" "reg" { 7 | account_key_pem = "${tls_private_key.private_key.0.private_key_pem}" 8 | email_address = "${var.acme_email_address}" 9 | count = "${var.acme_enabled}" 10 | } 11 | 12 | resource "acme_certificate" "acme" { 13 | account_key_pem = "${acme_registration.reg.0.account_key_pem}" 14 | common_name = "${aws_route53_record.main.fqdn}" 15 | count = "${var.acme_enabled}" 16 | 17 | dns_challenge { 18 | provider = "route53" 19 | } 20 | } 21 | 22 | resource "aws_iam_server_certificate" "acme" { 23 | name = "acme-certificate-${md5(acme_certificate.acme.0.certificate_pem)}" 24 | certificate_body = "${acme_certificate.acme.0.certificate_pem}" 25 | private_key = "${acme_certificate.acme.0.private_key_pem}" 26 | certificate_chain = "${acme_certificate.acme.0.issuer_pem}" 27 | count = "${var.acme_enabled}" 28 | 29 | lifecycle { 30 | create_before_destroy = true 31 | } 32 | } 33 | 34 | data "aws_route53_zone" "main" { 35 | name = "${var.route53_zone_name}" 36 | count = "${var.acme_enabled}" 37 | } 38 | 39 | resource "aws_route53_record" "main" { 40 | name = "gateway" 41 | zone_id = "${data.aws_route53_zone.main.id}" 42 | type = "A" 43 | count = "${var.acme_enabled}" 44 | alias { 45 | name = "${aws_lb.openfaas.dns_name}" 46 | zone_id = "${aws_lb.openfaas.zone_id}" 47 | evaluate_target_health = false 48 | } 49 | } 50 | 51 | -------------------------------------------------------------------------------- /alb.tf: -------------------------------------------------------------------------------- 1 | resource "aws_lb" "openfaas" { 2 | name = "${var.namespace}" 3 | internal = false 4 | security_groups = ["${aws_security_group.alb.id}"] 5 | subnets = ["${aws_subnet.external.*.id}"] 6 | load_balancer_type = "application" 7 | access_logs { 8 | bucket = "${var.alb_logs_bucket}" 9 | enabled = true 10 | } 11 | } 12 | 13 | resource "tls_private_key" "main" { 14 | algorithm = "RSA" 15 | } 16 | 17 | resource "tls_self_signed_cert" "main" { 18 | key_algorithm = "${tls_private_key.main.algorithm}" 19 | private_key_pem = "${tls_private_key.main.private_key_pem}" 20 | 21 | # Certificate expires after 12 hours. 22 | validity_period_hours = 12 23 | 24 | # Generate a new certificate if Terraform is run within three 25 | # hours of the certificate's expiration time. 26 | early_renewal_hours = 3 27 | 28 | # Reasonable set of uses for a server SSL certificate. 29 | allowed_uses = [ 30 | "key_encipherment", 31 | "digital_signature", 32 | "server_auth", 33 | ] 34 | 35 | dns_names = ["${aws_lb.openfaas.dns_name}"] 36 | 37 | subject { 38 | common_name = "${aws_lb.openfaas.dns_name}" 39 | organization = "ACME Examples, Inc" 40 | } 41 | } 42 | 43 | resource "aws_iam_server_certificate" "self_signed" { 44 | name = "example_self_signed_cert_${random_string.name.result}" 45 | certificate_body = "${tls_self_signed_cert.main.cert_pem}" 46 | private_key = "${tls_private_key.main.private_key_pem}" 47 | 48 | lifecycle { 49 | create_before_destroy = true 50 | ignore_changes = ["name"] 51 | } 52 | } 53 | 54 | resource "random_string" "name" { 55 | length = 6 56 | special = false 57 | } 58 | 59 | resource "aws_lb_target_group" "gateway" { 60 | name = "${var.namespace}-gateway" 61 | port = 8080 62 | protocol = "HTTP" 63 | vpc_id = "${aws_vpc.default.id}" 64 | 65 | target_type = "ip" 66 | health_check { 67 | path = "/healthz" 68 | matcher = "200" 69 | } 70 | } 71 | 72 | resource "aws_lb_listener" "gateway_self_signed" { 73 | load_balancer_arn = "${aws_lb.openfaas.arn}" 74 | port = 443 75 | protocol = "HTTPS" 76 | certificate_arn = "${aws_iam_server_certificate.self_signed.arn}" 77 | count = "${var.self_signed_enabled}" 78 | 79 | default_action { 80 | target_group_arn = "${aws_lb_target_group.gateway.arn}" 81 | type = "forward" 82 | } 83 | } 84 | 85 | resource "aws_lb_listener" "gateway_acme" { 86 | load_balancer_arn = "${aws_lb.openfaas.arn}" 87 | port = 443 88 | protocol = "HTTPS" 89 | certificate_arn = "${aws_iam_server_certificate.acme.arn}" 90 | count = "${var.acme_enabled}" 91 | default_action { 92 | target_group_arn = "${aws_lb_target_group.gateway.arn}" 93 | type = "forward" 94 | } 95 | } 96 | 97 | resource "aws_lb_target_group" "prometheus" { 98 | name = "${var.namespace}-prometheus" 99 | port = 9090 100 | protocol = "HTTP" 101 | vpc_id = "${aws_vpc.default.id}" 102 | 103 | target_type = "ip" 104 | health_check { 105 | path = "/graph" 106 | matcher = "200" 107 | } 108 | } 109 | 110 | resource "aws_lb_listener" "prometheus" { 111 | load_balancer_arn = "${aws_lb.openfaas.arn}" 112 | port = 9090 113 | protocol = "HTTP" 114 | default_action { 115 | target_group_arn = "${aws_lb_target_group.prometheus.arn}" 116 | type = "forward" 117 | } 118 | } 119 | 120 | resource "aws_security_group" "alb" { 121 | name = "${var.namespace}.alb" 122 | description = "Alb security group rules" 123 | vpc_id = "${aws_vpc.default.id}" 124 | 125 | tags { 126 | Name = "${format("%s-alb", var.namespace)}" 127 | } 128 | } 129 | 130 | resource "aws_security_group_rule" "alb_ingress_gateway" { 131 | type = "ingress" 132 | from_port = 443 133 | to_port = 443 134 | protocol = "tcp" 135 | cidr_blocks = ["${var.developer_ip}/32"] 136 | security_group_id = "${aws_security_group.alb.id}" 137 | } 138 | 139 | resource "aws_security_group_rule" "alb_ingress_prometheus" { 140 | type = "ingress" 141 | from_port = 9090 142 | to_port = 9090 143 | protocol = "tcp" 144 | cidr_blocks = ["${var.developer_ip}/32"] 145 | security_group_id = "${aws_security_group.alb.id}" 146 | } 147 | 148 | resource "aws_security_group_rule" "alb_egress_gateway" { 149 | type = "egress" 150 | from_port = 8080 151 | to_port = 8080 152 | protocol = "tcp" 153 | security_group_id = "${aws_security_group.alb.id}" 154 | source_security_group_id = "${aws_security_group.gateway.id}" 155 | } 156 | 157 | resource "aws_security_group_rule" "alb_egress_prometheus" { 158 | type = "egress" 159 | from_port = 9090 160 | to_port = 9090 161 | protocol = "tcp" 162 | security_group_id = "${aws_security_group.alb.id}" 163 | source_security_group_id = "${aws_security_group.prometheus.id}" 164 | } 165 | 166 | -------------------------------------------------------------------------------- /alert-manager.tf: -------------------------------------------------------------------------------- 1 | module "alertmanager" { 2 | source = "./service-internal" 3 | name = "alertmanager" 4 | ecs_cluster_name = "${var.ecs_cluster_name}" 5 | aws_region = "${var.aws_region}" 6 | desired_count = "1" 7 | security_groups = ["${aws_security_group.service.id}", "${aws_security_group.alertmanager.id}"] 8 | allowed_subnets = ["${aws_subnet.internal.*.id}"] 9 | namespace = "${var.namespace}" 10 | namespace_id = "${aws_service_discovery_private_dns_namespace.openfaas.id}" 11 | task_image = "ewilde/alertmanager" 12 | task_image_version = "v0.15.1" 13 | task_role_arn = "${aws_iam_role.alertmanager_role.arn}" 14 | task_ports = "[{\"containerPort\":9093,\"hostPort\":9093}]" 15 | task_command = < nats-streaming-server 6 | RUN chmod +x nats-streaming-server 7 | 8 | 9 | FROM alpine:3.7 10 | COPY --from=build-env /nats-streaming-server / 11 | 12 | # Expose client and management ports 13 | EXPOSE 4222 8222 14 | 15 | # Run with default memory based store 16 | ENTRYPOINT ["/nats-streaming-server"] 17 | CMD ["-m", "8222"] 18 | -------------------------------------------------------------------------------- /docker/prometheus/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM prom/prometheus:v2.3.1 2 | COPY alert.rules.yml /etc/prometheus/alert.rules.yml 3 | COPY prometheus.yml /etc/prometheus/prometheus.yml 4 | -------------------------------------------------------------------------------- /docker/prometheus/alert.rules.yml: -------------------------------------------------------------------------------- 1 | groups: 2 | - name: prometheus/alert.rules 3 | rules: 4 | - alert: service_down 5 | expr: up == 0 6 | - alert: APIHighInvocationRate 7 | expr: sum(rate(gateway_function_invocation_total{code="200"}[10s])) BY (function_name) > 5 8 | for: 5s 9 | labels: 10 | service: gateway 11 | severity: major 12 | value: '{{$value}}' 13 | annotations: 14 | description: High invocation total on {{ $labels.instance }} 15 | summary: High invocation total on {{ $labels.instance }} 16 | -------------------------------------------------------------------------------- /docker/prometheus/prometheus.yml: -------------------------------------------------------------------------------- 1 | # my global config 2 | global: 3 | scrape_interval: 15s # By default, scrape targets every 15 seconds. 4 | evaluation_interval: 15s # By default, scrape targets every 15 seconds. 5 | # scrape_timeout is set to the global default (10s). 6 | 7 | # Attach these labels to any time series or alerts when communicating with 8 | # external systems (federation, remote storage, Alertmanager). 9 | external_labels: 10 | monitor: 'faas-monitor' 11 | 12 | # Load rules once and periodically evaluate them according to the global 'evaluation_interval'. 13 | rule_files: 14 | - 'alert.rules.yml' 15 | 16 | 17 | # A scrape configuration containing exactly one endpoint to scrape: 18 | # Here it's Prometheus itself. 19 | scrape_configs: 20 | # The job name is added as a label `job=` to any timeseries scraped from this config. 21 | - job_name: 'prometheus' 22 | 23 | # Override the global default and scrape targets from this job every 5 seconds. 24 | scrape_interval: 5s 25 | 26 | # metrics_path defaults to '/metrics' 27 | # scheme defaults to 'http'. 28 | static_configs: 29 | - targets: ['localhost:9090'] 30 | 31 | - job_name: "gateway" 32 | scrape_interval: 5s 33 | dns_sd_configs: 34 | - names: ['gateway.openfaas.local'] 35 | port: 8080 36 | type: A 37 | refresh_interval: 5s 38 | 39 | alerting: 40 | alertmanagers: 41 | - static_configs: 42 | - targets: 43 | - alertmanager.openfaas.local:9093 44 | -------------------------------------------------------------------------------- /docs/architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ewilde/terraform-aws-openfaas-fargate/6268d896f3cdb20ef07015812814b2f3e023a38b/docs/architecture.png -------------------------------------------------------------------------------- /docs/architecture.xml: -------------------------------------------------------------------------------- 1 | 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 -------------------------------------------------------------------------------- /ecs.tf: -------------------------------------------------------------------------------- 1 | resource "aws_ecs_cluster" "openfaas" { 2 | name = "${var.ecs_cluster_name}" 3 | } 4 | 5 | resource "aws_iam_role" "ecs_role" { 6 | assume_role_policy = "${file("${path.module}/data/iam/ecs-task-assumerole.json")}" 7 | } 8 | 9 | resource "aws_iam_role_policy" "ecs_role_policy" { 10 | name = "openfaas-task-role" 11 | role = "${aws_iam_role.ecs_role.id}" 12 | policy = <