diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index b7cf9010..00000000 --- a/.travis.yml +++ /dev/null @@ -1,16 +0,0 @@ -addons: - apt: - packages: - - git - - make - - curl - -install: - - make init - -script: - - make terraform/install - - make terraform/get-plugins - - make terraform/get-modules - - make terraform/lint - - make terraform/validate \ No newline at end of file diff --git a/README.md b/README.md index 6113c99d..f1ca2fb5 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![Cloud Posse][logo]](https://cpco.io/homepage) -# terraform-aws-ecs-web-app [![Build Status](https://travis-ci.org/cloudposse/terraform-aws-ecs-web-app.svg?branch=master)](https://travis-ci.org/cloudposse/terraform-aws-ecs-web-app) [![Latest Release](https://img.shields.io/github/release/cloudposse/terraform-aws-ecs-web-app.svg)](https://github.com/cloudposse/terraform-aws-ecs-web-app/releases/latest) [![Slack Community](https://slack.cloudposse.com/badge.svg)](https://slack.cloudposse.com) +# terraform-aws-ecs-web-app [![Codefresh Build Status](https://g.codefresh.io/api/badges/pipeline/cloudposse/terraform-modules%2Fterraform-aws-ecs-web-app?type=cf-1)](https://g.codefresh.io/public/accounts/cloudposse/pipelines/5dbb22a15c2e97b3b73ab484) [![Latest Release](https://img.shields.io/github/release/cloudposse/terraform-aws-ecs-web-app.svg)](https://github.com/cloudposse/terraform-aws-ecs-web-app/releases/latest) [![Slack Community](https://slack.cloudposse.com/badge.svg)](https://slack.cloudposse.com) A Terraform module which implements a web app on ECS and supporting AWS resources. @@ -47,30 +47,33 @@ We literally have [*hundreds of terraform modules*][terraform_modules] that are Instead pin to the release tag (e.g. `?ref=tags/x.y.z`) of one of our [latest releases](https://github.com/cloudposse/terraform-aws-ecs-web-app/releases). -Module usage examples: +For a complete example, see [examples/complete](examples/complete). -- [without authentication](examples/without_authentication) - complete example without authentication -- [with Google OIDC authentication](examples/with_google_oidc_authentication) - complete example with Google OIDC authentication -- [with Cognito authentication](examples/with_cognito_authentication) - complete example with Cognito authentication +For automated tests of the complete example using [bats](https://github.com/bats-core/bats-core) and [Terratest](https://github.com/gruntwork-io/terratest) (which test and deploy the example on AWS), see [test](test). +Other examples: + +- [without authentication](examples/without_authentication) - without authentication +- [with Google OIDC authentication](examples/with_google_oidc_authentication) - with Google OIDC authentication +- [with Cognito authentication](examples/with_cognito_authentication) - with Cognito authentication ``` -module "default-backend-web-app" { +module "default_backend_web_app" { source = "git::https://github.com/cloudposse/terraform-aws-ecs-web-app.git?ref=master" namespace = "eg" stage = "testing" name = "appname" - vpc_id = "${module.vpc.vpc_id}" - alb_ingress_unauthenticated_listener_arns = "${module.alb.listener_arns}" - alb_ingress_unauthenticated_listener_arns_count = "1" - aws_logs_region = "us-west-2" - ecs_cluster_arn = "${aws_ecs_cluster.default.arn}" - ecs_cluster_name = "${aws_ecs_cluster.default.name}" - ecs_security_group_ids = ["${module.vpc.vpc_default_security_group_id}"] - ecs_private_subnet_ids = ["${module.subnets.private_subnet_ids}"] + vpc_id = module.vpc.vpc_id + alb_ingress_unauthenticated_listener_arns = module.alb.listener_arns + alb_ingress_unauthenticated_listener_arns_count = 1 + aws_logs_region = "us-east-2" + ecs_cluster_arn = aws_ecs_cluster.default.arn + ecs_cluster_name = aws_ecs_cluster.default.name + ecs_security_group_ids = [module.vpc.vpc_default_security_group_id] + ecs_private_subnet_ids = module.subnets.private_subnet_ids alb_ingress_healthcheck_path = "/healthz" alb_ingress_unauthenticated_paths = ["/*"] - codepipeline_enabled = "false" + codepipeline_enabled = false environment = [ { @@ -105,31 +108,29 @@ Available targets: | Name | Description | Type | Default | Required | |------|-------------|:----:|:-----:|:-----:| | alb_arn_suffix | ARN suffix of the ALB for the Target Group | string | `` | no | -| alb_ingress_authenticated_hosts | Authenticated hosts to match in Hosts header | list | `` | no | -| alb_ingress_authenticated_listener_arns | A list of authenticated ALB listener ARNs to attach ALB listener rules to | list | `` | no | -| alb_ingress_authenticated_listener_arns_count | The number of authenticated ARNs in `alb_ingress_authenticated_listener_arns`. This is necessary to work around a limitation in Terraform where counts cannot be computed | string | `0` | no | -| alb_ingress_authenticated_paths | Authenticated path pattern to match (a maximum of 1 can be defined) | list | `` | no | +| alb_ingress_authenticated_hosts | Authenticated hosts to match in Hosts header | list(string) | `` | no | +| alb_ingress_authenticated_listener_arns | A list of authenticated ALB listener ARNs to attach ALB listener rules to | list(string) | `` | no | +| alb_ingress_authenticated_listener_arns_count | The number of authenticated ARNs in `alb_ingress_authenticated_listener_arns`. This is necessary to work around a limitation in Terraform where counts cannot be computed | number | `0` | no | +| alb_ingress_authenticated_paths | Authenticated path pattern to match (a maximum of 1 can be defined) | list(string) | `` | no | | alb_ingress_healthcheck_path | The path of the healthcheck which the ALB checks | string | `/` | no | -| alb_ingress_listener_authenticated_priority | The priority for the rules with authentication, between 1 and 50000 (1 being highest priority). Must be different from `alb_ingress_listener_unauthenticated_priority` since a listener can't have multiple rules with the same priority | string | `300` | no | -| alb_ingress_listener_unauthenticated_priority | The priority for the rules without authentication, between 1 and 50000 (1 being highest priority). Must be different from `alb_ingress_listener_authenticated_priority` since a listener can't have multiple rules with the same priority | string | `1000` | no | -| alb_ingress_unauthenticated_hosts | Unauthenticated hosts to match in Hosts header | list | `` | no | -| alb_ingress_unauthenticated_listener_arns | A list of unauthenticated ALB listener ARNs to attach ALB listener rules to | list | `` | no | -| alb_ingress_unauthenticated_listener_arns_count | The number of unauthenticated ARNs in `alb_ingress_unauthenticated_listener_arns`. This is necessary to work around a limitation in Terraform where counts cannot be computed | string | `0` | no | -| alb_ingress_unauthenticated_paths | Unauthenticated path pattern to match (a maximum of 1 can be defined) | list | `` | no | -| alb_name | Name of the ALB for the Target Group | string | `` | no | +| alb_ingress_listener_authenticated_priority | The priority for the rules with authentication, between 1 and 50000 (1 being highest priority). Must be different from `alb_ingress_listener_unauthenticated_priority` since a listener can't have multiple rules with the same priority | number | `300` | no | +| alb_ingress_listener_unauthenticated_priority | The priority for the rules without authentication, between 1 and 50000 (1 being highest priority). Must be different from `alb_ingress_listener_authenticated_priority` since a listener can't have multiple rules with the same priority | number | `1000` | no | +| alb_ingress_unauthenticated_hosts | Unauthenticated hosts to match in Hosts header | list(string) | `` | no | +| alb_ingress_unauthenticated_listener_arns | A list of unauthenticated ALB listener ARNs to attach ALB listener rules to | list(string) | `` | no | +| alb_ingress_unauthenticated_listener_arns_count | The number of unauthenticated ARNs in `alb_ingress_unauthenticated_listener_arns`. This is necessary to work around a limitation in Terraform where counts cannot be computed | number | `0` | no | +| alb_ingress_unauthenticated_paths | Unauthenticated path pattern to match (a maximum of 1 can be defined) | list(string) | `` | no | | alb_security_group | Security group of the ALB | string | - | yes | -| alb_target_group_alarms_3xx_threshold | The maximum number of 3XX HTTPCodes in a given period for ECS Service | string | `25` | no | -| alb_target_group_alarms_4xx_threshold | The maximum number of 4XX HTTPCodes in a given period for ECS Service | string | `25` | no | -| alb_target_group_alarms_5xx_threshold | The maximum number of 5XX HTTPCodes in a given period for ECS Service | string | `25` | no | -| alb_target_group_alarms_alarm_actions | A list of ARNs (i.e. SNS Topic ARN) to execute when ALB Target Group alarms transition into an ALARM state from any other state | list | `` | no | -| alb_target_group_alarms_enabled | A boolean to enable/disable CloudWatch Alarms for ALB Target metrics | string | `false` | no | -| alb_target_group_alarms_evaluation_periods | The number of periods to analyze for ALB CloudWatch Alarms | string | `1` | no | -| alb_target_group_alarms_insufficient_data_actions | A list of ARNs (i.e. SNS Topic ARN) to execute when ALB Target Group alarms transition into an INSUFFICIENT_DATA state from any other state | list | `` | no | -| alb_target_group_alarms_ok_actions | A list of ARNs (i.e. SNS Topic ARN) to execute when ALB Target Group alarms transition into an OK state from any other state | list | `` | no | -| alb_target_group_alarms_period | The period (in seconds) to analyze for ALB CloudWatch Alarms | string | `300` | no | -| alb_target_group_alarms_response_time_threshold | The maximum ALB Target Group response time | string | `0.5` | no | -| alb_target_group_arn | Pass target group down to module | string | `` | no | -| attributes | List of attributes to add to label | list | `` | no | +| alb_target_group_alarms_3xx_threshold | The maximum number of 3XX HTTPCodes in a given period for ECS Service | number | `25` | no | +| alb_target_group_alarms_4xx_threshold | The maximum number of 4XX HTTPCodes in a given period for ECS Service | number | `25` | no | +| alb_target_group_alarms_5xx_threshold | The maximum number of 5XX HTTPCodes in a given period for ECS Service | number | `25` | no | +| alb_target_group_alarms_alarm_actions | A list of ARNs (i.e. SNS Topic ARN) to execute when ALB Target Group alarms transition into an ALARM state from any other state | list(string) | `` | no | +| alb_target_group_alarms_enabled | A boolean to enable/disable CloudWatch Alarms for ALB Target metrics | bool | `false` | no | +| alb_target_group_alarms_evaluation_periods | The number of periods to analyze for ALB CloudWatch Alarms | number | `1` | no | +| alb_target_group_alarms_insufficient_data_actions | A list of ARNs (i.e. SNS Topic ARN) to execute when ALB Target Group alarms transition into an INSUFFICIENT_DATA state from any other state | list(string) | `` | no | +| alb_target_group_alarms_ok_actions | A list of ARNs (i.e. SNS Topic ARN) to execute when ALB Target Group alarms transition into an OK state from any other state | list(string) | `` | no | +| alb_target_group_alarms_period | The period (in seconds) to analyze for ALB CloudWatch Alarms | number | `300` | no | +| alb_target_group_alarms_response_time_threshold | The maximum ALB Target Group response time | number | `0.5` | no | +| attributes | Additional attributes (_e.g._ "1") | list(string) | `` | no | | authentication_cognito_user_pool_arn | Cognito User Pool ARN | string | `` | no | | authentication_cognito_user_pool_client_id | Cognito User Pool Client ID | string | `` | no | | authentication_cognito_user_pool_domain | Cognito User Pool Domain. The User Pool Domain should be set to the domain prefix (`xxx`) instead of full domain (https://xxx.auth.us-west-2.amazoncognito.com) | string | `` | no | @@ -141,74 +142,74 @@ Available targets: | authentication_oidc_user_info_endpoint | OIDC User Info Endpoint | string | `` | no | | authentication_type | Authentication type. Supported values are `COGNITO` and `OIDC` | string | `` | no | | autoscaling_dimension | Dimension to autoscale on (valid options: cpu, memory) | string | `memory` | no | -| autoscaling_enabled | A boolean to enable/disable Autoscaling policy for ECS Service | string | `false` | no | -| autoscaling_max_capacity | Maximum number of running instances of a Service | string | `2` | no | -| autoscaling_min_capacity | Minimum number of running instances of a Service | string | `1` | no | -| autoscaling_scale_down_adjustment | Scaling adjustment to make during scale down event | string | `-1` | no | -| autoscaling_scale_down_cooldown | Period (in seconds) to wait between scale down events | string | `300` | no | -| autoscaling_scale_up_adjustment | Scaling adjustment to make during scale up event | string | `1` | no | -| autoscaling_scale_up_cooldown | Period (in seconds) to wait between scale up events | string | `60` | no | +| autoscaling_enabled | A boolean to enable/disable Autoscaling policy for ECS Service | bool | `false` | no | +| autoscaling_max_capacity | Maximum number of running instances of a Service | number | `2` | no | +| autoscaling_min_capacity | Minimum number of running instances of a Service | number | `1` | no | +| autoscaling_scale_down_adjustment | Scaling adjustment to make during scale down event | number | `-1` | no | +| autoscaling_scale_down_cooldown | Period (in seconds) to wait between scale down events | number | `300` | no | +| autoscaling_scale_up_adjustment | Scaling adjustment to make during scale up event | number | `1` | no | +| autoscaling_scale_up_cooldown | Period (in seconds) to wait between scale up events | number | `60` | no | | aws_logs_region | The region for the AWS Cloudwatch Logs group | string | - | yes | -| badge_enabled | Generates a publicly-accessible URL for the projects build badge. Available as badge_url attribute when enabled | string | `false` | no | -| branch | Branch of the GitHub repository, e.g. master | string | `` | no | +| badge_enabled | Generates a publicly-accessible URL for the projects build badge. Available as badge_url attribute when enabled | bool | `false` | no | +| branch | Branch of the GitHub repository, e.g. `master` | string | `` | no | | build_image | Docker image for build environment, _e.g._ `aws/codebuild/docker:docker:17.09.0` | string | `aws/codebuild/docker:17.09.0` | no | -| build_timeout | How long in minutes, from 5 to 480 (8 hours), for AWS CodeBuild to wait until timing out any related build that does not get marked as completed | string | `60` | no | +| build_timeout | How long in minutes, from 5 to 480 (8 hours), for AWS CodeBuild to wait until timing out any related build that does not get marked as completed | number | `60` | no | | buildspec | Declaration to use for building the project. [For more info](http://docs.aws.amazon.com/codebuild/latest/userguide/build-spec-ref.html) | string | `` | no | -| codepipeline_enabled | A boolean to enable/disable AWS Codepipeline and ECR | string | `true` | no | -| codepipeline_s3_bucket_force_destroy | A boolean that indicates all objects should be deleted from the CodePipeline artifact store S3 bucket so that the bucket can be destroyed without error | string | `false` | no | -| container_cpu | The vCPU setting to control cpu limits of container. (If FARGATE launch type is used below, this must be a supported vCPU size from the table here: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-cpu-memory-error.html) | string | `256` | no | +| codepipeline_enabled | A boolean to enable/disable AWS Codepipeline and ECR | bool | `true` | no | +| codepipeline_s3_bucket_force_destroy | A boolean that indicates all objects should be deleted from the CodePipeline artifact store S3 bucket so that the bucket can be destroyed without error | bool | `false` | no | +| container_cpu | The vCPU setting to control cpu limits of container. (If FARGATE launch type is used below, this must be a supported vCPU size from the table here: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-cpu-memory-error.html) | number | `256` | no | | container_image | The default container image to use in container definition | string | `cloudposse/default-backend` | no | -| container_memory | The amount of RAM to allow container to use in MB. (If FARGATE launch type is used below, this must be a supported Memory size from the table here: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-cpu-memory-error.html) | string | `512` | no | -| container_memory_reservation | The amount of RAM (Soft Limit) to allow container to use in MB. This value must be less than container_memory if set | string | `` | no | -| container_port | The port number on the container bound to assigned host_port | string | `80` | no | -| delimiter | The delimiter to be used in labels | string | `-` | no | -| desired_count | The desired number of tasks to start with. Set this to 0 if using DAEMON Service type. (FARGATE does not suppoert DAEMON Service type) | string | `1` | no | -| ecs_alarms_cpu_utilization_high_alarm_actions | A list of ARNs (i.e. SNS Topic ARN) to notify on CPU Utilization High Alarm action | list | `` | no | -| ecs_alarms_cpu_utilization_high_evaluation_periods | Number of periods to evaluate for the alarm | string | `1` | no | -| ecs_alarms_cpu_utilization_high_ok_actions | A list of ARNs (i.e. SNS Topic ARN) to notify on CPU Utilization High OK action | list | `` | no | -| ecs_alarms_cpu_utilization_high_period | Duration in seconds to evaluate for the alarm | string | `300` | no | -| ecs_alarms_cpu_utilization_high_threshold | The maximum percentage of CPU utilization average | string | `80` | no | -| ecs_alarms_cpu_utilization_low_alarm_actions | A list of ARNs (i.e. SNS Topic ARN) to notify on CPU Utilization Low Alarm action | list | `` | no | -| ecs_alarms_cpu_utilization_low_evaluation_periods | Number of periods to evaluate for the alarm | string | `1` | no | -| ecs_alarms_cpu_utilization_low_ok_actions | A list of ARNs (i.e. SNS Topic ARN) to notify on CPU Utilization Low OK action | list | `` | no | -| ecs_alarms_cpu_utilization_low_period | Duration in seconds to evaluate for the alarm | string | `300` | no | -| ecs_alarms_cpu_utilization_low_threshold | The minimum percentage of CPU utilization average | string | `20` | no | -| ecs_alarms_enabled | A boolean to enable/disable CloudWatch Alarms for ECS Service metrics | string | `false` | no | -| ecs_alarms_memory_utilization_high_alarm_actions | A list of ARNs (i.e. SNS Topic ARN) to notify on Memory Utilization High Alarm action | list | `` | no | -| ecs_alarms_memory_utilization_high_evaluation_periods | Number of periods to evaluate for the alarm | string | `1` | no | -| ecs_alarms_memory_utilization_high_ok_actions | A list of ARNs (i.e. SNS Topic ARN) to notify on Memory Utilization High OK action | list | `` | no | -| ecs_alarms_memory_utilization_high_period | Duration in seconds to evaluate for the alarm | string | `300` | no | -| ecs_alarms_memory_utilization_high_threshold | The maximum percentage of Memory utilization average | string | `80` | no | -| ecs_alarms_memory_utilization_low_alarm_actions | A list of ARNs (i.e. SNS Topic ARN) to notify on Memory Utilization Low Alarm action | list | `` | no | -| ecs_alarms_memory_utilization_low_evaluation_periods | Number of periods to evaluate for the alarm | string | `1` | no | -| ecs_alarms_memory_utilization_low_ok_actions | A list of ARNs (i.e. SNS Topic ARN) to notify on Memory Utilization Low OK action | list | `` | no | -| ecs_alarms_memory_utilization_low_period | Duration in seconds to evaluate for the alarm | string | `300` | no | -| ecs_alarms_memory_utilization_low_threshold | The minimum percentage of Memory utilization average | string | `20` | no | +| container_memory | The amount of RAM to allow container to use in MB. (If FARGATE launch type is used below, this must be a supported Memory size from the table here: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-cpu-memory-error.html) | number | `512` | no | +| container_memory_reservation | The amount of RAM (Soft Limit) to allow container to use in MB. This value must be less than `container_memory` if set | number | `128` | no | +| container_port | The port number on the container bound to assigned host_port | number | `80` | no | +| delimiter | Delimiter between `namespace`, `stage`, `name` and `attributes` | string | `-` | no | +| desired_count | The desired number of tasks to start with. Set this to 0 if using DAEMON Service type. (FARGATE does not suppoert DAEMON Service type) | number | `1` | no | +| ecs_alarms_cpu_utilization_high_alarm_actions | A list of ARNs (i.e. SNS Topic ARN) to notify on CPU Utilization High Alarm action | list(string) | `` | no | +| ecs_alarms_cpu_utilization_high_evaluation_periods | Number of periods to evaluate for the alarm | number | `1` | no | +| ecs_alarms_cpu_utilization_high_ok_actions | A list of ARNs (i.e. SNS Topic ARN) to notify on CPU Utilization High OK action | list(string) | `` | no | +| ecs_alarms_cpu_utilization_high_period | Duration in seconds to evaluate for the alarm | number | `300` | no | +| ecs_alarms_cpu_utilization_high_threshold | The maximum percentage of CPU utilization average | number | `80` | no | +| ecs_alarms_cpu_utilization_low_alarm_actions | A list of ARNs (i.e. SNS Topic ARN) to notify on CPU Utilization Low Alarm action | list(string) | `` | no | +| ecs_alarms_cpu_utilization_low_evaluation_periods | Number of periods to evaluate for the alarm | number | `1` | no | +| ecs_alarms_cpu_utilization_low_ok_actions | A list of ARNs (i.e. SNS Topic ARN) to notify on CPU Utilization Low OK action | list(string) | `` | no | +| ecs_alarms_cpu_utilization_low_period | Duration in seconds to evaluate for the alarm | number | `300` | no | +| ecs_alarms_cpu_utilization_low_threshold | The minimum percentage of CPU utilization average | number | `20` | no | +| ecs_alarms_enabled | A boolean to enable/disable CloudWatch Alarms for ECS Service metrics | bool | `false` | no | +| ecs_alarms_memory_utilization_high_alarm_actions | A list of ARNs (i.e. SNS Topic ARN) to notify on Memory Utilization High Alarm action | list(string) | `` | no | +| ecs_alarms_memory_utilization_high_evaluation_periods | Number of periods to evaluate for the alarm | number | `1` | no | +| ecs_alarms_memory_utilization_high_ok_actions | A list of ARNs (i.e. SNS Topic ARN) to notify on Memory Utilization High OK action | list(string) | `` | no | +| ecs_alarms_memory_utilization_high_period | Duration in seconds to evaluate for the alarm | number | `300` | no | +| ecs_alarms_memory_utilization_high_threshold | The maximum percentage of Memory utilization average | number | `80` | no | +| ecs_alarms_memory_utilization_low_alarm_actions | A list of ARNs (i.e. SNS Topic ARN) to notify on Memory Utilization Low Alarm action | list(string) | `` | no | +| ecs_alarms_memory_utilization_low_evaluation_periods | Number of periods to evaluate for the alarm | number | `1` | no | +| ecs_alarms_memory_utilization_low_ok_actions | A list of ARNs (i.e. SNS Topic ARN) to notify on Memory Utilization Low OK action | list(string) | `` | no | +| ecs_alarms_memory_utilization_low_period | Duration in seconds to evaluate for the alarm | number | `300` | no | +| ecs_alarms_memory_utilization_low_threshold | The minimum percentage of Memory utilization average | number | `20` | no | | ecs_cluster_arn | The ECS Cluster ARN where ECS Service will be provisioned | string | - | yes | | ecs_cluster_name | The ECS Cluster Name to use in ECS Code Pipeline Deployment step | string | - | yes | -| ecs_private_subnet_ids | List of Private Subnet IDs to provision ECS Service onto | list | - | yes | -| ecs_security_group_ids | Additional Security Group IDs to allow into ECS Service | list | `` | no | -| environment | The environment variables for the task definition. This is a list of maps | list | `` | no | +| ecs_private_subnet_ids | List of Private Subnet IDs to provision ECS Service onto | list(string) | - | yes | +| ecs_security_group_ids | Additional Security Group IDs to allow into ECS Service | list(string) | `` | no | +| environment | The environment variables to pass to the container. This is a list of maps | object | `null` | no | | github_oauth_token | GitHub Oauth Token with permissions to access private repositories | string | `` | no | -| github_webhook_events | A list of events which should trigger the webhook. See a list of [available events](https://developer.github.com/v3/activity/events/types/) | list | `` | no | +| github_webhook_events | A list of events which should trigger the webhook. See a list of [available events](https://developer.github.com/v3/activity/events/types/) | list(string) | `` | no | | github_webhooks_token | GitHub OAuth Token with permissions to create webhooks. If not provided, can be sourced from the `GITHUB_TOKEN` environment variable | string | `` | no | -| health_check_grace_period_seconds | Seconds to ignore failing load balancer health checks on newly instantiated tasks to prevent premature shutdown, up to 7200. Only valid for services configured to use load balancers | string | `0` | no | -| healthcheck | A map containing command (string), interval (duration in seconds), retries (1-10, number of times to retry before marking container unhealthy, and startPeriod (0-300, optional grace period to wait, in seconds, before failed healthchecks count toward retries) | map | `` | no | -| host_port | The port number to bind container_port to on the host | string | `` | no | +| health_check_grace_period_seconds | Seconds to ignore failing load balancer health checks on newly instantiated tasks to prevent premature shutdown, up to 7200. Only valid for services configured to use load balancers | number | `0` | no | +| healthcheck | A map containing command (string), timeout, interval (duration in seconds), retries (1-10, number of times to retry before marking container unhealthy), and startPeriod (0-300, optional grace period to wait, in seconds, before failed healthchecks count toward retries) | object | `null` | no | | launch_type | The ECS launch type (valid options: FARGATE or EC2) | string | `FARGATE` | no | -| name | Name (unique identifier for app or service) | string | - | yes | -| namespace | Namespace (e.g. `eg` or `cp`) | string | - | yes | -| poll_source_changes | Periodically check the location of your source content and run the pipeline if changes are detected | string | `false` | no | -| port_mappings | The port mappings to configure for the container. This is a list of maps. Each map should contain "containerPort", "hostPort", and "protocol", where "protocol" is one of "tcp" or "udp". If using containers in a task with the awsvpc or host network mode, the hostPort can either be left blank or set to the same value as the containerPort | list | `` | no | -| protocol | The protocol used for the port mapping. Options: `tcp` or `udp` | string | `tcp` | no | +| log_driver | The log driver to use for the container. If using Fargate launch type, only supported value is awslogs | string | `awslogs` | no | +| name | Name of the application | string | - | yes | +| namespace | Namespace (e.g. `eg` or `cp`) | string | `` | no | +| poll_source_changes | Periodically check the location of your source content and run the pipeline if changes are detected | bool | `false` | no | +| port_mappings | The port mappings to configure for the container. This is a list of maps. Each map should contain "containerPort", "hostPort", and "protocol", where "protocol" is one of "tcp" or "udp". If using containers in a task with the awsvpc or host network mode, the hostPort can either be left blank or set to the same value as the containerPort | object | `` | no | +| region | AWS Region for S3 bucket | string | - | yes | | repo_name | GitHub repository name of the application to be built and deployed to ECS | string | `` | no | | repo_owner | GitHub Organization or Username | string | `` | no | -| secrets | The secrets for the task definition. This is a list of maps | list | `` | no | -| stage | Stage (e.g. `prod`, `dev`, `staging`) | string | - | yes | -| tags | Map of key-value pairs to use for tags | map | `` | no | +| secrets | The secrets to pass to the container. This is a list of maps | object | `null` | no | +| stage | Stage (e.g. `prod`, `dev`, `staging`) | string | `` | no | +| tags | Additional tags (_e.g._ { BusinessUnit : ABC }) | map(string) | `` | no | | vpc_id | The VPC ID where resources are created | string | - | yes | | webhook_authentication | The type of authentication to use. One of IP, GITHUB_HMAC, or UNAUTHENTICATED | string | `GITHUB_HMAC` | no | -| webhook_enabled | Set to false to prevent the module from creating any webhook resources | string | `true` | no | +| webhook_enabled | Set to false to prevent the module from creating any webhook resources | bool | `true` | no | | webhook_filter_json_path | The JSON path to filter on | string | `$.ref` | no | | webhook_filter_match_equals | The value to match on (e.g. refs/heads/{Branch}) | string | `refs/heads/{Branch}` | no | | webhook_target_action | The name of the action in a pipeline you want to connect to the webhook. The action must be from the source (first) stage of the pipeline | string | `Source` | no | @@ -217,15 +218,57 @@ Available targets: | Name | Description | |------|-------------| -| badge_url | The URL of the build badge when `badge_enabled` is enabled | -| scale_down_policy_arn | Autoscaling scale up policy ARN | -| scale_up_policy_arn | Autoscaling scale up policy ARN | -| service_name | ECS Service Name | -| service_security_group_id | Security Group id of the ECS task | -| task_role_arn | ECS Task role ARN | -| task_role_name | ECS Task role name | -| webhook_id | The CodePipeline webhook's ARN. | -| webhook_url | The CodePipeline webhook's URL. POST events to this endpoint to trigger the target. | +| alb_ingress_target_group_arn | ALB Target Group ARN | +| alb_ingress_target_group_arn_suffix | ALB Target Group ARN suffix | +| alb_ingress_target_group_name | ALB Target Group name | +| codebuild_badge_url | The URL of the build badge when badge_enabled is enabled | +| codebuild_cache_bucket_arn | CodeBuild cache S3 bucket ARN | +| codebuild_cache_bucket_name | CodeBuild cache S3 bucket name | +| codebuild_project_id | CodeBuild project ID | +| codebuild_project_name | CodeBuild project name | +| codebuild_role_arn | CodeBuild IAM Role ARN | +| codebuild_role_id | CodeBuild IAM Role ID | +| codepipeline_arn | CodePipeline ARN | +| codepipeline_id | CodePipeline ID | +| codepipeline_webhook_id | The CodePipeline webhook's ID | +| codepipeline_webhook_url | The CodePipeline webhook's URL. POST events to this endpoint to trigger the target | +| container_definition_json | JSON encoded list of container definitions for use with other terraform resources such as aws_ecs_task_definition | +| container_definition_json_map | JSON encoded container definitions for use with other terraform resources such as aws_ecs_task_definition | +| ecr_registry_id | Registry ID | +| ecr_registry_url | Registry URL | +| ecr_repository_name | Registry name | +| ecs_alarms_cpu_utilization_high_cloudwatch_metric_alarm_arn | ECS CPU utilization high CloudWatch metric alarm ARN | +| ecs_alarms_cpu_utilization_high_cloudwatch_metric_alarm_id | ECS CPU utilization high CloudWatch metric alarm ID | +| ecs_alarms_cpu_utilization_low_cloudwatch_metric_alarm_arn | ECS CPU utilization low CloudWatch metric alarm ARN | +| ecs_alarms_cpu_utilization_low_cloudwatch_metric_alarm_id | ECS CPU utilization low CloudWatch metric alarm ID | +| ecs_alarms_memory_utilization_high_cloudwatch_metric_alarm_arn | ECS Memory utilization high CloudWatch metric alarm ARN | +| ecs_alarms_memory_utilization_high_cloudwatch_metric_alarm_id | ECS Memory utilization high CloudWatch metric alarm ID | +| ecs_alarms_memory_utilization_low_cloudwatch_metric_alarm_arn | ECS Memory utilization low CloudWatch metric alarm ARN | +| ecs_alarms_memory_utilization_low_cloudwatch_metric_alarm_id | ECS Memory utilization low CloudWatch metric alarm ID | +| ecs_cloudwatch_autoscaling_scale_down_policy_arn | ARN of the scale down policy | +| ecs_cloudwatch_autoscaling_scale_up_policy_arn | ARN of the scale up policy | +| ecs_exec_role_policy_id | The ECS service role policy ID, in the form of `role_name:role_policy_name` | +| ecs_exec_role_policy_name | ECS service role name | +| ecs_service_name | ECS Service name | +| ecs_service_role_arn | ECS Service role ARN | +| ecs_service_security_group_id | Security Group ID of the ECS task | +| ecs_task_definition_family | ECS task definition family | +| ecs_task_definition_revision | ECS task definition revision | +| ecs_task_exec_role_arn | ECS Task exec role ARN | +| ecs_task_exec_role_name | ECS Task role name | +| ecs_task_role_arn | ECS Task role ARN | +| ecs_task_role_id | ECS Task role id | +| ecs_task_role_name | ECS Task role name | +| httpcode_elb_5xx_count_cloudwatch_metric_alarm_arn | ALB 5xx count CloudWatch metric alarm ARN | +| httpcode_elb_5xx_count_cloudwatch_metric_alarm_id | ALB 5xx count CloudWatch metric alarm ID | +| httpcode_target_3xx_count_cloudwatch_metric_alarm_arn | ALB Target Group 3xx count CloudWatch metric alarm ARN | +| httpcode_target_3xx_count_cloudwatch_metric_alarm_id | ALB Target Group 3xx count CloudWatch metric alarm ID | +| httpcode_target_4xx_count_cloudwatch_metric_alarm_arn | ALB Target Group 4xx count CloudWatch metric alarm ARN | +| httpcode_target_4xx_count_cloudwatch_metric_alarm_id | ALB Target Group 4xx count CloudWatch metric alarm ID | +| httpcode_target_5xx_count_cloudwatch_metric_alarm_arn | ALB Target Group 5xx count CloudWatch metric alarm ARN | +| httpcode_target_5xx_count_cloudwatch_metric_alarm_id | ALB Target Group 5xx count CloudWatch metric alarm ID | +| target_response_time_average_cloudwatch_metric_alarm_arn | ALB Target Group response time average CloudWatch metric alarm ARN | +| target_response_time_average_cloudwatch_metric_alarm_id | ALB Target Group response time average CloudWatch metric alarm ID | @@ -376,13 +419,13 @@ Check out [our other projects][github], [follow us on twitter][twitter], [apply |---|---|---|---| [osterman_homepage]: https://github.com/osterman - [osterman_avatar]: https://github.com/osterman.png?size=150 + [osterman_avatar]: https://img.cloudposse.com/150x150/https://github.com/osterman.png [goruha_homepage]: https://github.com/goruha - [goruha_avatar]: https://github.com/goruha.png?size=150 + [goruha_avatar]: https://img.cloudposse.com/150x150/https://github.com/goruha.png [aknysh_homepage]: https://github.com/aknysh - [aknysh_avatar]: https://github.com/aknysh.png?size=150 + [aknysh_avatar]: https://img.cloudposse.com/150x150/https://github.com/aknysh.png [sarkis_homepage]: https://github.com/sarkis - [sarkis_avatar]: https://github.com/sarkis.png?size=150 + [sarkis_avatar]: https://img.cloudposse.com/150x150/https://github.com/sarkis.png diff --git a/README.yaml b/README.yaml index f6121cd7..1e273b9a 100644 --- a/README.yaml +++ b/README.yaml @@ -18,9 +18,9 @@ github_repo: cloudposse/terraform-aws-ecs-web-app # Badges to display badges: - - name: "Build Status" - image: "https://travis-ci.org/cloudposse/terraform-aws-ecs-web-app.svg?branch=master" - url: "https://travis-ci.org/cloudposse/terraform-aws-ecs-web-app" + - name: "Codefresh Build Status" + image: "https://g.codefresh.io/api/badges/pipeline/cloudposse/terraform-modules%2Fterraform-aws-ecs-web-app?type=cf-1" + url: "https://g.codefresh.io/public/accounts/cloudposse/pipelines/5dbb22a15c2e97b3b73ab484" - name: "Latest Release" image: "https://img.shields.io/github/release/cloudposse/terraform-aws-ecs-web-app.svg" url: "https://github.com/cloudposse/terraform-aws-ecs-web-app/releases/latest" @@ -70,30 +70,33 @@ description: |- # How to use this project usage: |- - Module usage examples: + For a complete example, see [examples/complete](examples/complete). - - [without authentication](examples/without_authentication) - complete example without authentication - - [with Google OIDC authentication](examples/with_google_oidc_authentication) - complete example with Google OIDC authentication - - [with Cognito authentication](examples/with_cognito_authentication) - complete example with Cognito authentication + For automated tests of the complete example using [bats](https://github.com/bats-core/bats-core) and [Terratest](https://github.com/gruntwork-io/terratest) (which test and deploy the example on AWS), see [test](test). + Other examples: + + - [without authentication](examples/without_authentication) - without authentication + - [with Google OIDC authentication](examples/with_google_oidc_authentication) - with Google OIDC authentication + - [with Cognito authentication](examples/with_cognito_authentication) - with Cognito authentication ``` - module "default-backend-web-app" { + module "default_backend_web_app" { source = "git::https://github.com/cloudposse/terraform-aws-ecs-web-app.git?ref=master" namespace = "eg" stage = "testing" name = "appname" - vpc_id = "${module.vpc.vpc_id}" - alb_ingress_unauthenticated_listener_arns = "${module.alb.listener_arns}" - alb_ingress_unauthenticated_listener_arns_count = "1" - aws_logs_region = "us-west-2" - ecs_cluster_arn = "${aws_ecs_cluster.default.arn}" - ecs_cluster_name = "${aws_ecs_cluster.default.name}" - ecs_security_group_ids = ["${module.vpc.vpc_default_security_group_id}"] - ecs_private_subnet_ids = ["${module.subnets.private_subnet_ids}"] + vpc_id = module.vpc.vpc_id + alb_ingress_unauthenticated_listener_arns = module.alb.listener_arns + alb_ingress_unauthenticated_listener_arns_count = 1 + aws_logs_region = "us-east-2" + ecs_cluster_arn = aws_ecs_cluster.default.arn + ecs_cluster_name = aws_ecs_cluster.default.name + ecs_security_group_ids = [module.vpc.vpc_default_security_group_id] + ecs_private_subnet_ids = module.subnets.private_subnet_ids alb_ingress_healthcheck_path = "/healthz" alb_ingress_unauthenticated_paths = ["/*"] - codepipeline_enabled = "false" + codepipeline_enabled = false environment = [ { diff --git a/codefresh/test.yml b/codefresh/test.yml new file mode 100644 index 00000000..ddd07f97 --- /dev/null +++ b/codefresh/test.yml @@ -0,0 +1,74 @@ +version: '1.0' + +stages: + - Prepare + - Test + +steps: + wait: + title: Wait + stage: Prepare + image: codefresh/cli:latest + commands: + - codefresh get builds --pipeline=${{CF_REPO_NAME}} --status running --limit 1000 -o json | jq --arg id ${{CF_BUILD_ID}} -ser 'flatten|.[-1].id==$id' + retry: + maxAttempts: 10 + delay: 20 + exponentialFactor: 1.1 + + main_clone: + title: "Clone repository" + type: git-clone + stage: Prepare + description: "Initialize" + repo: ${{CF_REPO_OWNER}}/${{CF_REPO_NAME}} + git: CF-default + revision: ${{CF_REVISION}} + + clean_init: + title: Prepare build-harness and test-harness + image: ${{TEST_IMAGE}} + stage: Prepare + commands: + - cf_export PATH="/usr/local/terraform/0.12/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + - make init + - git -C build-harness checkout master + - make -C test/ clean init TEST_HARNESS_BRANCH=master + - make -C test/src clean init + - find . -type d -name '.terraform' | xargs rm -rf + - find . -type f -name 'terraform.tfstate*' -exec rm -f {} \; + + test: + type: "parallel" + title: "Run tests" + description: "Run all tests in parallel" + stage: Test + steps: + test_readme_lint: + title: "Test README.md updated" + stage: "Test" + image: ${{TEST_IMAGE}} + description: Test "readme/lint" + commands: + - make readme/lint + + test_module: + title: Test module with bats + image: ${{TEST_IMAGE}} + stage: Test + commands: + - make -C test/ module + + test_examples_complete: + title: Test "examples/complete" with bats + image: ${{TEST_IMAGE}} + stage: Test + commands: + - make -C test/ examples/complete + + test_examples_complete_terratest: + title: Test "examples/complete" with terratest + image: ${{TEST_IMAGE}} + stage: Test + commands: + - make -C test/src diff --git a/docs/terraform.md b/docs/terraform.md index 1d8bdb77..65a37cf2 100644 --- a/docs/terraform.md +++ b/docs/terraform.md @@ -3,31 +3,29 @@ | Name | Description | Type | Default | Required | |------|-------------|:----:|:-----:|:-----:| | alb_arn_suffix | ARN suffix of the ALB for the Target Group | string | `` | no | -| alb_ingress_authenticated_hosts | Authenticated hosts to match in Hosts header | list | `` | no | -| alb_ingress_authenticated_listener_arns | A list of authenticated ALB listener ARNs to attach ALB listener rules to | list | `` | no | -| alb_ingress_authenticated_listener_arns_count | The number of authenticated ARNs in `alb_ingress_authenticated_listener_arns`. This is necessary to work around a limitation in Terraform where counts cannot be computed | string | `0` | no | -| alb_ingress_authenticated_paths | Authenticated path pattern to match (a maximum of 1 can be defined) | list | `` | no | +| alb_ingress_authenticated_hosts | Authenticated hosts to match in Hosts header | list(string) | `` | no | +| alb_ingress_authenticated_listener_arns | A list of authenticated ALB listener ARNs to attach ALB listener rules to | list(string) | `` | no | +| alb_ingress_authenticated_listener_arns_count | The number of authenticated ARNs in `alb_ingress_authenticated_listener_arns`. This is necessary to work around a limitation in Terraform where counts cannot be computed | number | `0` | no | +| alb_ingress_authenticated_paths | Authenticated path pattern to match (a maximum of 1 can be defined) | list(string) | `` | no | | alb_ingress_healthcheck_path | The path of the healthcheck which the ALB checks | string | `/` | no | -| alb_ingress_listener_authenticated_priority | The priority for the rules with authentication, between 1 and 50000 (1 being highest priority). Must be different from `alb_ingress_listener_unauthenticated_priority` since a listener can't have multiple rules with the same priority | string | `300` | no | -| alb_ingress_listener_unauthenticated_priority | The priority for the rules without authentication, between 1 and 50000 (1 being highest priority). Must be different from `alb_ingress_listener_authenticated_priority` since a listener can't have multiple rules with the same priority | string | `1000` | no | -| alb_ingress_unauthenticated_hosts | Unauthenticated hosts to match in Hosts header | list | `` | no | -| alb_ingress_unauthenticated_listener_arns | A list of unauthenticated ALB listener ARNs to attach ALB listener rules to | list | `` | no | -| alb_ingress_unauthenticated_listener_arns_count | The number of unauthenticated ARNs in `alb_ingress_unauthenticated_listener_arns`. This is necessary to work around a limitation in Terraform where counts cannot be computed | string | `0` | no | -| alb_ingress_unauthenticated_paths | Unauthenticated path pattern to match (a maximum of 1 can be defined) | list | `` | no | -| alb_name | Name of the ALB for the Target Group | string | `` | no | +| alb_ingress_listener_authenticated_priority | The priority for the rules with authentication, between 1 and 50000 (1 being highest priority). Must be different from `alb_ingress_listener_unauthenticated_priority` since a listener can't have multiple rules with the same priority | number | `300` | no | +| alb_ingress_listener_unauthenticated_priority | The priority for the rules without authentication, between 1 and 50000 (1 being highest priority). Must be different from `alb_ingress_listener_authenticated_priority` since a listener can't have multiple rules with the same priority | number | `1000` | no | +| alb_ingress_unauthenticated_hosts | Unauthenticated hosts to match in Hosts header | list(string) | `` | no | +| alb_ingress_unauthenticated_listener_arns | A list of unauthenticated ALB listener ARNs to attach ALB listener rules to | list(string) | `` | no | +| alb_ingress_unauthenticated_listener_arns_count | The number of unauthenticated ARNs in `alb_ingress_unauthenticated_listener_arns`. This is necessary to work around a limitation in Terraform where counts cannot be computed | number | `0` | no | +| alb_ingress_unauthenticated_paths | Unauthenticated path pattern to match (a maximum of 1 can be defined) | list(string) | `` | no | | alb_security_group | Security group of the ALB | string | - | yes | -| alb_target_group_alarms_3xx_threshold | The maximum number of 3XX HTTPCodes in a given period for ECS Service | string | `25` | no | -| alb_target_group_alarms_4xx_threshold | The maximum number of 4XX HTTPCodes in a given period for ECS Service | string | `25` | no | -| alb_target_group_alarms_5xx_threshold | The maximum number of 5XX HTTPCodes in a given period for ECS Service | string | `25` | no | -| alb_target_group_alarms_alarm_actions | A list of ARNs (i.e. SNS Topic ARN) to execute when ALB Target Group alarms transition into an ALARM state from any other state | list | `` | no | -| alb_target_group_alarms_enabled | A boolean to enable/disable CloudWatch Alarms for ALB Target metrics | string | `false` | no | -| alb_target_group_alarms_evaluation_periods | The number of periods to analyze for ALB CloudWatch Alarms | string | `1` | no | -| alb_target_group_alarms_insufficient_data_actions | A list of ARNs (i.e. SNS Topic ARN) to execute when ALB Target Group alarms transition into an INSUFFICIENT_DATA state from any other state | list | `` | no | -| alb_target_group_alarms_ok_actions | A list of ARNs (i.e. SNS Topic ARN) to execute when ALB Target Group alarms transition into an OK state from any other state | list | `` | no | -| alb_target_group_alarms_period | The period (in seconds) to analyze for ALB CloudWatch Alarms | string | `300` | no | -| alb_target_group_alarms_response_time_threshold | The maximum ALB Target Group response time | string | `0.5` | no | -| alb_target_group_arn | Pass target group down to module | string | `` | no | -| attributes | List of attributes to add to label | list | `` | no | +| alb_target_group_alarms_3xx_threshold | The maximum number of 3XX HTTPCodes in a given period for ECS Service | number | `25` | no | +| alb_target_group_alarms_4xx_threshold | The maximum number of 4XX HTTPCodes in a given period for ECS Service | number | `25` | no | +| alb_target_group_alarms_5xx_threshold | The maximum number of 5XX HTTPCodes in a given period for ECS Service | number | `25` | no | +| alb_target_group_alarms_alarm_actions | A list of ARNs (i.e. SNS Topic ARN) to execute when ALB Target Group alarms transition into an ALARM state from any other state | list(string) | `` | no | +| alb_target_group_alarms_enabled | A boolean to enable/disable CloudWatch Alarms for ALB Target metrics | bool | `false` | no | +| alb_target_group_alarms_evaluation_periods | The number of periods to analyze for ALB CloudWatch Alarms | number | `1` | no | +| alb_target_group_alarms_insufficient_data_actions | A list of ARNs (i.e. SNS Topic ARN) to execute when ALB Target Group alarms transition into an INSUFFICIENT_DATA state from any other state | list(string) | `` | no | +| alb_target_group_alarms_ok_actions | A list of ARNs (i.e. SNS Topic ARN) to execute when ALB Target Group alarms transition into an OK state from any other state | list(string) | `` | no | +| alb_target_group_alarms_period | The period (in seconds) to analyze for ALB CloudWatch Alarms | number | `300` | no | +| alb_target_group_alarms_response_time_threshold | The maximum ALB Target Group response time | number | `0.5` | no | +| attributes | Additional attributes (_e.g._ "1") | list(string) | `` | no | | authentication_cognito_user_pool_arn | Cognito User Pool ARN | string | `` | no | | authentication_cognito_user_pool_client_id | Cognito User Pool Client ID | string | `` | no | | authentication_cognito_user_pool_domain | Cognito User Pool Domain. The User Pool Domain should be set to the domain prefix (`xxx`) instead of full domain (https://xxx.auth.us-west-2.amazoncognito.com) | string | `` | no | @@ -39,74 +37,74 @@ | authentication_oidc_user_info_endpoint | OIDC User Info Endpoint | string | `` | no | | authentication_type | Authentication type. Supported values are `COGNITO` and `OIDC` | string | `` | no | | autoscaling_dimension | Dimension to autoscale on (valid options: cpu, memory) | string | `memory` | no | -| autoscaling_enabled | A boolean to enable/disable Autoscaling policy for ECS Service | string | `false` | no | -| autoscaling_max_capacity | Maximum number of running instances of a Service | string | `2` | no | -| autoscaling_min_capacity | Minimum number of running instances of a Service | string | `1` | no | -| autoscaling_scale_down_adjustment | Scaling adjustment to make during scale down event | string | `-1` | no | -| autoscaling_scale_down_cooldown | Period (in seconds) to wait between scale down events | string | `300` | no | -| autoscaling_scale_up_adjustment | Scaling adjustment to make during scale up event | string | `1` | no | -| autoscaling_scale_up_cooldown | Period (in seconds) to wait between scale up events | string | `60` | no | +| autoscaling_enabled | A boolean to enable/disable Autoscaling policy for ECS Service | bool | `false` | no | +| autoscaling_max_capacity | Maximum number of running instances of a Service | number | `2` | no | +| autoscaling_min_capacity | Minimum number of running instances of a Service | number | `1` | no | +| autoscaling_scale_down_adjustment | Scaling adjustment to make during scale down event | number | `-1` | no | +| autoscaling_scale_down_cooldown | Period (in seconds) to wait between scale down events | number | `300` | no | +| autoscaling_scale_up_adjustment | Scaling adjustment to make during scale up event | number | `1` | no | +| autoscaling_scale_up_cooldown | Period (in seconds) to wait between scale up events | number | `60` | no | | aws_logs_region | The region for the AWS Cloudwatch Logs group | string | - | yes | -| badge_enabled | Generates a publicly-accessible URL for the projects build badge. Available as badge_url attribute when enabled | string | `false` | no | -| branch | Branch of the GitHub repository, e.g. master | string | `` | no | +| badge_enabled | Generates a publicly-accessible URL for the projects build badge. Available as badge_url attribute when enabled | bool | `false` | no | +| branch | Branch of the GitHub repository, e.g. `master` | string | `` | no | | build_image | Docker image for build environment, _e.g._ `aws/codebuild/docker:docker:17.09.0` | string | `aws/codebuild/docker:17.09.0` | no | -| build_timeout | How long in minutes, from 5 to 480 (8 hours), for AWS CodeBuild to wait until timing out any related build that does not get marked as completed | string | `60` | no | +| build_timeout | How long in minutes, from 5 to 480 (8 hours), for AWS CodeBuild to wait until timing out any related build that does not get marked as completed | number | `60` | no | | buildspec | Declaration to use for building the project. [For more info](http://docs.aws.amazon.com/codebuild/latest/userguide/build-spec-ref.html) | string | `` | no | -| codepipeline_enabled | A boolean to enable/disable AWS Codepipeline and ECR | string | `true` | no | -| codepipeline_s3_bucket_force_destroy | A boolean that indicates all objects should be deleted from the CodePipeline artifact store S3 bucket so that the bucket can be destroyed without error | string | `false` | no | -| container_cpu | The vCPU setting to control cpu limits of container. (If FARGATE launch type is used below, this must be a supported vCPU size from the table here: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-cpu-memory-error.html) | string | `256` | no | +| codepipeline_enabled | A boolean to enable/disable AWS Codepipeline and ECR | bool | `true` | no | +| codepipeline_s3_bucket_force_destroy | A boolean that indicates all objects should be deleted from the CodePipeline artifact store S3 bucket so that the bucket can be destroyed without error | bool | `false` | no | +| container_cpu | The vCPU setting to control cpu limits of container. (If FARGATE launch type is used below, this must be a supported vCPU size from the table here: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-cpu-memory-error.html) | number | `256` | no | | container_image | The default container image to use in container definition | string | `cloudposse/default-backend` | no | -| container_memory | The amount of RAM to allow container to use in MB. (If FARGATE launch type is used below, this must be a supported Memory size from the table here: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-cpu-memory-error.html) | string | `512` | no | -| container_memory_reservation | The amount of RAM (Soft Limit) to allow container to use in MB. This value must be less than container_memory if set | string | `` | no | -| container_port | The port number on the container bound to assigned host_port | string | `80` | no | -| delimiter | The delimiter to be used in labels | string | `-` | no | -| desired_count | The desired number of tasks to start with. Set this to 0 if using DAEMON Service type. (FARGATE does not suppoert DAEMON Service type) | string | `1` | no | -| ecs_alarms_cpu_utilization_high_alarm_actions | A list of ARNs (i.e. SNS Topic ARN) to notify on CPU Utilization High Alarm action | list | `` | no | -| ecs_alarms_cpu_utilization_high_evaluation_periods | Number of periods to evaluate for the alarm | string | `1` | no | -| ecs_alarms_cpu_utilization_high_ok_actions | A list of ARNs (i.e. SNS Topic ARN) to notify on CPU Utilization High OK action | list | `` | no | -| ecs_alarms_cpu_utilization_high_period | Duration in seconds to evaluate for the alarm | string | `300` | no | -| ecs_alarms_cpu_utilization_high_threshold | The maximum percentage of CPU utilization average | string | `80` | no | -| ecs_alarms_cpu_utilization_low_alarm_actions | A list of ARNs (i.e. SNS Topic ARN) to notify on CPU Utilization Low Alarm action | list | `` | no | -| ecs_alarms_cpu_utilization_low_evaluation_periods | Number of periods to evaluate for the alarm | string | `1` | no | -| ecs_alarms_cpu_utilization_low_ok_actions | A list of ARNs (i.e. SNS Topic ARN) to notify on CPU Utilization Low OK action | list | `` | no | -| ecs_alarms_cpu_utilization_low_period | Duration in seconds to evaluate for the alarm | string | `300` | no | -| ecs_alarms_cpu_utilization_low_threshold | The minimum percentage of CPU utilization average | string | `20` | no | -| ecs_alarms_enabled | A boolean to enable/disable CloudWatch Alarms for ECS Service metrics | string | `false` | no | -| ecs_alarms_memory_utilization_high_alarm_actions | A list of ARNs (i.e. SNS Topic ARN) to notify on Memory Utilization High Alarm action | list | `` | no | -| ecs_alarms_memory_utilization_high_evaluation_periods | Number of periods to evaluate for the alarm | string | `1` | no | -| ecs_alarms_memory_utilization_high_ok_actions | A list of ARNs (i.e. SNS Topic ARN) to notify on Memory Utilization High OK action | list | `` | no | -| ecs_alarms_memory_utilization_high_period | Duration in seconds to evaluate for the alarm | string | `300` | no | -| ecs_alarms_memory_utilization_high_threshold | The maximum percentage of Memory utilization average | string | `80` | no | -| ecs_alarms_memory_utilization_low_alarm_actions | A list of ARNs (i.e. SNS Topic ARN) to notify on Memory Utilization Low Alarm action | list | `` | no | -| ecs_alarms_memory_utilization_low_evaluation_periods | Number of periods to evaluate for the alarm | string | `1` | no | -| ecs_alarms_memory_utilization_low_ok_actions | A list of ARNs (i.e. SNS Topic ARN) to notify on Memory Utilization Low OK action | list | `` | no | -| ecs_alarms_memory_utilization_low_period | Duration in seconds to evaluate for the alarm | string | `300` | no | -| ecs_alarms_memory_utilization_low_threshold | The minimum percentage of Memory utilization average | string | `20` | no | +| container_memory | The amount of RAM to allow container to use in MB. (If FARGATE launch type is used below, this must be a supported Memory size from the table here: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-cpu-memory-error.html) | number | `512` | no | +| container_memory_reservation | The amount of RAM (Soft Limit) to allow container to use in MB. This value must be less than `container_memory` if set | number | `128` | no | +| container_port | The port number on the container bound to assigned host_port | number | `80` | no | +| delimiter | Delimiter between `namespace`, `stage`, `name` and `attributes` | string | `-` | no | +| desired_count | The desired number of tasks to start with. Set this to 0 if using DAEMON Service type. (FARGATE does not suppoert DAEMON Service type) | number | `1` | no | +| ecs_alarms_cpu_utilization_high_alarm_actions | A list of ARNs (i.e. SNS Topic ARN) to notify on CPU Utilization High Alarm action | list(string) | `` | no | +| ecs_alarms_cpu_utilization_high_evaluation_periods | Number of periods to evaluate for the alarm | number | `1` | no | +| ecs_alarms_cpu_utilization_high_ok_actions | A list of ARNs (i.e. SNS Topic ARN) to notify on CPU Utilization High OK action | list(string) | `` | no | +| ecs_alarms_cpu_utilization_high_period | Duration in seconds to evaluate for the alarm | number | `300` | no | +| ecs_alarms_cpu_utilization_high_threshold | The maximum percentage of CPU utilization average | number | `80` | no | +| ecs_alarms_cpu_utilization_low_alarm_actions | A list of ARNs (i.e. SNS Topic ARN) to notify on CPU Utilization Low Alarm action | list(string) | `` | no | +| ecs_alarms_cpu_utilization_low_evaluation_periods | Number of periods to evaluate for the alarm | number | `1` | no | +| ecs_alarms_cpu_utilization_low_ok_actions | A list of ARNs (i.e. SNS Topic ARN) to notify on CPU Utilization Low OK action | list(string) | `` | no | +| ecs_alarms_cpu_utilization_low_period | Duration in seconds to evaluate for the alarm | number | `300` | no | +| ecs_alarms_cpu_utilization_low_threshold | The minimum percentage of CPU utilization average | number | `20` | no | +| ecs_alarms_enabled | A boolean to enable/disable CloudWatch Alarms for ECS Service metrics | bool | `false` | no | +| ecs_alarms_memory_utilization_high_alarm_actions | A list of ARNs (i.e. SNS Topic ARN) to notify on Memory Utilization High Alarm action | list(string) | `` | no | +| ecs_alarms_memory_utilization_high_evaluation_periods | Number of periods to evaluate for the alarm | number | `1` | no | +| ecs_alarms_memory_utilization_high_ok_actions | A list of ARNs (i.e. SNS Topic ARN) to notify on Memory Utilization High OK action | list(string) | `` | no | +| ecs_alarms_memory_utilization_high_period | Duration in seconds to evaluate for the alarm | number | `300` | no | +| ecs_alarms_memory_utilization_high_threshold | The maximum percentage of Memory utilization average | number | `80` | no | +| ecs_alarms_memory_utilization_low_alarm_actions | A list of ARNs (i.e. SNS Topic ARN) to notify on Memory Utilization Low Alarm action | list(string) | `` | no | +| ecs_alarms_memory_utilization_low_evaluation_periods | Number of periods to evaluate for the alarm | number | `1` | no | +| ecs_alarms_memory_utilization_low_ok_actions | A list of ARNs (i.e. SNS Topic ARN) to notify on Memory Utilization Low OK action | list(string) | `` | no | +| ecs_alarms_memory_utilization_low_period | Duration in seconds to evaluate for the alarm | number | `300` | no | +| ecs_alarms_memory_utilization_low_threshold | The minimum percentage of Memory utilization average | number | `20` | no | | ecs_cluster_arn | The ECS Cluster ARN where ECS Service will be provisioned | string | - | yes | | ecs_cluster_name | The ECS Cluster Name to use in ECS Code Pipeline Deployment step | string | - | yes | -| ecs_private_subnet_ids | List of Private Subnet IDs to provision ECS Service onto | list | - | yes | -| ecs_security_group_ids | Additional Security Group IDs to allow into ECS Service | list | `` | no | -| environment | The environment variables for the task definition. This is a list of maps | list | `` | no | +| ecs_private_subnet_ids | List of Private Subnet IDs to provision ECS Service onto | list(string) | - | yes | +| ecs_security_group_ids | Additional Security Group IDs to allow into ECS Service | list(string) | `` | no | +| environment | The environment variables to pass to the container. This is a list of maps | object | `null` | no | | github_oauth_token | GitHub Oauth Token with permissions to access private repositories | string | `` | no | -| github_webhook_events | A list of events which should trigger the webhook. See a list of [available events](https://developer.github.com/v3/activity/events/types/) | list | `` | no | +| github_webhook_events | A list of events which should trigger the webhook. See a list of [available events](https://developer.github.com/v3/activity/events/types/) | list(string) | `` | no | | github_webhooks_token | GitHub OAuth Token with permissions to create webhooks. If not provided, can be sourced from the `GITHUB_TOKEN` environment variable | string | `` | no | -| health_check_grace_period_seconds | Seconds to ignore failing load balancer health checks on newly instantiated tasks to prevent premature shutdown, up to 7200. Only valid for services configured to use load balancers | string | `0` | no | -| healthcheck | A map containing command (string), interval (duration in seconds), retries (1-10, number of times to retry before marking container unhealthy, and startPeriod (0-300, optional grace period to wait, in seconds, before failed healthchecks count toward retries) | map | `` | no | -| host_port | The port number to bind container_port to on the host | string | `` | no | +| health_check_grace_period_seconds | Seconds to ignore failing load balancer health checks on newly instantiated tasks to prevent premature shutdown, up to 7200. Only valid for services configured to use load balancers | number | `0` | no | +| healthcheck | A map containing command (string), timeout, interval (duration in seconds), retries (1-10, number of times to retry before marking container unhealthy), and startPeriod (0-300, optional grace period to wait, in seconds, before failed healthchecks count toward retries) | object | `null` | no | | launch_type | The ECS launch type (valid options: FARGATE or EC2) | string | `FARGATE` | no | -| name | Name (unique identifier for app or service) | string | - | yes | -| namespace | Namespace (e.g. `eg` or `cp`) | string | - | yes | -| poll_source_changes | Periodically check the location of your source content and run the pipeline if changes are detected | string | `false` | no | -| port_mappings | The port mappings to configure for the container. This is a list of maps. Each map should contain "containerPort", "hostPort", and "protocol", where "protocol" is one of "tcp" or "udp". If using containers in a task with the awsvpc or host network mode, the hostPort can either be left blank or set to the same value as the containerPort | list | `` | no | -| protocol | The protocol used for the port mapping. Options: `tcp` or `udp` | string | `tcp` | no | +| log_driver | The log driver to use for the container. If using Fargate launch type, only supported value is awslogs | string | `awslogs` | no | +| name | Name of the application | string | - | yes | +| namespace | Namespace (e.g. `eg` or `cp`) | string | `` | no | +| poll_source_changes | Periodically check the location of your source content and run the pipeline if changes are detected | bool | `false` | no | +| port_mappings | The port mappings to configure for the container. This is a list of maps. Each map should contain "containerPort", "hostPort", and "protocol", where "protocol" is one of "tcp" or "udp". If using containers in a task with the awsvpc or host network mode, the hostPort can either be left blank or set to the same value as the containerPort | object | `` | no | +| region | AWS Region for S3 bucket | string | - | yes | | repo_name | GitHub repository name of the application to be built and deployed to ECS | string | `` | no | | repo_owner | GitHub Organization or Username | string | `` | no | -| secrets | The secrets for the task definition. This is a list of maps | list | `` | no | -| stage | Stage (e.g. `prod`, `dev`, `staging`) | string | - | yes | -| tags | Map of key-value pairs to use for tags | map | `` | no | +| secrets | The secrets to pass to the container. This is a list of maps | object | `null` | no | +| stage | Stage (e.g. `prod`, `dev`, `staging`) | string | `` | no | +| tags | Additional tags (_e.g._ { BusinessUnit : ABC }) | map(string) | `` | no | | vpc_id | The VPC ID where resources are created | string | - | yes | | webhook_authentication | The type of authentication to use. One of IP, GITHUB_HMAC, or UNAUTHENTICATED | string | `GITHUB_HMAC` | no | -| webhook_enabled | Set to false to prevent the module from creating any webhook resources | string | `true` | no | +| webhook_enabled | Set to false to prevent the module from creating any webhook resources | bool | `true` | no | | webhook_filter_json_path | The JSON path to filter on | string | `$.ref` | no | | webhook_filter_match_equals | The value to match on (e.g. refs/heads/{Branch}) | string | `refs/heads/{Branch}` | no | | webhook_target_action | The name of the action in a pipeline you want to connect to the webhook. The action must be from the source (first) stage of the pipeline | string | `Source` | no | @@ -115,13 +113,55 @@ | Name | Description | |------|-------------| -| badge_url | The URL of the build badge when `badge_enabled` is enabled | -| scale_down_policy_arn | Autoscaling scale up policy ARN | -| scale_up_policy_arn | Autoscaling scale up policy ARN | -| service_name | ECS Service Name | -| service_security_group_id | Security Group id of the ECS task | -| task_role_arn | ECS Task role ARN | -| task_role_name | ECS Task role name | -| webhook_id | The CodePipeline webhook's ARN. | -| webhook_url | The CodePipeline webhook's URL. POST events to this endpoint to trigger the target. | +| alb_ingress_target_group_arn | ALB Target Group ARN | +| alb_ingress_target_group_arn_suffix | ALB Target Group ARN suffix | +| alb_ingress_target_group_name | ALB Target Group name | +| codebuild_badge_url | The URL of the build badge when badge_enabled is enabled | +| codebuild_cache_bucket_arn | CodeBuild cache S3 bucket ARN | +| codebuild_cache_bucket_name | CodeBuild cache S3 bucket name | +| codebuild_project_id | CodeBuild project ID | +| codebuild_project_name | CodeBuild project name | +| codebuild_role_arn | CodeBuild IAM Role ARN | +| codebuild_role_id | CodeBuild IAM Role ID | +| codepipeline_arn | CodePipeline ARN | +| codepipeline_id | CodePipeline ID | +| codepipeline_webhook_id | The CodePipeline webhook's ID | +| codepipeline_webhook_url | The CodePipeline webhook's URL. POST events to this endpoint to trigger the target | +| container_definition_json | JSON encoded list of container definitions for use with other terraform resources such as aws_ecs_task_definition | +| container_definition_json_map | JSON encoded container definitions for use with other terraform resources such as aws_ecs_task_definition | +| ecr_registry_id | Registry ID | +| ecr_registry_url | Registry URL | +| ecr_repository_name | Registry name | +| ecs_alarms_cpu_utilization_high_cloudwatch_metric_alarm_arn | ECS CPU utilization high CloudWatch metric alarm ARN | +| ecs_alarms_cpu_utilization_high_cloudwatch_metric_alarm_id | ECS CPU utilization high CloudWatch metric alarm ID | +| ecs_alarms_cpu_utilization_low_cloudwatch_metric_alarm_arn | ECS CPU utilization low CloudWatch metric alarm ARN | +| ecs_alarms_cpu_utilization_low_cloudwatch_metric_alarm_id | ECS CPU utilization low CloudWatch metric alarm ID | +| ecs_alarms_memory_utilization_high_cloudwatch_metric_alarm_arn | ECS Memory utilization high CloudWatch metric alarm ARN | +| ecs_alarms_memory_utilization_high_cloudwatch_metric_alarm_id | ECS Memory utilization high CloudWatch metric alarm ID | +| ecs_alarms_memory_utilization_low_cloudwatch_metric_alarm_arn | ECS Memory utilization low CloudWatch metric alarm ARN | +| ecs_alarms_memory_utilization_low_cloudwatch_metric_alarm_id | ECS Memory utilization low CloudWatch metric alarm ID | +| ecs_cloudwatch_autoscaling_scale_down_policy_arn | ARN of the scale down policy | +| ecs_cloudwatch_autoscaling_scale_up_policy_arn | ARN of the scale up policy | +| ecs_exec_role_policy_id | The ECS service role policy ID, in the form of `role_name:role_policy_name` | +| ecs_exec_role_policy_name | ECS service role name | +| ecs_service_name | ECS Service name | +| ecs_service_role_arn | ECS Service role ARN | +| ecs_service_security_group_id | Security Group ID of the ECS task | +| ecs_task_definition_family | ECS task definition family | +| ecs_task_definition_revision | ECS task definition revision | +| ecs_task_exec_role_arn | ECS Task exec role ARN | +| ecs_task_exec_role_name | ECS Task role name | +| ecs_task_role_arn | ECS Task role ARN | +| ecs_task_role_id | ECS Task role id | +| ecs_task_role_name | ECS Task role name | +| httpcode_elb_5xx_count_cloudwatch_metric_alarm_arn | ALB 5xx count CloudWatch metric alarm ARN | +| httpcode_elb_5xx_count_cloudwatch_metric_alarm_id | ALB 5xx count CloudWatch metric alarm ID | +| httpcode_target_3xx_count_cloudwatch_metric_alarm_arn | ALB Target Group 3xx count CloudWatch metric alarm ARN | +| httpcode_target_3xx_count_cloudwatch_metric_alarm_id | ALB Target Group 3xx count CloudWatch metric alarm ID | +| httpcode_target_4xx_count_cloudwatch_metric_alarm_arn | ALB Target Group 4xx count CloudWatch metric alarm ARN | +| httpcode_target_4xx_count_cloudwatch_metric_alarm_id | ALB Target Group 4xx count CloudWatch metric alarm ID | +| httpcode_target_5xx_count_cloudwatch_metric_alarm_arn | ALB Target Group 5xx count CloudWatch metric alarm ARN | +| httpcode_target_5xx_count_cloudwatch_metric_alarm_id | ALB Target Group 5xx count CloudWatch metric alarm ID | +| target_response_time_average_cloudwatch_metric_alarm_arn | ALB Target Group response time average CloudWatch metric alarm ARN | +| target_response_time_average_cloudwatch_metric_alarm_id | ALB Target Group response time average CloudWatch metric alarm ID | diff --git a/examples/complete/fixtures.us-east-2.tfvars b/examples/complete/fixtures.us-east-2.tfvars new file mode 100644 index 00000000..73cbfa8b --- /dev/null +++ b/examples/complete/fixtures.us-east-2.tfvars @@ -0,0 +1,133 @@ +region = "us-east-2" + +availability_zones = ["us-east-2a", "us-east-2b"] + +namespace = "eg" + +stage = "test" + +name = "ecs-web-app" + +vpc_cidr_block = "172.16.0.0/16" + +container_image = "cloudposse/default-backend" + +container_cpu = 256 + +container_memory = 512 + +container_memory_reservation = 128 + +container_port = 80 + +container_port_mappings = [ + { + containerPort = 80 + hostPort = 80 + protocol = "tcp" + } +] + +desired_count = 1 + +launch_type = "FARGATE" + +alb_target_group_alarms_enabled = true + +alb_target_group_alarms_3xx_threshold = 25 + +alb_target_group_alarms_4xx_threshold = 25 + +alb_target_group_alarms_5xx_threshold = 25 + +alb_target_group_alarms_response_time_threshold = 0.5 + +alb_target_group_alarms_period = 300 + +alb_target_group_alarms_evaluation_periods = 1 + +alb_ingress_healthcheck_path = "/" + +alb_ingress_listener_unauthenticated_priority = 1000 + +alb_ingress_unauthenticated_paths = ["/"] + +aws_logs_region = "us-east-2" + +log_driver = "awslogs" + +ecs_alarms_enabled = true + +ecs_alarms_cpu_utilization_high_threshold = 80 + +ecs_alarms_cpu_utilization_high_evaluation_periods = 1 + +ecs_alarms_cpu_utilization_high_period = 300 + +ecs_alarms_cpu_utilization_low_threshold = 20 + +ecs_alarms_cpu_utilization_low_evaluation_periods = 1 + +ecs_alarms_cpu_utilization_low_period = 300 + +ecs_alarms_memory_utilization_high_threshold = 80 + +ecs_alarms_memory_utilization_high_evaluation_periods = 1 + +ecs_alarms_memory_utilization_high_period = 300 + +ecs_alarms_memory_utilization_low_threshold = 20 + +ecs_alarms_memory_utilization_low_evaluation_periods = 1 + +ecs_alarms_memory_utilization_low_period = 300 + +autoscaling_enabled = true + +autoscaling_dimension = "memory" + +autoscaling_min_capacity = 1 + +autoscaling_max_capacity = 2 + +autoscaling_scale_up_adjustment = 1 + +autoscaling_scale_up_cooldown = 60 + +autoscaling_scale_down_adjustment = -1 + +autoscaling_scale_down_cooldown = 300 + +poll_source_changes = false + +webhook_enabled = false + +webhook_target_action = "Source" + +webhook_filter_json_path = "$.ref" + +webhook_filter_match_equals = "refs/heads/{Branch}" + +authentication_type = "" + +codepipeline_enabled = true + +codepipeline_s3_bucket_force_destroy = true + +codepipeline_github_oauth_token = "test" + +codepipeline_github_webhooks_token = "test" + +codepipeline_github_webhook_events = ["push"] + +codepipeline_repo_owner = "cloudposse" + +codepipeline_repo_name = "default-backend" + +codepipeline_branch = "master" + +codepipeline_badge_enabled = false + +codepipeline_build_image = "aws/codebuild/docker:17.09.0" + +codepipeline_build_timeout = 20 diff --git a/examples/complete/main.tf b/examples/complete/main.tf new file mode 100644 index 00000000..853778a1 --- /dev/null +++ b/examples/complete/main.tf @@ -0,0 +1,197 @@ +provider "aws" { + region = var.region +} + +module "label" { + source = "git::https://github.com/cloudposse/terraform-null-label.git?ref=tags/0.16.0" + namespace = var.namespace + name = var.name + stage = var.stage + delimiter = var.delimiter + attributes = var.attributes + tags = var.tags +} + +module "vpc" { + source = "git::https://github.com/cloudposse/terraform-aws-vpc.git?ref=tags/0.8.1" + namespace = var.namespace + stage = var.stage + name = var.name + delimiter = var.delimiter + attributes = var.attributes + cidr_block = var.vpc_cidr_block + tags = var.tags +} + +module "subnets" { + source = "git::https://github.com/cloudposse/terraform-aws-dynamic-subnets.git?ref=tags/0.16.1" + availability_zones = var.availability_zones + namespace = var.namespace + stage = var.stage + name = var.name + attributes = var.attributes + delimiter = var.delimiter + vpc_id = module.vpc.vpc_id + igw_id = module.vpc.igw_id + cidr_block = module.vpc.vpc_cidr_block + nat_gateway_enabled = true + nat_instance_enabled = false + tags = var.tags +} + +module "alb" { + source = "git::https://github.com/cloudposse/terraform-aws-alb.git?ref=tags/0.7.0" + namespace = var.namespace + stage = var.stage + name = var.name + attributes = var.attributes + delimiter = var.delimiter + vpc_id = module.vpc.vpc_id + security_group_ids = [module.vpc.vpc_default_security_group_id] + subnet_ids = module.subnets.public_subnet_ids + internal = false + http_enabled = true + access_logs_enabled = false + alb_access_logs_s3_bucket_force_destroy = true + access_logs_region = var.region + cross_zone_load_balancing_enabled = true + http2_enabled = true + deletion_protection_enabled = false + tags = var.tags +} + +resource "aws_ecs_cluster" "default" { + name = module.label.id + tags = module.label.tags +} + +resource "aws_sns_topic" "sns_topic" { + name = module.label.id + display_name = "Test terraform-aws-ecs-web-app" + tags = module.label.tags +} + +module "ecs_web_app" { + source = "../.." + namespace = var.namespace + stage = var.stage + name = var.name + attributes = var.attributes + delimiter = var.delimiter + tags = var.tags + + region = var.region + vpc_id = module.vpc.vpc_id + + // Container + container_image = var.container_image + container_cpu = var.container_cpu + container_memory = var.container_memory + container_memory_reservation = var.container_memory_reservation + port_mappings = var.container_port_mappings + log_driver = var.log_driver + aws_logs_region = var.region + healthcheck = var.healthcheck + + // Authentication + authentication_type = var.authentication_type + alb_ingress_listener_unauthenticated_priority = var.alb_ingress_listener_unauthenticated_priority + alb_ingress_listener_authenticated_priority = var.alb_ingress_listener_authenticated_priority + alb_ingress_unauthenticated_hosts = var.alb_ingress_unauthenticated_hosts + alb_ingress_authenticated_hosts = var.alb_ingress_authenticated_hosts + alb_ingress_unauthenticated_paths = var.alb_ingress_unauthenticated_paths + alb_ingress_authenticated_paths = var.alb_ingress_authenticated_paths + authentication_cognito_user_pool_arn = var.authentication_cognito_user_pool_arn + authentication_cognito_user_pool_client_id = var.authentication_cognito_user_pool_client_id + authentication_cognito_user_pool_domain = var.authentication_cognito_user_pool_domain + authentication_oidc_client_id = var.authentication_oidc_client_id + authentication_oidc_client_secret = var.authentication_oidc_client_secret + authentication_oidc_issuer = var.authentication_oidc_issuer + authentication_oidc_authorization_endpoint = var.authentication_oidc_authorization_endpoint + authentication_oidc_token_endpoint = var.authentication_oidc_token_endpoint + authentication_oidc_user_info_endpoint = var.authentication_oidc_user_info_endpoint + + // ECS + ecs_private_subnet_ids = module.subnets.private_subnet_ids + ecs_cluster_arn = aws_ecs_cluster.default.arn + ecs_cluster_name = aws_ecs_cluster.default.name + ecs_security_group_ids = var.ecs_security_group_ids + health_check_grace_period_seconds = var.health_check_grace_period_seconds + desired_count = var.desired_count + launch_type = var.launch_type + container_port = var.container_port + + // ALB + alb_arn_suffix = module.alb.alb_arn_suffix + alb_security_group = module.alb.security_group_id + alb_ingress_unauthenticated_listener_arns = [module.alb.http_listener_arn] + alb_ingress_unauthenticated_listener_arns_count = 1 + alb_ingress_healthcheck_path = var.alb_ingress_healthcheck_path + + // CodePipeline + codepipeline_enabled = var.codepipeline_enabled + badge_enabled = var.codepipeline_badge_enabled + github_oauth_token = var.codepipeline_github_oauth_token + github_webhooks_token = var.codepipeline_github_webhooks_token + github_webhook_events = var.codepipeline_github_webhook_events + repo_owner = var.codepipeline_repo_owner + repo_name = var.codepipeline_repo_name + branch = var.codepipeline_branch + build_image = var.codepipeline_build_image + build_timeout = var.codepipeline_build_timeout + buildspec = var.codepipeline_buildspec + poll_source_changes = var.poll_source_changes + webhook_enabled = var.webhook_enabled + webhook_target_action = var.webhook_target_action + webhook_authentication = var.webhook_authentication + webhook_filter_json_path = var.webhook_filter_json_path + webhook_filter_match_equals = var.webhook_filter_match_equals + codepipeline_s3_bucket_force_destroy = var.codepipeline_s3_bucket_force_destroy + environment = var.environment + secrets = var.secrets + + // Autoscaling + autoscaling_enabled = var.autoscaling_enabled + autoscaling_dimension = var.autoscaling_dimension + autoscaling_min_capacity = var.autoscaling_min_capacity + autoscaling_max_capacity = var.autoscaling_max_capacity + autoscaling_scale_up_adjustment = var.autoscaling_scale_up_adjustment + autoscaling_scale_up_cooldown = var.autoscaling_scale_up_cooldown + autoscaling_scale_down_adjustment = var.autoscaling_scale_down_adjustment + autoscaling_scale_down_cooldown = var.autoscaling_scale_down_cooldown + + // ECS alarms + ecs_alarms_enabled = var.ecs_alarms_enabled + ecs_alarms_cpu_utilization_high_threshold = var.ecs_alarms_cpu_utilization_high_threshold + ecs_alarms_cpu_utilization_high_evaluation_periods = var.ecs_alarms_cpu_utilization_high_evaluation_periods + ecs_alarms_cpu_utilization_high_period = var.ecs_alarms_cpu_utilization_high_period + ecs_alarms_cpu_utilization_low_threshold = var.ecs_alarms_cpu_utilization_low_threshold + ecs_alarms_cpu_utilization_low_evaluation_periods = var.ecs_alarms_cpu_utilization_low_evaluation_periods + ecs_alarms_cpu_utilization_low_period = var.ecs_alarms_cpu_utilization_low_period + ecs_alarms_memory_utilization_high_threshold = var.ecs_alarms_memory_utilization_high_threshold + ecs_alarms_memory_utilization_high_evaluation_periods = var.ecs_alarms_memory_utilization_high_evaluation_periods + ecs_alarms_memory_utilization_high_period = var.ecs_alarms_memory_utilization_high_period + ecs_alarms_memory_utilization_low_threshold = var.ecs_alarms_memory_utilization_low_threshold + ecs_alarms_memory_utilization_low_evaluation_periods = var.ecs_alarms_memory_utilization_low_evaluation_periods + ecs_alarms_memory_utilization_low_period = var.ecs_alarms_memory_utilization_low_period + ecs_alarms_cpu_utilization_high_alarm_actions = [aws_sns_topic.sns_topic.arn] + ecs_alarms_cpu_utilization_high_ok_actions = [aws_sns_topic.sns_topic.arn] + ecs_alarms_cpu_utilization_low_alarm_actions = [aws_sns_topic.sns_topic.arn] + ecs_alarms_cpu_utilization_low_ok_actions = [aws_sns_topic.sns_topic.arn] + ecs_alarms_memory_utilization_high_alarm_actions = [aws_sns_topic.sns_topic.arn] + ecs_alarms_memory_utilization_high_ok_actions = [aws_sns_topic.sns_topic.arn] + ecs_alarms_memory_utilization_low_alarm_actions = [aws_sns_topic.sns_topic.arn] + ecs_alarms_memory_utilization_low_ok_actions = [aws_sns_topic.sns_topic.arn] + + // ALB and Target Group alarms + alb_target_group_alarms_enabled = var.alb_target_group_alarms_enabled + alb_target_group_alarms_evaluation_periods = var.alb_target_group_alarms_evaluation_periods + alb_target_group_alarms_period = var.alb_target_group_alarms_period + alb_target_group_alarms_3xx_threshold = var.alb_target_group_alarms_3xx_threshold + alb_target_group_alarms_4xx_threshold = var.alb_target_group_alarms_4xx_threshold + alb_target_group_alarms_5xx_threshold = var.alb_target_group_alarms_5xx_threshold + alb_target_group_alarms_response_time_threshold = var.alb_target_group_alarms_response_time_threshold + alb_target_group_alarms_alarm_actions = [aws_sns_topic.sns_topic.arn] + alb_target_group_alarms_ok_actions = [aws_sns_topic.sns_topic.arn] + alb_target_group_alarms_insufficient_data_actions = [aws_sns_topic.sns_topic.arn] +} diff --git a/examples/complete/outputs.tf b/examples/complete/outputs.tf new file mode 100644 index 00000000..a49a7c5a --- /dev/null +++ b/examples/complete/outputs.tf @@ -0,0 +1,320 @@ +output "public_subnet_cidrs" { + value = module.subnets.public_subnet_cidrs + description = "Public subnet CIDRs" +} + +output "private_subnet_cidrs" { + value = module.subnets.private_subnet_cidrs + description = "Private subnet CIDRs" +} + +output "vpc_cidr" { + value = module.vpc.vpc_cidr_block + description = "VPC ID" +} + +output "alb_name" { + description = "The ARN suffix of the ALB" + value = module.alb.alb_name +} + +output "alb_arn" { + description = "The ARN of the ALB" + value = module.alb.alb_arn +} + +output "alb_arn_suffix" { + description = "The ARN suffix of the ALB" + value = module.alb.alb_arn_suffix +} + +output "alb_dns_name" { + description = "DNS name of ALB" + value = module.alb.alb_dns_name +} + +output "alb_zone_id" { + description = "The ID of the zone which ALB is provisioned" + value = module.alb.alb_zone_id +} + +output "alb_security_group_id" { + description = "The security group ID of the ALB" + value = module.alb.security_group_id +} + +output "alb_default_target_group_arn" { + description = "The default target group ARN" + value = module.alb.default_target_group_arn +} + +output "alb_http_listener_arn" { + description = "The ARN of the HTTP listener" + value = module.alb.http_listener_arn +} + +output "alb_listener_arns" { + description = "A list of all the listener ARNs" + value = module.alb.listener_arns +} + +output "alb_access_logs_bucket_id" { + description = "The S3 bucket ID for access logs" + value = module.alb.access_logs_bucket_id +} + +output "ecr_registry_id" { + value = module.ecs_web_app.ecr_registry_id + description = "Registry ID" +} + +output "ecr_registry_url" { + value = module.ecs_web_app.ecr_registry_url + description = "Registry URL" +} + +output "ecr_repository_name" { + value = module.ecs_web_app.ecr_repository_name + description = "Registry name" +} + +output "alb_ingress_target_group_name" { + description = "ALB Target Group name" + value = module.ecs_web_app.alb_ingress_target_group_name +} + +output "alb_ingress_target_group_arn" { + description = "ALB Target Group ARN" + value = module.ecs_web_app.alb_ingress_target_group_arn +} + +output "alb_ingress_target_group_arn_suffix" { + description = "ALB Target Group ARN suffix" + value = module.ecs_web_app.alb_ingress_target_group_arn_suffix +} + +output "container_definition_json" { + description = "JSON encoded list of container definitions for use with other terraform resources such as aws_ecs_task_definition" + value = module.ecs_web_app.container_definition_json +} + +output "container_definition_json_map" { + description = "JSON encoded container definitions for use with other terraform resources such as aws_ecs_task_definition" + value = module.ecs_web_app.container_definition_json_map +} + +output "ecs_exec_role_policy_id" { + description = "The ECS service role policy ID, in the form of `role_name:role_policy_name`" + value = module.ecs_web_app.ecs_exec_role_policy_id +} + +output "ecs_exec_role_policy_name" { + description = "ECS service role name" + value = module.ecs_web_app.ecs_exec_role_policy_name +} + +output "ecs_service_name" { + description = "ECS Service name" + value = module.ecs_web_app.ecs_service_name +} + +output "ecs_service_role_arn" { + description = "ECS Service role ARN" + value = module.ecs_web_app.ecs_service_role_arn +} + +output "ecs_task_exec_role_name" { + description = "ECS Task role name" + value = module.ecs_web_app.ecs_task_exec_role_name +} + +output "ecs_task_exec_role_arn" { + description = "ECS Task exec role ARN" + value = module.ecs_web_app.ecs_task_exec_role_arn +} + +output "ecs_task_role_name" { + description = "ECS Task role name" + value = module.ecs_web_app.ecs_task_role_name +} + +output "ecs_task_role_arn" { + description = "ECS Task role ARN" + value = module.ecs_web_app.ecs_task_role_arn +} + +output "ecs_task_role_id" { + description = "ECS Task role id" + value = module.ecs_web_app.ecs_task_role_id +} + +output "ecs_service_security_group_id" { + description = "Security Group ID of the ECS task" + value = module.ecs_web_app.ecs_service_security_group_id +} + +output "ecs_task_definition_family" { + description = "ECS task definition family" + value = module.ecs_web_app.ecs_task_definition_family +} + +output "ecs_task_definition_revision" { + description = "ECS task definition revision" + value = module.ecs_web_app.ecs_task_definition_revision +} + +output "codebuild_project_name" { + description = "CodeBuild project name" + value = module.ecs_web_app.codebuild_project_name +} + +output "codebuild_project_id" { + description = "CodeBuild project ID" + value = module.ecs_web_app.codebuild_project_id +} + +output "codebuild_role_id" { + description = "CodeBuild IAM Role ID" + value = module.ecs_web_app.codebuild_role_id +} + +output "codebuild_role_arn" { + description = "CodeBuild IAM Role ARN" + value = module.ecs_web_app.codebuild_role_arn +} + +output "codebuild_cache_bucket_name" { + description = "CodeBuild cache S3 bucket name" + value = module.ecs_web_app.codebuild_cache_bucket_name +} + +output "codebuild_cache_bucket_arn" { + description = "CodeBuild cache S3 bucket ARN" + value = module.ecs_web_app.codebuild_cache_bucket_arn +} + +output "codebuild_badge_url" { + description = "The URL of the build badge when badge_enabled is enabled" + value = module.ecs_web_app.codebuild_badge_url +} + +output "codepipeline_id" { + description = "CodePipeline ID" + value = module.ecs_web_app.codepipeline_id +} + +output "codepipeline_arn" { + description = "CodePipeline ARN" + value = module.ecs_web_app.codepipeline_arn +} + +output "codepipeline_webhook_id" { + description = "The CodePipeline webhook's ID" + value = module.ecs_web_app.codepipeline_webhook_id +} + +output "codepipeline_webhook_url" { + description = "The CodePipeline webhook's URL. POST events to this endpoint to trigger the target" + value = module.ecs_web_app.codepipeline_webhook_url + sensitive = true +} + +output "ecs_cloudwatch_autoscaling_scale_up_policy_arn" { + description = "ARN of the scale up policy" + value = module.ecs_web_app.ecs_cloudwatch_autoscaling_scale_up_policy_arn +} + +output "ecs_cloudwatch_autoscaling_scale_down_policy_arn" { + description = "ARN of the scale down policy" + value = module.ecs_web_app.ecs_cloudwatch_autoscaling_scale_down_policy_arn +} + +output "ecs_alarms_cpu_utilization_high_cloudwatch_metric_alarm_id" { + value = module.ecs_web_app.ecs_alarms_cpu_utilization_high_cloudwatch_metric_alarm_id + description = "ECS CPU utilization high CloudWatch metric alarm ID" +} + +output "ecs_alarms_cpu_utilization_high_cloudwatch_metric_alarm_arn" { + value = module.ecs_web_app.ecs_alarms_cpu_utilization_high_cloudwatch_metric_alarm_arn + description = "ECS CPU utilization high CloudWatch metric alarm ARN" +} + +output "ecs_alarms_cpu_utilization_low_cloudwatch_metric_alarm_id" { + value = module.ecs_web_app.ecs_alarms_cpu_utilization_low_cloudwatch_metric_alarm_id + description = "ECS CPU utilization low CloudWatch metric alarm ID" +} + +output "ecs_alarms_cpu_utilization_low_cloudwatch_metric_alarm_arn" { + value = module.ecs_web_app.ecs_alarms_cpu_utilization_low_cloudwatch_metric_alarm_arn + description = "ECS CPU utilization low CloudWatch metric alarm ARN" +} + +output "ecs_alarms_memory_utilization_high_cloudwatch_metric_alarm_id" { + value = module.ecs_web_app.ecs_alarms_memory_utilization_high_cloudwatch_metric_alarm_id + description = "ECS Memory utilization high CloudWatch metric alarm ID" +} + +output "ecs_alarms_memory_utilization_high_cloudwatch_metric_alarm_arn" { + value = module.ecs_web_app.ecs_alarms_memory_utilization_high_cloudwatch_metric_alarm_arn + description = "ECS Memory utilization high CloudWatch metric alarm ARN" +} + +output "ecs_alarms_memory_utilization_low_cloudwatch_metric_alarm_id" { + value = module.ecs_web_app.ecs_alarms_memory_utilization_low_cloudwatch_metric_alarm_id + description = "ECS Memory utilization low CloudWatch metric alarm ID" +} + +output "ecs_alarms_memory_utilization_low_cloudwatch_metric_alarm_arn" { + value = module.ecs_web_app.ecs_alarms_memory_utilization_low_cloudwatch_metric_alarm_arn + description = "ECS Memory utilization low CloudWatch metric alarm ARN" +} + +output "httpcode_target_3xx_count_cloudwatch_metric_alarm_id" { + value = module.ecs_web_app.httpcode_target_3xx_count_cloudwatch_metric_alarm_id + description = "ALB Target Group 3xx count CloudWatch metric alarm ID" +} + +output "httpcode_target_3xx_count_cloudwatch_metric_alarm_arn" { + value = module.ecs_web_app.httpcode_target_3xx_count_cloudwatch_metric_alarm_arn + description = "ALB Target Group 3xx count CloudWatch metric alarm ARN" +} + +output "httpcode_target_4xx_count_cloudwatch_metric_alarm_id" { + value = module.ecs_web_app.httpcode_target_4xx_count_cloudwatch_metric_alarm_id + description = "ALB Target Group 4xx count CloudWatch metric alarm ID" +} + +output "httpcode_target_4xx_count_cloudwatch_metric_alarm_arn" { + value = module.ecs_web_app.httpcode_target_4xx_count_cloudwatch_metric_alarm_arn + description = "ALB Target Group 4xx count CloudWatch metric alarm ARN" +} + +output "httpcode_target_5xx_count_cloudwatch_metric_alarm_id" { + value = module.ecs_web_app.httpcode_target_5xx_count_cloudwatch_metric_alarm_id + description = "ALB Target Group 5xx count CloudWatch metric alarm ID" +} + +output "httpcode_target_5xx_count_cloudwatch_metric_alarm_arn" { + value = module.ecs_web_app.httpcode_target_5xx_count_cloudwatch_metric_alarm_arn + description = "ALB Target Group 5xx count CloudWatch metric alarm ARN" +} + +output "httpcode_elb_5xx_count_cloudwatch_metric_alarm_id" { + value = module.ecs_web_app.httpcode_elb_5xx_count_cloudwatch_metric_alarm_id + description = "ALB 5xx count CloudWatch metric alarm ID" +} + +output "httpcode_elb_5xx_count_cloudwatch_metric_alarm_arn" { + value = module.ecs_web_app.httpcode_elb_5xx_count_cloudwatch_metric_alarm_arn + description = "ALB 5xx count CloudWatch metric alarm ARN" +} + +output "target_response_time_average_cloudwatch_metric_alarm_id" { + value = module.ecs_web_app.target_response_time_average_cloudwatch_metric_alarm_id + description = "ALB Target Group response time average CloudWatch metric alarm ID" +} + +output "target_response_time_average_cloudwatch_metric_alarm_arn" { + value = module.ecs_web_app.target_response_time_average_cloudwatch_metric_alarm_arn + description = "ALB Target Group response time average CloudWatch metric alarm ARN" +} diff --git a/examples/complete/variables.tf b/examples/complete/variables.tf new file mode 100644 index 00000000..35cb88f2 --- /dev/null +++ b/examples/complete/variables.tf @@ -0,0 +1,541 @@ +variable "region" { + type = string + description = "AWS Region for S3 bucket" +} + +variable "availability_zones" { + type = list(string) + description = "List of availability zones" +} + +variable "vpc_cidr_block" { + type = string + description = "VPC CIDR block" +} + +variable "namespace" { + type = string + description = "Namespace (e.g. `eg` or `cp`)" + default = "" +} + +variable "stage" { + type = string + description = "Stage (e.g. `prod`, `dev`, `staging`)" + default = "" +} + +variable "name" { + type = string + description = "Name of the application" +} + +variable "delimiter" { + type = string + default = "-" + description = "Delimiter between `namespace`, `stage`, `name` and `attributes`" +} + +variable "attributes" { + type = list(string) + description = "Additional attributes (_e.g._ \"1\")" + default = [] +} + +variable "tags" { + type = map(string) + description = "Additional tags (_e.g._ { BusinessUnit : ABC })" + default = {} +} + +variable "codepipeline_enabled" { + type = bool + description = "A boolean to enable/disable AWS Codepipeline and ECR" + default = true +} + +variable "container_image" { + type = string + description = "The default container image to use in container definition" + default = "cloudposse/default-backend" +} + +variable "container_cpu" { + type = number + description = "The vCPU setting to control cpu limits of container. (If FARGATE launch type is used below, this must be a supported vCPU size from the table here: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-cpu-memory-error.html)" + default = 256 +} + +variable "container_memory" { + type = number + description = "The amount of RAM to allow container to use in MB. (If FARGATE launch type is used below, this must be a supported Memory size from the table here: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-cpu-memory-error.html)" + default = 512 +} + +variable "container_memory_reservation" { + type = number + description = "The amount of RAM (Soft Limit) to allow container to use in MB. This value must be less than `container_memory` if set" + default = 128 +} + +variable "container_port" { + type = number + description = "The port number on the container bound to assigned host_port" + default = 80 +} + +variable "container_port_mappings" { + type = list(object({ + containerPort = number + hostPort = number + protocol = string + })) + + description = "The port mappings to configure for the container. This is a list of maps. Each map should contain \"containerPort\", \"hostPort\", and \"protocol\", where \"protocol\" is one of \"tcp\" or \"udp\". If using containers in a task with the awsvpc or host network mode, the hostPort can either be left blank or set to the same value as the containerPort" + + default = [ + { + containerPort = 80 + hostPort = 80 + protocol = "tcp" + } + ] +} + +variable "desired_count" { + type = number + description = "The desired number of tasks to start with. Set this to 0 if using DAEMON Service type. (FARGATE does not suppoert DAEMON Service type)" + default = 1 +} + +variable "launch_type" { + type = string + description = "The ECS launch type (valid options: FARGATE or EC2)" + default = "FARGATE" +} + +variable "environment" { + type = list(object({ + name = string + value = string + })) + description = "The environment variables to pass to the container. This is a list of maps" + default = null +} + +variable "secrets" { + type = list(object({ + name = string + valueFrom = string + })) + description = "The secrets to pass to the container. This is a list of maps" + default = null +} + +# https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_HealthCheck.html +variable "healthcheck" { + type = object({ + command = list(string) + retries = number + timeout = number + interval = number + startPeriod = number + }) + description = "A map containing command (string), timeout, interval (duration in seconds), retries (1-10, number of times to retry before marking container unhealthy), and startPeriod (0-300, optional grace period to wait, in seconds, before failed healthchecks count toward retries)" + default = null +} + +variable "health_check_grace_period_seconds" { + type = number + description = "Seconds to ignore failing load balancer health checks on newly instantiated tasks to prevent premature shutdown, up to 7200. Only valid for services configured to use load balancers" + default = 0 +} + +variable "alb_target_group_alarms_enabled" { + type = bool + description = "A boolean to enable/disable CloudWatch Alarms for ALB Target metrics" + default = false +} + +variable "alb_target_group_alarms_3xx_threshold" { + type = number + description = "The maximum number of 3XX HTTPCodes in a given period for ECS Service" + default = 25 +} + +variable "alb_target_group_alarms_4xx_threshold" { + type = number + description = "The maximum number of 4XX HTTPCodes in a given period for ECS Service" + default = 25 +} + +variable "alb_target_group_alarms_5xx_threshold" { + type = number + description = "The maximum number of 5XX HTTPCodes in a given period for ECS Service" + default = 25 +} + +variable "alb_target_group_alarms_response_time_threshold" { + type = number + description = "The maximum ALB Target Group response time" + default = 0.5 +} + +variable "alb_target_group_alarms_period" { + type = number + description = "The period (in seconds) to analyze for ALB CloudWatch Alarms" + default = 300 +} + +variable "alb_target_group_alarms_evaluation_periods" { + type = number + description = "The number of periods to analyze for ALB CloudWatch Alarms" + default = 1 +} + +variable "alb_ingress_healthcheck_path" { + type = string + description = "The path of the healthcheck which the ALB checks" + default = "/" +} + +variable "alb_ingress_listener_unauthenticated_priority" { + type = number + default = 1000 + description = "The priority for the rules without authentication, between 1 and 50000 (1 being highest priority). Must be different from `alb_ingress_listener_authenticated_priority` since a listener can't have multiple rules with the same priority" +} + +variable "alb_ingress_listener_authenticated_priority" { + type = number + default = 300 + description = "The priority for the rules with authentication, between 1 and 50000 (1 being highest priority). Must be different from `alb_ingress_listener_unauthenticated_priority` since a listener can't have multiple rules with the same priority" +} + +variable "alb_ingress_unauthenticated_hosts" { + type = list(string) + default = [] + description = "Unauthenticated hosts to match in Hosts header" +} + +variable "alb_ingress_authenticated_hosts" { + type = list(string) + default = [] + description = "Authenticated hosts to match in Hosts header" +} + +variable "alb_ingress_unauthenticated_paths" { + type = list(string) + default = [] + description = "Unauthenticated path pattern to match (a maximum of 1 can be defined)" +} + +variable "alb_ingress_authenticated_paths" { + type = list(string) + default = [] + description = "Authenticated path pattern to match (a maximum of 1 can be defined)" +} + +variable "aws_logs_region" { + type = string + description = "The region for the AWS Cloudwatch Logs group" +} + +variable "log_driver" { + type = string + description = "The log driver to use for the container. If using Fargate launch type, only supported value is awslogs" + default = "awslogs" +} + +variable "ecs_alarms_enabled" { + type = bool + description = "A boolean to enable/disable CloudWatch Alarms for ECS Service metrics" + default = false +} + +variable "ecs_alarms_cpu_utilization_high_threshold" { + type = number + description = "The maximum percentage of CPU utilization average" + default = 80 +} + +variable "ecs_alarms_cpu_utilization_high_evaluation_periods" { + type = number + description = "Number of periods to evaluate for the alarm" + default = 1 +} + +variable "ecs_alarms_cpu_utilization_high_period" { + type = number + description = "Duration in seconds to evaluate for the alarm" + default = 300 +} + +variable "ecs_alarms_cpu_utilization_low_threshold" { + type = number + description = "The minimum percentage of CPU utilization average" + default = 20 +} + +variable "ecs_alarms_cpu_utilization_low_evaluation_periods" { + type = number + description = "Number of periods to evaluate for the alarm" + default = 1 +} + +variable "ecs_alarms_cpu_utilization_low_period" { + type = number + description = "Duration in seconds to evaluate for the alarm" + default = 300 +} + +variable "ecs_alarms_memory_utilization_high_threshold" { + type = number + description = "The maximum percentage of Memory utilization average" + default = 80 +} + +variable "ecs_alarms_memory_utilization_high_evaluation_periods" { + type = number + description = "Number of periods to evaluate for the alarm" + default = 1 +} + +variable "ecs_alarms_memory_utilization_high_period" { + type = number + description = "Duration in seconds to evaluate for the alarm" + default = 300 +} + +variable "ecs_alarms_memory_utilization_low_threshold" { + type = number + description = "The minimum percentage of Memory utilization average" + default = 20 +} + +variable "ecs_alarms_memory_utilization_low_evaluation_periods" { + type = number + description = "Number of periods to evaluate for the alarm" + default = 1 +} + +variable "ecs_alarms_memory_utilization_low_period" { + type = number + description = "Duration in seconds to evaluate for the alarm" + default = 300 +} + +variable "ecs_security_group_ids" { + type = list(string) + description = "Additional Security Group IDs to allow into ECS Service" + default = [] +} + +variable "codepipeline_github_oauth_token" { + type = string + description = "GitHub Oauth Token with permissions to access private repositories" + default = "" +} + +variable "codepipeline_github_webhooks_token" { + type = string + description = "GitHub OAuth Token with permissions to create webhooks. If not provided, can be sourced from the `GITHUB_TOKEN` environment variable" + default = "" +} + +variable "codepipeline_github_webhook_events" { + type = list(string) + description = "A list of events which should trigger the webhook. See a list of [available events](https://developer.github.com/v3/activity/events/types/)" + default = ["push"] +} + +variable "codepipeline_repo_owner" { + type = string + description = "GitHub Organization or Username" + default = "" +} + +variable "codepipeline_repo_name" { + type = string + description = "GitHub repository name of the application to be built and deployed to ECS" + default = "" +} + +variable "codepipeline_branch" { + type = string + description = "Branch of the GitHub repository, e.g. `master`" + default = "" +} + +variable "codepipeline_badge_enabled" { + type = bool + default = false + description = "Generates a publicly-accessible URL for the projects build badge. Available as badge_url attribute when enabled" +} + +variable "codepipeline_build_image" { + type = string + default = "aws/codebuild/docker:17.09.0" + description = "Docker image for build environment, _e.g._ `aws/codebuild/docker:docker:17.09.0`" +} + +variable "codepipeline_build_timeout" { + type = number + default = 60 + description = "How long in minutes, from 5 to 480 (8 hours), for AWS CodeBuild to wait until timing out any related build that does not get marked as completed" +} + +variable "codepipeline_buildspec" { + type = string + description = "Declaration to use for building the project. [For more info](http://docs.aws.amazon.com/codebuild/latest/userguide/build-spec-ref.html)" + default = "" +} + +variable "autoscaling_enabled" { + type = bool + description = "A boolean to enable/disable Autoscaling policy for ECS Service" + default = false +} + +variable "autoscaling_dimension" { + type = string + description = "Dimension to autoscale on (valid options: cpu, memory)" + default = "memory" +} + +variable "autoscaling_min_capacity" { + type = number + description = "Minimum number of running instances of a Service" + default = 1 +} + +variable "autoscaling_max_capacity" { + type = number + description = "Maximum number of running instances of a Service" + default = 2 +} + +variable "autoscaling_scale_up_adjustment" { + type = number + description = "Scaling adjustment to make during scale up event" + default = 1 +} + +variable "autoscaling_scale_up_cooldown" { + type = number + description = "Period (in seconds) to wait between scale up events" + default = 60 +} + +variable "autoscaling_scale_down_adjustment" { + type = number + description = "Scaling adjustment to make during scale down event" + default = -1 +} + +variable "autoscaling_scale_down_cooldown" { + type = number + description = "Period (in seconds) to wait between scale down events" + default = 300 +} + +variable "poll_source_changes" { + type = bool + default = false + description = "Periodically check the location of your source content and run the pipeline if changes are detected" +} + +variable "webhook_enabled" { + type = bool + description = "Set to false to prevent the module from creating any webhook resources" + default = true +} + +variable "webhook_target_action" { + type = string + description = "The name of the action in a pipeline you want to connect to the webhook. The action must be from the source (first) stage of the pipeline" + default = "Source" +} + +variable "webhook_authentication" { + type = string + description = "The type of authentication to use. One of IP, GITHUB_HMAC, or UNAUTHENTICATED" + default = "GITHUB_HMAC" +} + +variable "webhook_filter_json_path" { + type = string + description = "The JSON path to filter on" + default = "$.ref" +} + +variable "webhook_filter_match_equals" { + type = string + description = "The value to match on (e.g. refs/heads/{Branch})" + default = "refs/heads/{Branch}" +} + +variable "authentication_type" { + type = string + description = "Authentication type. Supported values are `COGNITO` and `OIDC`" + default = "" +} + +variable "authentication_cognito_user_pool_arn" { + type = string + description = "Cognito User Pool ARN" + default = "" +} + +variable "authentication_cognito_user_pool_client_id" { + type = string + description = "Cognito User Pool Client ID" + default = "" +} + +variable "authentication_cognito_user_pool_domain" { + type = string + description = "Cognito User Pool Domain. The User Pool Domain should be set to the domain prefix (`xxx`) instead of full domain (https://xxx.auth.us-west-2.amazoncognito.com)" + default = "" +} + +variable "authentication_oidc_client_id" { + type = string + description = "OIDC Client ID" + default = "" +} + +variable "authentication_oidc_client_secret" { + type = string + description = "OIDC Client Secret" + default = "" +} + +variable "authentication_oidc_issuer" { + type = string + description = "OIDC Issuer" + default = "" +} + +variable "authentication_oidc_authorization_endpoint" { + type = string + description = "OIDC Authorization Endpoint" + default = "" +} + +variable "authentication_oidc_token_endpoint" { + type = string + description = "OIDC Token Endpoint" + default = "" +} + +variable "authentication_oidc_user_info_endpoint" { + type = string + description = "OIDC User Info Endpoint" + default = "" +} + +variable "codepipeline_s3_bucket_force_destroy" { + type = bool + description = "A boolean that indicates all objects should be deleted from the CodePipeline artifact store S3 bucket so that the bucket can be destroyed without error" + default = false +} diff --git a/examples/complete/versions.tf b/examples/complete/versions.tf new file mode 100644 index 00000000..9840ed75 --- /dev/null +++ b/examples/complete/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = "~> 0.12.0" + + required_providers { + aws = "~> 2.0" + template = "~> 2.0" + null = "~> 2.0" + local = "~> 1.3" + } +} diff --git a/examples/with_cognito_authentication/main.tf b/examples/with_cognito_authentication/main.tf index 73664079..11cbbb21 100644 --- a/examples/with_cognito_authentication/main.tf +++ b/examples/with_cognito_authentication/main.tf @@ -1,76 +1,84 @@ provider "aws" { - region = "${var.region}" + region = var.region } module "vpc" { - source = "git::https://github.com/cloudposse/terraform-aws-vpc.git?ref=tags/0.3.4" - namespace = "${var.namespace}" - stage = "${var.stage}" - name = "${var.name}" + source = "git::https://github.com/cloudposse/terraform-aws-vpc.git?ref=tags/0.8.1" + namespace = var.namespace + stage = var.stage + name = var.name cidr_block = "172.16.0.0/16" } -data "aws_availability_zones" "available" {} +data "aws_availability_zones" "available" { +} locals { - availability_zones = "${slice(data.aws_availability_zones.available.names, 0, 2)}" + availability_zones = slice(data.aws_availability_zones.available.names, 0, 2) } module "subnets" { - source = "git::https://github.com/cloudposse/terraform-aws-dynamic-subnets.git?ref=tags/0.3.6" - availability_zones = "${local.availability_zones}" - namespace = "${var.namespace}" - stage = "${var.stage}" - name = "${var.name}" - region = "${var.region}" - vpc_id = "${module.vpc.vpc_id}" - igw_id = "${module.vpc.igw_id}" - cidr_block = "${module.vpc.vpc_cidr_block}" - nat_gateway_enabled = "true" + source = "git::https://github.com/cloudposse/terraform-aws-dynamic-subnets.git?ref=tags/0.16.1" + availability_zones = local.availability_zones + namespace = var.namespace + stage = var.stage + name = var.name + region = var.region + vpc_id = module.vpc.vpc_id + igw_id = module.vpc.igw_id + cidr_block = module.vpc.vpc_cidr_block + nat_gateway_enabled = true + nat_instance_enabled = false } module "alb" { - source = "git::https://github.com/cloudposse/terraform-aws-alb.git?ref=tags/0.2.6" - name = "${var.name}" - namespace = "${var.namespace}" - stage = "${var.stage}" - attributes = ["${compact(concat(var.attributes, list("alb")))}"] - vpc_id = "${module.vpc.vpc_id}" + source = "git::https://github.com/cloudposse/terraform-aws-alb.git?ref=tags/0.7.0" + name = var.name + namespace = var.namespace + stage = var.stage + attributes = [compact(concat(var.attributes, ["alb"]))] + vpc_id = module.vpc.vpc_id ip_address_type = "ipv4" - subnet_ids = ["${module.subnets.public_subnet_ids}"] - security_group_ids = ["${module.vpc.vpc_default_security_group_id}"] - access_logs_region = "${var.region}" - https_enabled = "true" + subnet_ids = [module.subnets.public_subnet_ids] + security_group_ids = [module.vpc.vpc_default_security_group_id] + access_logs_region = var.region + https_enabled = true http_ingress_cidr_blocks = ["0.0.0.0/0"] https_ingress_cidr_blocks = ["0.0.0.0/0"] - certificate_arn = "${var.certificate_arn}" - health_check_interval = "60" + certificate_arn = var.certificate_arn + health_check_interval = 60 } -module "ecs_cluster_label" { - source = "git::https://github.com/cloudposse/terraform-terraform-label.git?ref=tags/0.2.1" - name = "${var.name}" - namespace = "${var.namespace}" - stage = "${var.stage}" - tags = "${var.tags}" - attributes = "${var.attributes}" - delimiter = "${var.delimiter}" +module "label" { + source = "git::https://github.com/cloudposse/terraform-null-label.git?ref=tags/0.16.0" + name = var.name + namespace = var.namespace + stage = var.stage + tags = var.tags + attributes = var.attributes + delimiter = var.delimiter } # ECS Cluster (needed even if using FARGATE launch type) resource "aws_ecs_cluster" "default" { - name = "${module.ecs_cluster_label.id}" + name = module.label.id +} + +resource "aws_cloudwatch_log_group" "app" { + name = module.label.id + tags = module.label.tags } module "web_app" { source = "../../" - namespace = "${var.namespace}" - stage = "${var.stage}" - name = "${var.name}" - attributes = ["${compact(concat(var.attributes, list("app")))}"] + namespace = var.namespace + stage = var.stage + name = var.name + attributes = compact(concat(var.attributes, ["app"])) + region = var.region launch_type = "FARGATE" - vpc_id = "${module.vpc.vpc_id}" + vpc_id = module.vpc.vpc_id environment = [ { @@ -79,70 +87,74 @@ module "web_app" { }, { name = "VPC_ID" - value = "${module.vpc.vpc_id}" - }, + value = module.vpc.vpc_id + } ] desired_count = 1 - container_image = "${var.default_container_image}" - container_cpu = "256" - container_memory = "512" - container_port = "80" - build_timeout = 5 - - port_mappings = [{ - "containerPort" = 80 - "hostPort" = 80 - "protocol" = "tcp" - }] - - codepipeline_enabled = "false" - webhook_enabled = "false" - badge_enabled = "false" - ecs_alarms_enabled = "false" - autoscaling_enabled = "false" + container_image = var.default_container_image + container_cpu = 256 + container_memory = 512 + container_port = 80 + build_timeout = 10 + + log_configuration = { + logDriver = "awslogs" + options = { + "awslogs-region" = var.region + "awslogs-group" = aws_cloudwatch_log_group.app.name + "awslogs-stream-prefix" = var.name + } + secretOptions = null + } + + codepipeline_enabled = false + webhook_enabled = false + badge_enabled = false + ecs_alarms_enabled = false + autoscaling_enabled = false autoscaling_dimension = "cpu" autoscaling_min_capacity = 1 autoscaling_max_capacity = 2 - autoscaling_scale_up_adjustment = "1" - autoscaling_scale_up_cooldown = "60" - autoscaling_scale_down_adjustment = "-1" - autoscaling_scale_down_cooldown = "300" - - aws_logs_region = "${var.region}" - ecs_cluster_arn = "${aws_ecs_cluster.default.arn}" - ecs_cluster_name = "${aws_ecs_cluster.default.name}" - ecs_security_group_ids = ["${module.vpc.vpc_default_security_group_id}"] - ecs_private_subnet_ids = ["${module.subnets.private_subnet_ids}"] - - alb_target_group_alarms_enabled = "true" - alb_target_group_alarms_3xx_threshold = "25" - alb_target_group_alarms_4xx_threshold = "25" - alb_target_group_alarms_5xx_threshold = "25" - alb_target_group_alarms_response_time_threshold = "0.5" - alb_target_group_alarms_period = "300" - alb_target_group_alarms_evaluation_periods = "1" - - alb_arn_suffix = "${module.alb.alb_arn_suffix}" - alb_name = "${module.alb.alb_name}" + autoscaling_scale_up_adjustment = 1 + autoscaling_scale_up_cooldown = 60 + autoscaling_scale_down_adjustment = -1 + autoscaling_scale_down_cooldown = 300 + + aws_logs_region = var.region + ecs_cluster_arn = aws_ecs_cluster.default.arn + ecs_cluster_name = aws_ecs_cluster.default.name + ecs_security_group_ids = [module.vpc.vpc_default_security_group_id] + ecs_private_subnet_ids = module.subnets.private_subnet_ids + + alb_security_group = "xxxxxxxx" + alb_target_group_alarms_enabled = true + alb_target_group_alarms_3xx_threshold = 25 + alb_target_group_alarms_4xx_threshold = 25 + alb_target_group_alarms_5xx_threshold = 25 + alb_target_group_alarms_response_time_threshold = 0.5 + alb_target_group_alarms_period = 300 + alb_target_group_alarms_evaluation_periods = 1 + + alb_arn_suffix = module.alb.alb_arn_suffix alb_ingress_healthcheck_path = "/" # NOTE: Cognito and OIDC authentication only supported on HTTPS endpoints; here we provide `https_listener_arn` from ALB - alb_ingress_authenticated_listener_arns = ["${module.alb.https_listener_arn}"] + alb_ingress_authenticated_listener_arns = module.alb.https_listener_arn alb_ingress_authenticated_listener_arns_count = 1 # Unauthenticated paths (with higher priority than the authenticated paths) alb_ingress_unauthenticated_paths = ["/events"] - alb_ingress_listener_unauthenticated_priority = "50" + alb_ingress_listener_unauthenticated_priority = 50 # Authenticated paths alb_ingress_authenticated_paths = ["/*"] - alb_ingress_listener_authenticated_priority = "100" + alb_ingress_listener_authenticated_priority = 100 authentication_type = "COGNITO" - authentication_cognito_user_pool_arn = "${var.cognito_user_pool_arn}" - authentication_cognito_user_pool_client_id = "${var.cognito_user_pool_client_id}" - authentication_cognito_user_pool_domain = "${var.cognito_user_pool_domain}" + authentication_cognito_user_pool_arn = var.cognito_user_pool_arn + authentication_cognito_user_pool_client_id = var.cognito_user_pool_client_id + authentication_cognito_user_pool_domain = var.cognito_user_pool_domain } diff --git a/examples/with_cognito_authentication/variables.tf b/examples/with_cognito_authentication/variables.tf index a4e7fe90..2c96aca5 100644 --- a/examples/with_cognito_authentication/variables.tf +++ b/examples/with_cognito_authentication/variables.tf @@ -1,67 +1,67 @@ variable "namespace" { - type = "string" + type = string description = "Namespace (e.g. `cp` or `cloudposse`)" default = "eg" } variable "stage" { - type = "string" + type = string description = "Stage (e.g. `prod`, `dev`, `staging`)" default = "testing" } variable "name" { - type = "string" + type = string description = "Application or solution name (e.g. `app`)" default = "ecs" } variable "delimiter" { - type = "string" + type = string default = "-" description = "Delimiter to be used between `namespace`, `stage`, `name` and `attributes`" } variable "attributes" { - type = "list" + type = list(string) default = [] description = "Additional attributes (e.g. `1`)" } variable "tags" { - type = "map" + type = map(string) default = {} description = "Additional tags (e.g. map(`BusinessUnit`,`XYZ`)" } variable "region" { - type = "string" + type = string description = "AWS Region" - default = "us-west-2" + default = "us-east-2" } variable "default_container_image" { - type = "string" + type = string description = "The default container image to use in container definition" default = "nginxdemos/hello:latest" } variable "certificate_arn" { - type = "string" + type = string description = "SSL certificate ARN for ALB HTTPS endpoints" } variable "cognito_user_pool_arn" { - type = "string" + type = string description = "Cognito User Pool ARN" } variable "cognito_user_pool_client_id" { - type = "string" + type = string description = "Cognito User Pool Client ID" } variable "cognito_user_pool_domain" { - type = "string" + type = string description = "Cognito User Pool Domain" } diff --git a/examples/with_cognito_authentication/versions.tf b/examples/with_cognito_authentication/versions.tf new file mode 100644 index 00000000..9840ed75 --- /dev/null +++ b/examples/with_cognito_authentication/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = "~> 0.12.0" + + required_providers { + aws = "~> 2.0" + template = "~> 2.0" + null = "~> 2.0" + local = "~> 1.3" + } +} diff --git a/examples/with_google_oidc_authentication/main.tf b/examples/with_google_oidc_authentication/main.tf index 804d58b4..17fa83ac 100644 --- a/examples/with_google_oidc_authentication/main.tf +++ b/examples/with_google_oidc_authentication/main.tf @@ -1,76 +1,84 @@ provider "aws" { - region = "${var.region}" + region = var.region } module "vpc" { - source = "git::https://github.com/cloudposse/terraform-aws-vpc.git?ref=tags/0.3.4" - namespace = "${var.namespace}" - stage = "${var.stage}" - name = "${var.name}" + source = "git::https://github.com/cloudposse/terraform-aws-vpc.git?ref=tags/0.8.1" + namespace = var.namespace + stage = var.stage + name = var.name cidr_block = "172.16.0.0/16" } -data "aws_availability_zones" "available" {} +data "aws_availability_zones" "available" { +} locals { - availability_zones = "${slice(data.aws_availability_zones.available.names, 0, 2)}" + availability_zones = slice(data.aws_availability_zones.available.names, 0, 2) } module "subnets" { - source = "git::https://github.com/cloudposse/terraform-aws-dynamic-subnets.git?ref=tags/0.3.6" - availability_zones = "${local.availability_zones}" - namespace = "${var.namespace}" - stage = "${var.stage}" - name = "${var.name}" - region = "${var.region}" - vpc_id = "${module.vpc.vpc_id}" - igw_id = "${module.vpc.igw_id}" - cidr_block = "${module.vpc.vpc_cidr_block}" - nat_gateway_enabled = "true" + source = "git::https://github.com/cloudposse/terraform-aws-dynamic-subnets.git?ref=tags/0.16.1" + availability_zones = local.availability_zones + namespace = var.namespace + stage = var.stage + name = var.name + region = var.region + vpc_id = module.vpc.vpc_id + igw_id = module.vpc.igw_id + cidr_block = module.vpc.vpc_cidr_block + nat_gateway_enabled = true + nat_instance_enabled = false } module "alb" { - source = "git::https://github.com/cloudposse/terraform-aws-alb.git?ref=tags/0.2.6" - name = "${var.name}" - namespace = "${var.namespace}" - stage = "${var.stage}" - attributes = ["${compact(concat(var.attributes, list("alb")))}"] - vpc_id = "${module.vpc.vpc_id}" + source = "git::https://github.com/cloudposse/terraform-aws-alb.git?ref=tags/0.7.0" + name = var.name + namespace = var.namespace + stage = var.stage + attributes = compact(concat(var.attributes, ["alb"])) + vpc_id = module.vpc.vpc_id ip_address_type = "ipv4" - subnet_ids = ["${module.subnets.public_subnet_ids}"] - security_group_ids = ["${module.vpc.vpc_default_security_group_id}"] - access_logs_region = "${var.region}" - https_enabled = "true" + subnet_ids = module.subnets.public_subnet_ids + security_group_ids = [module.vpc.vpc_default_security_group_id] + access_logs_region = var.region + https_enabled = true http_ingress_cidr_blocks = ["0.0.0.0/0"] https_ingress_cidr_blocks = ["0.0.0.0/0"] - certificate_arn = "${var.certificate_arn}" - health_check_interval = "60" + certificate_arn = var.certificate_arn + health_check_interval = 60 } -module "ecs_cluster_label" { - source = "git::https://github.com/cloudposse/terraform-terraform-label.git?ref=tags/0.2.1" - name = "${var.name}" - namespace = "${var.namespace}" - stage = "${var.stage}" - tags = "${var.tags}" - attributes = "${var.attributes}" - delimiter = "${var.delimiter}" +module "label" { + source = "git::https://github.com/cloudposse/terraform-null-label.git?ref=tags/0.16.0" + name = var.name + namespace = var.namespace + stage = var.stage + tags = var.tags + attributes = var.attributes + delimiter = var.delimiter } # ECS Cluster (needed even if using FARGATE launch type) resource "aws_ecs_cluster" "default" { - name = "${module.ecs_cluster_label.id}" + name = module.label.id +} + +resource "aws_cloudwatch_log_group" "app" { + name = module.label.id + tags = module.label.tags } module "web_app" { source = "../../" - namespace = "${var.namespace}" - stage = "${var.stage}" - name = "${var.name}" - attributes = ["${compact(concat(var.attributes, list("app")))}"] + namespace = var.namespace + stage = var.stage + name = var.name + attributes = compact(concat(var.attributes, ["app"])) + region = var.region launch_type = "FARGATE" - vpc_id = "${module.vpc.vpc_id}" + vpc_id = module.vpc.vpc_id environment = [ { @@ -79,71 +87,75 @@ module "web_app" { }, { name = "VPC_ID" - value = "${module.vpc.vpc_id}" - }, + value = module.vpc.vpc_id + } ] desired_count = 1 - container_image = "${var.default_container_image}" - container_cpu = "256" - container_memory = "512" - container_port = "80" + container_image = var.default_container_image + container_cpu = 256 + container_memory = 512 + container_port = 80 build_timeout = 5 - port_mappings = [{ - "containerPort" = 80 - "hostPort" = 80 - "protocol" = "tcp" - }] - - codepipeline_enabled = "false" - webhook_enabled = "false" - badge_enabled = "false" - ecs_alarms_enabled = "false" - autoscaling_enabled = "false" + log_configuration = { + logDriver = "awslogs" + options = { + "awslogs-region" = var.region + "awslogs-group" = aws_cloudwatch_log_group.app.name + "awslogs-stream-prefix" = var.name + } + secretOptions = null + } + + codepipeline_enabled = false + webhook_enabled = false + badge_enabled = false + ecs_alarms_enabled = false + autoscaling_enabled = false autoscaling_dimension = "cpu" autoscaling_min_capacity = 1 autoscaling_max_capacity = 2 - autoscaling_scale_up_adjustment = "1" - autoscaling_scale_up_cooldown = "60" - autoscaling_scale_down_adjustment = "-1" - autoscaling_scale_down_cooldown = "300" - - aws_logs_region = "${var.region}" - ecs_cluster_arn = "${aws_ecs_cluster.default.arn}" - ecs_cluster_name = "${aws_ecs_cluster.default.name}" - ecs_security_group_ids = ["${module.vpc.vpc_default_security_group_id}"] - ecs_private_subnet_ids = ["${module.subnets.private_subnet_ids}"] - - alb_target_group_alarms_enabled = "true" - alb_target_group_alarms_3xx_threshold = "25" - alb_target_group_alarms_4xx_threshold = "25" - alb_target_group_alarms_5xx_threshold = "25" - alb_target_group_alarms_response_time_threshold = "0.5" - alb_target_group_alarms_period = "300" - alb_target_group_alarms_evaluation_periods = "1" - - alb_arn_suffix = "${module.alb.alb_arn_suffix}" - alb_name = "${module.alb.alb_name}" + autoscaling_scale_up_adjustment = 1 + autoscaling_scale_up_cooldown = 60 + autoscaling_scale_down_adjustment = -1 + autoscaling_scale_down_cooldown = 300 + + aws_logs_region = var.region + ecs_cluster_arn = aws_ecs_cluster.default.arn + ecs_cluster_name = aws_ecs_cluster.default.name + ecs_security_group_ids = [module.vpc.vpc_default_security_group_id] + ecs_private_subnet_ids = module.subnets.private_subnet_ids + + alb_security_group = "xxxxxxxx" + alb_target_group_alarms_enabled = true + alb_target_group_alarms_3xx_threshold = 25 + alb_target_group_alarms_4xx_threshold = 25 + alb_target_group_alarms_5xx_threshold = 25 + alb_target_group_alarms_response_time_threshold = 0.5 + alb_target_group_alarms_period = 300 + alb_target_group_alarms_evaluation_periods = 1 + + alb_arn_suffix = module.alb.alb_arn_suffix alb_ingress_healthcheck_path = "/" # NOTE: Cognito and OIDC authentication only supported on HTTPS endpoints; here we provide `https_listener_arn` from ALB - alb_ingress_authenticated_listener_arns = ["${module.alb.https_listener_arn}"] + alb_ingress_authenticated_listener_arns = module.alb.https_listener_arn alb_ingress_authenticated_listener_arns_count = 1 # Unauthenticated paths (with higher priority than the authenticated paths) alb_ingress_unauthenticated_paths = ["/events"] - alb_ingress_listener_unauthenticated_priority = "50" + alb_ingress_listener_unauthenticated_priority = 50 # Authenticated paths alb_ingress_authenticated_paths = ["/*"] - alb_ingress_listener_authenticated_priority = "100" + alb_ingress_listener_authenticated_priority = 100 authentication_type = "OIDC" - authentication_oidc_client_id = "${var.google_oidc_client_id}" - authentication_oidc_client_secret = "${var.google_oidc_client_secret}" + authentication_oidc_client_id = var.google_oidc_client_id + authentication_oidc_client_secret = var.google_oidc_client_secret authentication_oidc_issuer = "https://accounts.google.com" authentication_oidc_authorization_endpoint = "https://accounts.google.com/o/oauth2/v2/auth" authentication_oidc_token_endpoint = "https://oauth2.googleapis.com/token" diff --git a/examples/with_google_oidc_authentication/variables.tf b/examples/with_google_oidc_authentication/variables.tf index 07bd28b3..a9f4ab3f 100644 --- a/examples/with_google_oidc_authentication/variables.tf +++ b/examples/with_google_oidc_authentication/variables.tf @@ -1,62 +1,62 @@ variable "namespace" { - type = "string" + type = string description = "Namespace (e.g. `cp` or `cloudposse`)" default = "eg" } variable "stage" { - type = "string" + type = string description = "Stage (e.g. `prod`, `dev`, `staging`)" default = "testing" } variable "name" { - type = "string" + type = string description = "Application or solution name (e.g. `app`)" default = "ecs" } variable "delimiter" { - type = "string" + type = string default = "-" description = "Delimiter to be used between `namespace`, `stage`, `name` and `attributes`" } variable "attributes" { - type = "list" + type = list(string) default = [] description = "Additional attributes (e.g. `1`)" } variable "tags" { - type = "map" + type = map(string) default = {} description = "Additional tags (e.g. map(`BusinessUnit`,`XYZ`)" } variable "region" { - type = "string" + type = string description = "AWS Region" - default = "us-west-2" + default = "us-east-2" } variable "default_container_image" { - type = "string" + type = string description = "The default container image to use in container definition" default = "nginxdemos/hello:latest" } variable "certificate_arn" { - type = "string" + type = string description = "SSL certificate ARN for ALB HTTPS endpoints" } variable "google_oidc_client_id" { - type = "string" + type = string description = "Google OIDC Client ID. Use this URL to create a Google OAuth 2.0 Client and obtain the Client ID and Client Secret: https://console.developers.google.com/apis/credentials" } variable "google_oidc_client_secret" { - type = "string" + type = string description = "Google OIDC Client Secret. Use this URL to create a Google OAuth 2.0 Client and obtain the Client ID and Client Secret: https://console.developers.google.com/apis/credentials" } diff --git a/examples/with_google_oidc_authentication/versions.tf b/examples/with_google_oidc_authentication/versions.tf new file mode 100644 index 00000000..9840ed75 --- /dev/null +++ b/examples/with_google_oidc_authentication/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = "~> 0.12.0" + + required_providers { + aws = "~> 2.0" + template = "~> 2.0" + null = "~> 2.0" + local = "~> 1.3" + } +} diff --git a/examples/without_authentication/main.tf b/examples/without_authentication/main.tf index 2176b9d3..4bfd3273 100644 --- a/examples/without_authentication/main.tf +++ b/examples/without_authentication/main.tf @@ -1,76 +1,84 @@ provider "aws" { - region = "${var.region}" + region = var.region } module "vpc" { - source = "git::https://github.com/cloudposse/terraform-aws-vpc.git?ref=tags/0.3.4" - namespace = "${var.namespace}" - stage = "${var.stage}" - name = "${var.name}" + source = "git::https://github.com/cloudposse/terraform-aws-vpc.git?ref=tags/0.8.1" + namespace = var.namespace + stage = var.stage + name = var.name cidr_block = "172.16.0.0/16" } -data "aws_availability_zones" "available" {} +data "aws_availability_zones" "available" { +} locals { - availability_zones = "${slice(data.aws_availability_zones.available.names, 0, 2)}" + availability_zones = slice(data.aws_availability_zones.available.names, 0, 2) } module "subnets" { - source = "git::https://github.com/cloudposse/terraform-aws-dynamic-subnets.git?ref=tags/0.3.6" - availability_zones = "${local.availability_zones}" - namespace = "${var.namespace}" - stage = "${var.stage}" - name = "${var.name}" - region = "${var.region}" - vpc_id = "${module.vpc.vpc_id}" - igw_id = "${module.vpc.igw_id}" - cidr_block = "${module.vpc.vpc_cidr_block}" - nat_gateway_enabled = "true" + source = "git::https://github.com/cloudposse/terraform-aws-dynamic-subnets.git?ref=tags/0.16.1" + availability_zones = local.availability_zones + namespace = var.namespace + stage = var.stage + name = var.name + region = var.region + vpc_id = module.vpc.vpc_id + igw_id = module.vpc.igw_id + cidr_block = module.vpc.vpc_cidr_block + nat_gateway_enabled = true + nat_instance_enabled = false } module "alb" { - source = "git::https://github.com/cloudposse/terraform-aws-alb.git?ref=tags/0.2.6" - name = "${var.name}" - namespace = "${var.namespace}" - stage = "${var.stage}" - attributes = ["${compact(concat(var.attributes, list("alb")))}"] - vpc_id = "${module.vpc.vpc_id}" + source = "git::https://github.com/cloudposse/terraform-aws-alb.git?ref=tags/0.7.0" + name = var.name + namespace = var.namespace + stage = var.stage + attributes = compact(concat(var.attributes, ["alb"])) + vpc_id = module.vpc.vpc_id ip_address_type = "ipv4" - subnet_ids = ["${module.subnets.public_subnet_ids}"] - security_group_ids = ["${module.vpc.vpc_default_security_group_id}"] - access_logs_region = "${var.region}" - https_enabled = "true" + subnet_ids = module.subnets.public_subnet_ids + security_group_ids = [module.vpc.vpc_default_security_group_id] + access_logs_region = var.region + https_enabled = true http_ingress_cidr_blocks = ["0.0.0.0/0"] https_ingress_cidr_blocks = ["0.0.0.0/0"] - certificate_arn = "${var.certificate_arn}" - health_check_interval = "60" + certificate_arn = var.certificate_arn + health_check_interval = 60 } -module "ecs_cluster_label" { - source = "git::https://github.com/cloudposse/terraform-terraform-label.git?ref=tags/0.2.1" - name = "${var.name}" - namespace = "${var.namespace}" - stage = "${var.stage}" - tags = "${var.tags}" - attributes = "${var.attributes}" - delimiter = "${var.delimiter}" +module "label" { + source = "git::https://github.com/cloudposse/terraform-null-label.git?ref=tags/0.16.0" + name = var.name + namespace = var.namespace + stage = var.stage + tags = var.tags + attributes = var.attributes + delimiter = var.delimiter } # ECS Cluster (needed even if using FARGATE launch type) resource "aws_ecs_cluster" "default" { - name = "${module.ecs_cluster_label.id}" + name = module.label.id +} + +resource "aws_cloudwatch_log_group" "app" { + name = module.label.id + tags = module.label.tags } module "web_app" { source = "../../" - namespace = "${var.namespace}" - stage = "${var.stage}" - name = "${var.name}" - attributes = ["${compact(concat(var.attributes, list("app")))}"] + namespace = var.namespace + stage = var.stage + name = var.name + attributes = compact(concat(var.attributes, ["app"])) + region = var.region launch_type = "FARGATE" - vpc_id = "${module.vpc.vpc_id}" + vpc_id = module.vpc.vpc_id environment = [ { @@ -79,61 +87,65 @@ module "web_app" { }, { name = "VPC_ID" - value = "${module.vpc.vpc_id}" - }, + value = module.vpc.vpc_id + } ] desired_count = 1 - container_image = "${var.default_container_image}" - container_cpu = "256" - container_memory = "512" - container_port = "80" + container_image = var.default_container_image + container_cpu = 256 + container_memory = 512 + container_port = 80 build_timeout = 5 - port_mappings = [{ - "containerPort" = 80 - "hostPort" = 80 - "protocol" = "tcp" - }] - - codepipeline_enabled = "false" - webhook_enabled = "false" - badge_enabled = "false" - ecs_alarms_enabled = "false" - autoscaling_enabled = "false" + log_configuration = { + logDriver = "awslogs" + options = { + "awslogs-region" = var.region + "awslogs-group" = aws_cloudwatch_log_group.app.name + "awslogs-stream-prefix" = var.name + } + secretOptions = null + } + + codepipeline_enabled = false + webhook_enabled = false + badge_enabled = false + ecs_alarms_enabled = false + autoscaling_enabled = false autoscaling_dimension = "cpu" autoscaling_min_capacity = 1 autoscaling_max_capacity = 2 - autoscaling_scale_up_adjustment = "1" - autoscaling_scale_up_cooldown = "60" - autoscaling_scale_down_adjustment = "-1" - autoscaling_scale_down_cooldown = "300" - - aws_logs_region = "${var.region}" - ecs_cluster_arn = "${aws_ecs_cluster.default.arn}" - ecs_cluster_name = "${aws_ecs_cluster.default.name}" - ecs_security_group_ids = ["${module.vpc.vpc_default_security_group_id}"] - ecs_private_subnet_ids = ["${module.subnets.private_subnet_ids}"] - - alb_target_group_alarms_enabled = "true" - alb_target_group_alarms_3xx_threshold = "25" - alb_target_group_alarms_4xx_threshold = "25" - alb_target_group_alarms_5xx_threshold = "25" - alb_target_group_alarms_response_time_threshold = "0.5" - alb_target_group_alarms_period = "300" - alb_target_group_alarms_evaluation_periods = "1" - - alb_arn_suffix = "${module.alb.alb_arn_suffix}" - alb_name = "${module.alb.alb_name}" + autoscaling_scale_up_adjustment = 1 + autoscaling_scale_up_cooldown = 60 + autoscaling_scale_down_adjustment = -1 + autoscaling_scale_down_cooldown = 300 + + aws_logs_region = var.region + ecs_cluster_arn = aws_ecs_cluster.default.arn + ecs_cluster_name = aws_ecs_cluster.default.name + ecs_security_group_ids = [module.vpc.vpc_default_security_group_id] + ecs_private_subnet_ids = module.subnets.private_subnet_ids + + alb_security_group = "xxxxxxxx" + alb_target_group_alarms_enabled = true + alb_target_group_alarms_3xx_threshold = 25 + alb_target_group_alarms_4xx_threshold = 25 + alb_target_group_alarms_5xx_threshold = 25 + alb_target_group_alarms_response_time_threshold = 0.5 + alb_target_group_alarms_period = 300 + alb_target_group_alarms_evaluation_periods = 1 + + alb_arn_suffix = module.alb.alb_arn_suffix alb_ingress_healthcheck_path = "/" # Without authentication, both HTTP and HTTPS endpoints are supported - alb_ingress_unauthenticated_listener_arns = ["${module.alb.listener_arns}"] + alb_ingress_unauthenticated_listener_arns = module.alb.listener_arns alb_ingress_unauthenticated_listener_arns_count = 2 # All paths are unauthenticated alb_ingress_unauthenticated_paths = ["/*"] - alb_ingress_listener_unauthenticated_priority = "100" + alb_ingress_listener_unauthenticated_priority = 100 } diff --git a/examples/without_authentication/variables.tf b/examples/without_authentication/variables.tf index 35b5f81c..1bbec5e7 100644 --- a/examples/without_authentication/variables.tf +++ b/examples/without_authentication/variables.tf @@ -1,52 +1,52 @@ variable "namespace" { - type = "string" + type = string description = "Namespace (e.g. `cp` or `cloudposse`)" default = "eg" } variable "stage" { - type = "string" + type = string description = "Stage (e.g. `prod`, `dev`, `staging`)" default = "testing" } variable "name" { - type = "string" + type = string description = "Application or solution name (e.g. `app`)" default = "ecs" } variable "delimiter" { - type = "string" + type = string default = "-" description = "Delimiter to be used between `namespace`, `stage`, `name` and `attributes`" } variable "attributes" { - type = "list" + type = list(string) default = [] description = "Additional attributes (e.g. `1`)" } variable "tags" { - type = "map" + type = map(string) default = {} description = "Additional tags (e.g. map(`BusinessUnit`,`XYZ`)" } variable "region" { - type = "string" + type = string description = "AWS Region" - default = "us-west-2" + default = "us-east-2" } variable "certificate_arn" { - type = "string" + type = string description = "SSL certificate ARN for ALB HTTPS endpoints" } variable "default_container_image" { - type = "string" + type = string description = "The default container image to use in container definition" default = "nginxdemos/hello:latest" } diff --git a/examples/without_authentication/versions.tf b/examples/without_authentication/versions.tf new file mode 100644 index 00000000..9840ed75 --- /dev/null +++ b/examples/without_authentication/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = "~> 0.12.0" + + required_providers { + aws = "~> 2.0" + template = "~> 2.0" + null = "~> 2.0" + local = "~> 1.3" + } +} diff --git a/main.tf b/main.tf index b68aecb6..6221c5fc 100644 --- a/main.tf +++ b/main.tf @@ -1,229 +1,261 @@ -# Pin the `aws` provider -# https://www.terraform.io/docs/configuration/providers.html -# Any non-beta version >= 2.12.0 and < 2.13.0, e.g. 2.12.X -provider "aws" { - version = "~> 2.12.0" -} - -terraform { - required_version = "~> 0.11.0" -} - module "default_label" { - source = "git::https://github.com/cloudposse/terraform-terraform-label.git?ref=tags/0.2.1" - name = "${var.name}" - namespace = "${var.namespace}" - stage = "${var.stage}" - attributes = "${var.attributes}" + source = "git::https://github.com/cloudposse/terraform-null-label.git?ref=tags/0.16.0" + name = var.name + namespace = var.namespace + stage = var.stage + delimiter = var.delimiter + attributes = var.attributes + tags = var.tags } module "ecr" { - enabled = "${var.codepipeline_enabled}" - source = "git::https://github.com/cloudposse/terraform-aws-ecr.git?ref=tags/0.5.0" - name = "${var.name}" - namespace = "${var.namespace}" - stage = "${var.stage}" - attributes = "${compact(concat(var.attributes, list("ecr")))}" + source = "git::https://github.com/cloudposse/terraform-aws-ecr.git?ref=tags/0.7.0" + enabled = var.codepipeline_enabled + name = var.name + namespace = var.namespace + stage = var.stage + attributes = compact(concat(var.attributes, ["ecr"])) } resource "aws_cloudwatch_log_group" "app" { - name = "${module.default_label.id}" - tags = "${module.default_label.tags}" + name = module.default_label.id + tags = module.default_label.tags } module "alb_ingress" { - source = "git::https://github.com/cloudposse/terraform-aws-alb-ingress.git?ref=tags/0.7.0" - name = "${var.name}" - namespace = "${var.namespace}" - stage = "${var.stage}" - attributes = "${var.attributes}" - vpc_id = "${var.vpc_id}" - port = "${var.container_port}" - health_check_path = "${var.alb_ingress_healthcheck_path}" - - authenticated_paths = ["${var.alb_ingress_authenticated_paths}"] - unauthenticated_paths = ["${var.alb_ingress_unauthenticated_paths}"] - authenticated_hosts = ["${var.alb_ingress_authenticated_hosts}"] - unauthenticated_hosts = ["${var.alb_ingress_unauthenticated_hosts}"] - - authenticated_priority = "${var.alb_ingress_listener_authenticated_priority}" - unauthenticated_priority = "${var.alb_ingress_listener_unauthenticated_priority}" - - unauthenticated_listener_arns = "${var.alb_ingress_unauthenticated_listener_arns}" - unauthenticated_listener_arns_count = "${var.alb_ingress_unauthenticated_listener_arns_count}" - authenticated_listener_arns = "${var.alb_ingress_authenticated_listener_arns}" - authenticated_listener_arns_count = "${var.alb_ingress_authenticated_listener_arns_count}" - - authentication_type = "${var.authentication_type}" - authentication_cognito_user_pool_arn = "${var.authentication_cognito_user_pool_arn}" - authentication_cognito_user_pool_client_id = "${var.authentication_cognito_user_pool_client_id}" - authentication_cognito_user_pool_domain = "${var.authentication_cognito_user_pool_domain}" - authentication_oidc_client_id = "${var.authentication_oidc_client_id}" - authentication_oidc_client_secret = "${var.authentication_oidc_client_secret}" - authentication_oidc_issuer = "${var.authentication_oidc_issuer}" - authentication_oidc_authorization_endpoint = "${var.authentication_oidc_authorization_endpoint}" - authentication_oidc_token_endpoint = "${var.authentication_oidc_token_endpoint}" - authentication_oidc_user_info_endpoint = "${var.authentication_oidc_user_info_endpoint}" + source = "git::https://github.com/cloudposse/terraform-aws-alb-ingress.git?ref=tags/0.9.0" + name = var.name + namespace = var.namespace + stage = var.stage + attributes = var.attributes + vpc_id = var.vpc_id + port = var.container_port + health_check_path = var.alb_ingress_healthcheck_path + default_target_group_enabled = true + + authenticated_paths = var.alb_ingress_authenticated_paths + unauthenticated_paths = var.alb_ingress_unauthenticated_paths + authenticated_hosts = var.alb_ingress_authenticated_hosts + unauthenticated_hosts = var.alb_ingress_unauthenticated_hosts + + authenticated_priority = var.alb_ingress_listener_authenticated_priority + unauthenticated_priority = var.alb_ingress_listener_unauthenticated_priority + + unauthenticated_listener_arns = var.alb_ingress_unauthenticated_listener_arns + unauthenticated_listener_arns_count = var.alb_ingress_unauthenticated_listener_arns_count + authenticated_listener_arns = var.alb_ingress_authenticated_listener_arns + authenticated_listener_arns_count = var.alb_ingress_authenticated_listener_arns_count + + authentication_type = var.authentication_type + authentication_cognito_user_pool_arn = var.authentication_cognito_user_pool_arn + authentication_cognito_user_pool_client_id = var.authentication_cognito_user_pool_client_id + authentication_cognito_user_pool_domain = var.authentication_cognito_user_pool_domain + authentication_oidc_client_id = var.authentication_oidc_client_id + authentication_oidc_client_secret = var.authentication_oidc_client_secret + authentication_oidc_issuer = var.authentication_oidc_issuer + authentication_oidc_authorization_endpoint = var.authentication_oidc_authorization_endpoint + authentication_oidc_token_endpoint = var.authentication_oidc_token_endpoint + authentication_oidc_user_info_endpoint = var.authentication_oidc_user_info_endpoint } module "container_definition" { - source = "git::https://github.com/cloudposse/terraform-aws-ecs-container-definition.git?ref=tags/0.9.1" - container_name = "${module.default_label.id}" - container_image = "${var.container_image}" - container_memory = "${var.container_memory}" - container_memory_reservation = "${var.container_memory_reservation}" - container_cpu = "${var.container_cpu}" - healthcheck = "${var.healthcheck}" - environment = "${var.environment}" - port_mappings = "${var.port_mappings}" - secrets = "${var.secrets}" - - log_options = { - "awslogs-region" = "${var.aws_logs_region}" - "awslogs-group" = "${aws_cloudwatch_log_group.app.name}" - "awslogs-stream-prefix" = "${var.name}" + source = "git::https://github.com/cloudposse/terraform-aws-ecs-container-definition.git?ref=tags/0.21.0" + container_name = module.default_label.id + container_image = var.container_image + container_memory = var.container_memory + container_memory_reservation = var.container_memory_reservation + container_cpu = var.container_cpu + healthcheck = var.healthcheck + environment = var.environment + port_mappings = var.port_mappings + secrets = var.secrets + + log_configuration = { + logDriver = var.log_driver + options = { + "awslogs-region" = var.aws_logs_region + "awslogs-group" = aws_cloudwatch_log_group.app.name + "awslogs-stream-prefix" = var.name + } + secretOptions = null } } module "ecs_alb_service_task" { - source = "git::https://github.com/cloudposse/terraform-aws-ecs-alb-service-task.git?ref=tags/0.14.0" - name = "${var.name}" - namespace = "${var.namespace}" - stage = "${var.stage}" - attributes = "${var.attributes}" - alb_target_group_arn = "${module.alb_ingress.target_group_arn}" - alb_security_group = "${var.alb_security_group}" - container_definition_json = "${module.container_definition.json}" - container_name = "${module.default_label.id}" - desired_count = "${var.desired_count}" - health_check_grace_period_seconds = "${var.health_check_grace_period_seconds}" - task_cpu = "${var.container_cpu}" - task_memory = "${var.container_memory}" - ecs_cluster_arn = "${var.ecs_cluster_arn}" - launch_type = "${var.launch_type}" - vpc_id = "${var.vpc_id}" - security_group_ids = ["${var.ecs_security_group_ids}"] - subnet_ids = ["${var.ecs_private_subnet_ids}"] - container_port = "${var.container_port}" - tags = "${var.tags}" + source = "git::https://github.com/cloudposse/terraform-aws-ecs-alb-service-task.git?ref=tags/0.17.0" + name = var.name + namespace = var.namespace + stage = var.stage + attributes = var.attributes + alb_security_group = var.alb_security_group + container_definition_json = module.container_definition.json + desired_count = var.desired_count + health_check_grace_period_seconds = var.health_check_grace_period_seconds + task_cpu = var.container_cpu + task_memory = var.container_memory + ecs_cluster_arn = var.ecs_cluster_arn + launch_type = var.launch_type + vpc_id = var.vpc_id + security_group_ids = var.ecs_security_group_ids + subnet_ids = var.ecs_private_subnet_ids + container_port = var.container_port + tags = var.tags + + ecs_load_balancers = [ + { + container_name = module.default_label.id + container_port = var.container_port + elb_name = null + target_group_arn = module.alb_ingress.target_group_arn + }] } module "ecs_codepipeline" { - enabled = "${var.codepipeline_enabled}" - source = "git::https://github.com/cloudposse/terraform-aws-ecs-codepipeline.git?ref=tags/0.9.0" - name = "${var.name}" - namespace = "${var.namespace}" - stage = "${var.stage}" - attributes = "${var.attributes}" - github_oauth_token = "${var.github_oauth_token}" - github_webhooks_token = "${var.github_webhooks_token}" - github_webhook_events = "${var.github_webhook_events}" - repo_owner = "${var.repo_owner}" - repo_name = "${var.repo_name}" - branch = "${var.branch}" - badge_enabled = "${var.badge_enabled}" - build_image = "${var.build_image}" - build_timeout = "${var.build_timeout}" - buildspec = "${var.buildspec}" - image_repo_name = "${module.ecr.repository_name}" - service_name = "${module.ecs_alb_service_task.service_name}" - ecs_cluster_name = "${var.ecs_cluster_name}" - privileged_mode = "true" - poll_source_changes = "${var.poll_source_changes}" - - webhook_enabled = "${var.webhook_enabled}" - webhook_target_action = "${var.webhook_target_action}" - webhook_authentication = "${var.webhook_authentication}" - webhook_filter_json_path = "${var.webhook_filter_json_path}" - webhook_filter_match_equals = "${var.webhook_filter_match_equals}" - - s3_bucket_force_destroy = "${var.codepipeline_s3_bucket_force_destroy}" - - environment_variables = [{ - "name" = "CONTAINER_NAME" - "value" = "${module.default_label.id}" - }] + enabled = var.codepipeline_enabled + source = "git::https://github.com/cloudposse/terraform-aws-ecs-codepipeline.git?ref=tags/0.10.0" + name = var.name + namespace = var.namespace + stage = var.stage + attributes = var.attributes + region = var.region + github_oauth_token = var.github_oauth_token + github_webhooks_token = var.github_webhooks_token + github_webhook_events = var.github_webhook_events + repo_owner = var.repo_owner + repo_name = var.repo_name + branch = var.branch + badge_enabled = var.badge_enabled + build_image = var.build_image + build_timeout = var.build_timeout + buildspec = var.buildspec + image_repo_name = module.ecr.repository_name + service_name = module.ecs_alb_service_task.service_name + ecs_cluster_name = var.ecs_cluster_name + privileged_mode = true + poll_source_changes = var.poll_source_changes + + webhook_enabled = var.webhook_enabled + webhook_target_action = var.webhook_target_action + webhook_authentication = var.webhook_authentication + webhook_filter_json_path = var.webhook_filter_json_path + webhook_filter_match_equals = var.webhook_filter_match_equals + + s3_bucket_force_destroy = var.codepipeline_s3_bucket_force_destroy + + environment_variables = [ + { + name = "CONTAINER_NAME" + value = module.default_label.id + } + ] } -module "autoscaling" { - enabled = "${var.autoscaling_enabled}" - source = "git::https://github.com/cloudposse/terraform-aws-ecs-cloudwatch-autoscaling.git?ref=tags/0.1.0" - name = "${var.name}" - namespace = "${var.namespace}" - stage = "${var.stage}" - attributes = "${var.attributes}" - service_name = "${module.ecs_alb_service_task.service_name}" - cluster_name = "${var.ecs_cluster_name}" - min_capacity = "${var.autoscaling_min_capacity}" - max_capacity = "${var.autoscaling_max_capacity}" - scale_down_adjustment = "${var.autoscaling_scale_down_adjustment}" - scale_down_cooldown = "${var.autoscaling_scale_down_cooldown}" - scale_up_adjustment = "${var.autoscaling_scale_up_adjustment}" - scale_up_cooldown = "${var.autoscaling_scale_up_cooldown}" +module "ecs_cloudwatch_autoscaling" { + enabled = var.autoscaling_enabled + source = "git::https://github.com/cloudposse/terraform-aws-ecs-cloudwatch-autoscaling.git?ref=tags/0.2.0" + name = var.name + namespace = var.namespace + stage = var.stage + attributes = var.attributes + service_name = module.ecs_alb_service_task.service_name + cluster_name = var.ecs_cluster_name + min_capacity = var.autoscaling_min_capacity + max_capacity = var.autoscaling_max_capacity + scale_down_adjustment = var.autoscaling_scale_down_adjustment + scale_down_cooldown = var.autoscaling_scale_down_cooldown + scale_up_adjustment = var.autoscaling_scale_up_adjustment + scale_up_cooldown = var.autoscaling_scale_up_cooldown } locals { - cpu_utilization_high_alarm_actions = "${var.autoscaling_enabled == "true" && var.autoscaling_dimension == "cpu" ? module.autoscaling.scale_up_policy_arn : ""}" - cpu_utilization_low_alarm_actions = "${var.autoscaling_enabled == "true" && var.autoscaling_dimension == "cpu" ? module.autoscaling.scale_down_policy_arn : ""}" - memory_utilization_high_alarm_actions = "${var.autoscaling_enabled == "true" && var.autoscaling_dimension == "memory" ? module.autoscaling.scale_up_policy_arn : ""}" - memory_utilization_low_alarm_actions = "${var.autoscaling_enabled == "true" && var.autoscaling_dimension == "memory" ? module.autoscaling.scale_down_policy_arn : ""}" + cpu_utilization_high_alarm_actions = var.autoscaling_enabled && var.autoscaling_dimension == "cpu" ? module.ecs_cloudwatch_autoscaling.scale_up_policy_arn : "" + cpu_utilization_low_alarm_actions = var.autoscaling_enabled && var.autoscaling_dimension == "cpu" ? module.ecs_cloudwatch_autoscaling.scale_down_policy_arn : "" + memory_utilization_high_alarm_actions = var.autoscaling_enabled && var.autoscaling_dimension == "memory" ? module.ecs_cloudwatch_autoscaling.scale_up_policy_arn : "" + memory_utilization_low_alarm_actions = var.autoscaling_enabled && var.autoscaling_dimension == "memory" ? module.ecs_cloudwatch_autoscaling.scale_down_policy_arn : "" } -module "ecs_alarms" { - source = "git::https://github.com/cloudposse/terraform-aws-ecs-cloudwatch-sns-alarms.git?ref=tags/0.4.0" - name = "${var.name}" - namespace = "${var.namespace}" - stage = "${var.stage}" - attributes = "${var.attributes}" - tags = "${var.tags}" - - enabled = "${var.ecs_alarms_enabled}" - cluster_name = "${var.ecs_cluster_name}" - service_name = "${module.ecs_alb_service_task.service_name}" - - cpu_utilization_high_threshold = "${var.ecs_alarms_cpu_utilization_high_threshold}" - cpu_utilization_high_evaluation_periods = "${var.ecs_alarms_cpu_utilization_high_evaluation_periods}" - cpu_utilization_high_period = "${var.ecs_alarms_cpu_utilization_high_period}" - cpu_utilization_high_alarm_actions = "${compact(concat(var.ecs_alarms_cpu_utilization_high_alarm_actions, list(local.cpu_utilization_high_alarm_actions)))}" - cpu_utilization_high_ok_actions = "${var.ecs_alarms_cpu_utilization_high_ok_actions}" - - cpu_utilization_low_threshold = "${var.ecs_alarms_cpu_utilization_low_threshold}" - cpu_utilization_low_evaluation_periods = "${var.ecs_alarms_cpu_utilization_low_evaluation_periods}" - cpu_utilization_low_period = "${var.ecs_alarms_cpu_utilization_low_period}" - cpu_utilization_low_alarm_actions = "${compact(concat(var.ecs_alarms_cpu_utilization_low_alarm_actions, list(local.cpu_utilization_low_alarm_actions)))}" - cpu_utilization_low_ok_actions = "${var.ecs_alarms_cpu_utilization_low_ok_actions}" - - memory_utilization_high_threshold = "${var.ecs_alarms_memory_utilization_high_threshold}" - memory_utilization_high_evaluation_periods = "${var.ecs_alarms_memory_utilization_high_evaluation_periods}" - memory_utilization_high_period = "${var.ecs_alarms_memory_utilization_high_period}" - memory_utilization_high_alarm_actions = "${compact(concat(var.ecs_alarms_memory_utilization_high_alarm_actions, list(local.memory_utilization_high_alarm_actions)))}" - memory_utilization_high_ok_actions = "${var.ecs_alarms_memory_utilization_high_ok_actions}" - - memory_utilization_low_threshold = "${var.ecs_alarms_memory_utilization_low_threshold}" - memory_utilization_low_evaluation_periods = "${var.ecs_alarms_memory_utilization_low_evaluation_periods}" - memory_utilization_low_period = "${var.ecs_alarms_memory_utilization_low_period}" - memory_utilization_low_alarm_actions = "${compact(concat(var.ecs_alarms_memory_utilization_low_alarm_actions, list(local.memory_utilization_low_alarm_actions)))}" - memory_utilization_low_ok_actions = "${var.ecs_alarms_memory_utilization_low_ok_actions}" +module "ecs_cloudwatch_sns_alarms" { + source = "git::https://github.com/cloudposse/terraform-aws-ecs-cloudwatch-sns-alarms.git?ref=tags/0.5.0" + enabled = var.ecs_alarms_enabled + + name = var.name + namespace = var.namespace + stage = var.stage + attributes = var.attributes + tags = var.tags + + cluster_name = var.ecs_cluster_name + service_name = module.ecs_alb_service_task.service_name + + cpu_utilization_high_threshold = var.ecs_alarms_cpu_utilization_high_threshold + cpu_utilization_high_evaluation_periods = var.ecs_alarms_cpu_utilization_high_evaluation_periods + cpu_utilization_high_period = var.ecs_alarms_cpu_utilization_high_period + + cpu_utilization_high_alarm_actions = compact( + concat( + var.ecs_alarms_cpu_utilization_high_alarm_actions, + [local.cpu_utilization_high_alarm_actions], + ) + ) + + cpu_utilization_high_ok_actions = var.ecs_alarms_cpu_utilization_high_ok_actions + + cpu_utilization_low_threshold = var.ecs_alarms_cpu_utilization_low_threshold + cpu_utilization_low_evaluation_periods = var.ecs_alarms_cpu_utilization_low_evaluation_periods + cpu_utilization_low_period = var.ecs_alarms_cpu_utilization_low_period + + cpu_utilization_low_alarm_actions = compact( + concat( + var.ecs_alarms_cpu_utilization_low_alarm_actions, + [local.cpu_utilization_low_alarm_actions], + ) + ) + + cpu_utilization_low_ok_actions = var.ecs_alarms_cpu_utilization_low_ok_actions + + memory_utilization_high_threshold = var.ecs_alarms_memory_utilization_high_threshold + memory_utilization_high_evaluation_periods = var.ecs_alarms_memory_utilization_high_evaluation_periods + memory_utilization_high_period = var.ecs_alarms_memory_utilization_high_period + + memory_utilization_high_alarm_actions = compact( + concat( + var.ecs_alarms_memory_utilization_high_alarm_actions, + [local.memory_utilization_high_alarm_actions], + ) + ) + + memory_utilization_high_ok_actions = var.ecs_alarms_memory_utilization_high_ok_actions + + memory_utilization_low_threshold = var.ecs_alarms_memory_utilization_low_threshold + memory_utilization_low_evaluation_periods = var.ecs_alarms_memory_utilization_low_evaluation_periods + memory_utilization_low_period = var.ecs_alarms_memory_utilization_low_period + + memory_utilization_low_alarm_actions = compact( + concat( + var.ecs_alarms_memory_utilization_low_alarm_actions, + [local.memory_utilization_low_alarm_actions], + ) + ) + + memory_utilization_low_ok_actions = var.ecs_alarms_memory_utilization_low_ok_actions } -module "alb_target_group_alarms" { - enabled = "${var.alb_target_group_alarms_enabled}" - source = "git::https://github.com/cloudposse/terraform-aws-alb-target-group-cloudwatch-sns-alarms.git?ref=tags/0.5.0" - name = "${var.name}" - namespace = "${var.namespace}" - stage = "${var.stage}" - attributes = "${var.attributes}" - alarm_actions = ["${var.alb_target_group_alarms_alarm_actions}"] - ok_actions = ["${var.alb_target_group_alarms_ok_actions}"] - insufficient_data_actions = ["${var.alb_target_group_alarms_insufficient_data_actions}"] - alb_name = "${var.alb_name}" - alb_arn_suffix = "${var.alb_arn_suffix}" - target_group_name = "${module.alb_ingress.target_group_name}" - target_group_arn_suffix = "${module.alb_ingress.target_group_arn_suffix}" - target_3xx_count_threshold = "${var.alb_target_group_alarms_3xx_threshold}" - target_4xx_count_threshold = "${var.alb_target_group_alarms_4xx_threshold}" - target_5xx_count_threshold = "${var.alb_target_group_alarms_5xx_threshold}" - target_response_time_threshold = "${var.alb_target_group_alarms_response_time_threshold}" - period = "${var.alb_target_group_alarms_period}" - evaluation_periods = "${var.alb_target_group_alarms_evaluation_periods}" +module "alb_target_group_cloudwatch_sns_alarms" { + source = "git::https://github.com/cloudposse/terraform-aws-alb-target-group-cloudwatch-sns-alarms.git?ref=tags/0.7.0" + enabled = var.alb_target_group_alarms_enabled + name = var.name + namespace = var.namespace + stage = var.stage + attributes = var.attributes + alarm_actions = var.alb_target_group_alarms_alarm_actions + ok_actions = var.alb_target_group_alarms_ok_actions + insufficient_data_actions = var.alb_target_group_alarms_insufficient_data_actions + alb_arn_suffix = var.alb_arn_suffix + target_group_arn_suffix = module.alb_ingress.target_group_arn_suffix + target_3xx_count_threshold = var.alb_target_group_alarms_3xx_threshold + target_4xx_count_threshold = var.alb_target_group_alarms_4xx_threshold + target_5xx_count_threshold = var.alb_target_group_alarms_5xx_threshold + target_response_time_threshold = var.alb_target_group_alarms_response_time_threshold + period = var.alb_target_group_alarms_period + evaluation_periods = var.alb_target_group_alarms_evaluation_periods } diff --git a/outputs.tf b/outputs.tf index d1aa2e1f..846b29db 100644 --- a/outputs.tf +++ b/outputs.tf @@ -1,45 +1,255 @@ -output "scale_down_policy_arn" { - description = "Autoscaling scale up policy ARN" - value = "${module.autoscaling.scale_down_policy_arn}" +output "ecr_registry_id" { + value = module.ecr.registry_id + description = "Registry ID" } -output "scale_up_policy_arn" { - description = "Autoscaling scale up policy ARN" - value = "${module.autoscaling.scale_up_policy_arn}" +output "ecr_registry_url" { + value = module.ecr.registry_url + description = "Registry URL" } -output "service_name" { - description = "ECS Service Name" - value = "${module.ecs_alb_service_task.service_name}" +output "ecr_repository_name" { + value = module.ecr.repository_name + description = "Registry name" } -output "task_role_name" { +output "alb_ingress_target_group_name" { + description = "ALB Target Group name" + value = module.alb_ingress.target_group_name +} + +output "alb_ingress_target_group_arn" { + description = "ALB Target Group ARN" + value = module.alb_ingress.target_group_arn +} + +output "alb_ingress_target_group_arn_suffix" { + description = "ALB Target Group ARN suffix" + value = module.alb_ingress.target_group_arn_suffix +} + +output "container_definition_json" { + description = "JSON encoded list of container definitions for use with other terraform resources such as aws_ecs_task_definition" + value = module.container_definition.json +} + +output "container_definition_json_map" { + description = "JSON encoded container definitions for use with other terraform resources such as aws_ecs_task_definition" + value = module.container_definition.json_map +} + +output "ecs_exec_role_policy_id" { + description = "The ECS service role policy ID, in the form of `role_name:role_policy_name`" + value = module.ecs_alb_service_task.ecs_exec_role_policy_id +} + +output "ecs_exec_role_policy_name" { + description = "ECS service role name" + value = module.ecs_alb_service_task.ecs_exec_role_policy_name +} + +output "ecs_service_name" { + description = "ECS Service name" + value = module.ecs_alb_service_task.service_name +} + +output "ecs_service_role_arn" { + description = "ECS Service role ARN" + value = module.ecs_alb_service_task.service_role_arn +} + +output "ecs_task_exec_role_name" { description = "ECS Task role name" - value = "${module.ecs_alb_service_task.task_role_name}" + value = module.ecs_alb_service_task.task_exec_role_name +} + +output "ecs_task_exec_role_arn" { + description = "ECS Task exec role ARN" + value = module.ecs_alb_service_task.task_exec_role_arn } -output "task_role_arn" { +output "ecs_task_role_name" { + description = "ECS Task role name" + value = module.ecs_alb_service_task.task_role_name +} + +output "ecs_task_role_arn" { description = "ECS Task role ARN" - value = "${module.ecs_alb_service_task.task_role_arn}" + value = module.ecs_alb_service_task.task_role_arn +} + +output "ecs_task_role_id" { + description = "ECS Task role id" + value = module.ecs_alb_service_task.task_role_id +} + +output "ecs_service_security_group_id" { + description = "Security Group ID of the ECS task" + value = module.ecs_alb_service_task.service_security_group_id +} + +output "ecs_task_definition_family" { + description = "ECS task definition family" + value = module.ecs_alb_service_task.task_definition_family +} + +output "ecs_task_definition_revision" { + description = "ECS task definition revision" + value = module.ecs_alb_service_task.task_definition_revision +} + +output "codebuild_project_name" { + description = "CodeBuild project name" + value = module.ecs_codepipeline.codebuild_project_name +} + +output "codebuild_project_id" { + description = "CodeBuild project ID" + value = module.ecs_codepipeline.codebuild_project_id +} + +output "codebuild_role_id" { + description = "CodeBuild IAM Role ID" + value = module.ecs_codepipeline.codebuild_role_id +} + +output "codebuild_role_arn" { + description = "CodeBuild IAM Role ARN" + value = module.ecs_codepipeline.codebuild_role_arn +} + +output "codebuild_cache_bucket_name" { + description = "CodeBuild cache S3 bucket name" + value = module.ecs_codepipeline.codebuild_cache_bucket_name +} + +output "codebuild_cache_bucket_arn" { + description = "CodeBuild cache S3 bucket ARN" + value = module.ecs_codepipeline.codebuild_cache_bucket_arn } -output "service_security_group_id" { - description = "Security Group id of the ECS task" - value = "${module.ecs_alb_service_task.service_security_group_id}" +output "codebuild_badge_url" { + description = "The URL of the build badge when badge_enabled is enabled" + value = module.ecs_codepipeline.codebuild_badge_url } -output "badge_url" { - description = "The URL of the build badge when `badge_enabled` is enabled" - value = "${module.ecs_codepipeline.badge_url}" +output "codepipeline_id" { + description = "CodePipeline ID" + value = module.ecs_codepipeline.codepipeline_id } -output "webhook_id" { - description = "The CodePipeline webhook's ARN." - value = "${module.ecs_codepipeline.webhook_id}" +output "codepipeline_arn" { + description = "CodePipeline ARN" + value = module.ecs_codepipeline.codepipeline_arn } -output "webhook_url" { - description = "The CodePipeline webhook's URL. POST events to this endpoint to trigger the target." - value = "${module.ecs_codepipeline.webhook_url}" +output "codepipeline_webhook_id" { + description = "The CodePipeline webhook's ID" + value = module.ecs_codepipeline.webhook_id +} + +output "codepipeline_webhook_url" { + description = "The CodePipeline webhook's URL. POST events to this endpoint to trigger the target" + value = module.ecs_codepipeline.webhook_url sensitive = true } + +output "ecs_cloudwatch_autoscaling_scale_up_policy_arn" { + description = "ARN of the scale up policy" + value = module.ecs_cloudwatch_autoscaling.scale_up_policy_arn +} + +output "ecs_cloudwatch_autoscaling_scale_down_policy_arn" { + description = "ARN of the scale down policy" + value = module.ecs_cloudwatch_autoscaling.scale_down_policy_arn +} + +output "ecs_alarms_cpu_utilization_high_cloudwatch_metric_alarm_id" { + value = module.ecs_cloudwatch_sns_alarms.cpu_utilization_high_cloudwatch_metric_alarm_id + description = "ECS CPU utilization high CloudWatch metric alarm ID" +} + +output "ecs_alarms_cpu_utilization_high_cloudwatch_metric_alarm_arn" { + value = module.ecs_cloudwatch_sns_alarms.cpu_utilization_high_cloudwatch_metric_alarm_arn + description = "ECS CPU utilization high CloudWatch metric alarm ARN" +} + +output "ecs_alarms_cpu_utilization_low_cloudwatch_metric_alarm_id" { + value = module.ecs_cloudwatch_sns_alarms.cpu_utilization_low_cloudwatch_metric_alarm_id + description = "ECS CPU utilization low CloudWatch metric alarm ID" +} + +output "ecs_alarms_cpu_utilization_low_cloudwatch_metric_alarm_arn" { + value = module.ecs_cloudwatch_sns_alarms.cpu_utilization_low_cloudwatch_metric_alarm_arn + description = "ECS CPU utilization low CloudWatch metric alarm ARN" +} + +output "ecs_alarms_memory_utilization_high_cloudwatch_metric_alarm_id" { + value = module.ecs_cloudwatch_sns_alarms.memory_utilization_high_cloudwatch_metric_alarm_id + description = "ECS Memory utilization high CloudWatch metric alarm ID" +} + +output "ecs_alarms_memory_utilization_high_cloudwatch_metric_alarm_arn" { + value = module.ecs_cloudwatch_sns_alarms.memory_utilization_high_cloudwatch_metric_alarm_arn + description = "ECS Memory utilization high CloudWatch metric alarm ARN" +} + +output "ecs_alarms_memory_utilization_low_cloudwatch_metric_alarm_id" { + value = module.ecs_cloudwatch_sns_alarms.memory_utilization_low_cloudwatch_metric_alarm_id + description = "ECS Memory utilization low CloudWatch metric alarm ID" +} + +output "ecs_alarms_memory_utilization_low_cloudwatch_metric_alarm_arn" { + value = module.ecs_cloudwatch_sns_alarms.memory_utilization_low_cloudwatch_metric_alarm_arn + description = "ECS Memory utilization low CloudWatch metric alarm ARN" +} + +output "httpcode_target_3xx_count_cloudwatch_metric_alarm_id" { + value = module.alb_target_group_cloudwatch_sns_alarms.httpcode_target_3xx_count_cloudwatch_metric_alarm_id + description = "ALB Target Group 3xx count CloudWatch metric alarm ID" +} + +output "httpcode_target_3xx_count_cloudwatch_metric_alarm_arn" { + value = module.alb_target_group_cloudwatch_sns_alarms.httpcode_target_3xx_count_cloudwatch_metric_alarm_arn + description = "ALB Target Group 3xx count CloudWatch metric alarm ARN" +} + +output "httpcode_target_4xx_count_cloudwatch_metric_alarm_id" { + value = module.alb_target_group_cloudwatch_sns_alarms.httpcode_target_4xx_count_cloudwatch_metric_alarm_id + description = "ALB Target Group 4xx count CloudWatch metric alarm ID" +} + +output "httpcode_target_4xx_count_cloudwatch_metric_alarm_arn" { + value = module.alb_target_group_cloudwatch_sns_alarms.httpcode_target_4xx_count_cloudwatch_metric_alarm_arn + description = "ALB Target Group 4xx count CloudWatch metric alarm ARN" +} + +output "httpcode_target_5xx_count_cloudwatch_metric_alarm_id" { + value = module.alb_target_group_cloudwatch_sns_alarms.httpcode_target_5xx_count_cloudwatch_metric_alarm_id + description = "ALB Target Group 5xx count CloudWatch metric alarm ID" +} + +output "httpcode_target_5xx_count_cloudwatch_metric_alarm_arn" { + value = module.alb_target_group_cloudwatch_sns_alarms.httpcode_target_5xx_count_cloudwatch_metric_alarm_arn + description = "ALB Target Group 5xx count CloudWatch metric alarm ARN" +} + +output "httpcode_elb_5xx_count_cloudwatch_metric_alarm_id" { + value = module.alb_target_group_cloudwatch_sns_alarms.httpcode_elb_5xx_count_cloudwatch_metric_alarm_id + description = "ALB 5xx count CloudWatch metric alarm ID" +} + +output "httpcode_elb_5xx_count_cloudwatch_metric_alarm_arn" { + value = module.alb_target_group_cloudwatch_sns_alarms.httpcode_elb_5xx_count_cloudwatch_metric_alarm_arn + description = "ALB 5xx count CloudWatch metric alarm ARN" +} + +output "target_response_time_average_cloudwatch_metric_alarm_id" { + value = module.alb_target_group_cloudwatch_sns_alarms.target_response_time_average_cloudwatch_metric_alarm_id + description = "ALB Target Group response time average CloudWatch metric alarm ID" +} + +output "target_response_time_average_cloudwatch_metric_alarm_arn" { + value = module.alb_target_group_cloudwatch_sns_alarms.target_response_time_average_cloudwatch_metric_alarm_arn + description = "ALB Target Group response time average CloudWatch metric alarm ARN" +} diff --git a/test/.gitignore b/test/.gitignore new file mode 100644 index 00000000..442804a2 --- /dev/null +++ b/test/.gitignore @@ -0,0 +1 @@ +.test-harness diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 00000000..17b2fe74 --- /dev/null +++ b/test/Makefile @@ -0,0 +1,43 @@ +TEST_HARNESS ?= https://github.com/cloudposse/test-harness.git +TEST_HARNESS_BRANCH ?= master +TEST_HARNESS_PATH = $(realpath .test-harness) +BATS_ARGS ?= --tap +BATS_LOG ?= test.log + +# Define a macro to run the tests +define RUN_TESTS +@echo "Running tests in $(1)" +@cd $(1) && bats $(BATS_ARGS) $(addsuffix .bats,$(addprefix $(TEST_HARNESS_PATH)/test/terraform/,$(TESTS))) +endef + +default: all + +-include Makefile.* + +## Provision the test-harnesss +.test-harness: + [ -d $@ ] || git clone --depth=1 -b $(TEST_HARNESS_BRANCH) $(TEST_HARNESS) $@ + +## Initialize the tests +init: .test-harness + +## Install all dependencies (OS specific) +deps:: + @exit 0 + +## Clean up the test harness +clean: + [ "$(TEST_HARNESS_PATH)" == "/" ] || rm -rf $(TEST_HARNESS_PATH) + +## Run all tests +all: module examples/complete + +## Run basic sanity checks against the module itself +module: export TESTS ?= installed lint get-modules module-pinning get-plugins provider-pinning validate terraform-docs input-descriptions output-descriptions +module: deps + $(call RUN_TESTS, ../) + +## Run tests against example +examples/complete: export TESTS ?= installed lint get-modules get-plugins validate +examples/complete: deps + $(call RUN_TESTS, ../$@) diff --git a/test/Makefile.alpine b/test/Makefile.alpine new file mode 100644 index 00000000..7925b186 --- /dev/null +++ b/test/Makefile.alpine @@ -0,0 +1,5 @@ +ifneq (,$(wildcard /sbin/apk)) +## Install all dependencies for alpine +deps:: init + @apk add --update terraform-docs@cloudposse json2hcl@cloudposse +endif diff --git a/test/src/.gitignore b/test/src/.gitignore new file mode 100644 index 00000000..31b0219e --- /dev/null +++ b/test/src/.gitignore @@ -0,0 +1,2 @@ +.gopath +vendor/ diff --git a/test/src/Gopkg.lock b/test/src/Gopkg.lock new file mode 100644 index 00000000..87bb6bd6 --- /dev/null +++ b/test/src/Gopkg.lock @@ -0,0 +1,92 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[[projects]] + digest = "1:ffe9824d294da03b391f44e1ae8281281b4afc1bdaa9588c9097785e3af10cec" + name = "github.com/davecgh/go-spew" + packages = ["spew"] + pruneopts = "UT" + revision = "8991bc29aa16c548c550c7ff78260e27b9ab7c73" + version = "v1.1.1" + +[[projects]] + digest = "1:75d6042fc66aebc974cc49b0c6c7cc3b9adb5f8130fbfa0dbec0820d990afa25" + name = "github.com/gruntwork-io/terratest" + packages = [ + "modules/collections", + "modules/customerrors", + "modules/files", + "modules/logger", + "modules/retry", + "modules/shell", + "modules/ssh", + "modules/terraform", + ] + pruneopts = "UT" + revision = "892abb2c35878d0808101bbfe6559e931dc2d354" + version = "v0.16.0" + +[[projects]] + digest = "1:0028cb19b2e4c3112225cd871870f2d9cf49b9b4276531f03438a88e94be86fe" + name = "github.com/pmezard/go-difflib" + packages = ["difflib"] + pruneopts = "UT" + revision = "792786c7400a136282c1664665ae0a8db921c6c2" + version = "v1.0.0" + +[[projects]] + digest = "1:5da8ce674952566deae4dbc23d07c85caafc6cfa815b0b3e03e41979cedb8750" + name = "github.com/stretchr/testify" + packages = [ + "assert", + "require", + ] + pruneopts = "UT" + revision = "ffdc059bfe9ce6a4e144ba849dbedead332c6053" + version = "v1.3.0" + +[[projects]] + branch = "master" + digest = "1:831470c2758c8b733941144f2803a0ccad0632c5a767415b777ebd296b5f463e" + name = "golang.org/x/crypto" + packages = [ + "curve25519", + "ed25519", + "ed25519/internal/edwards25519", + "internal/chacha20", + "internal/subtle", + "poly1305", + "ssh", + "ssh/agent", + ] + pruneopts = "UT" + revision = "22d7a77e9e5f409e934ed268692e56707cd169e5" + +[[projects]] + branch = "master" + digest = "1:76ee51c3f468493aff39dbacc401e8831fbb765104cbf613b89bef01cf4bad70" + name = "golang.org/x/net" + packages = ["context"] + pruneopts = "UT" + revision = "f3200d17e092c607f615320ecaad13d87ad9a2b3" + +[[projects]] + branch = "master" + digest = "1:181f3fd33e620b958b5ab77da177cf775cdcccd7db82963607875fbd09ae995e" + name = "golang.org/x/sys" + packages = [ + "cpu", + "unix", + ] + pruneopts = "UT" + revision = "9cd6430ef91e39e1a0ec0470cf1321a33ef1b887" + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + input-imports = [ + "github.com/gruntwork-io/terratest/modules/terraform", + "github.com/stretchr/testify/assert", + ] + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/test/src/Gopkg.toml b/test/src/Gopkg.toml new file mode 100644 index 00000000..995bac57 --- /dev/null +++ b/test/src/Gopkg.toml @@ -0,0 +1,7 @@ +[[constraint]] + name = "github.com/stretchr/testify" + version = "1.2.2" + +[prune] + go-tests = true + unused-packages = true diff --git a/test/src/Makefile b/test/src/Makefile new file mode 100644 index 00000000..abd81cf5 --- /dev/null +++ b/test/src/Makefile @@ -0,0 +1,50 @@ +PACKAGE = terraform-aws-ecs-web-app +GOEXE ?= /usr/bin/go +GOPATH = $(CURDIR)/.gopath +GOBIN = $(GOPATH)/bin +BASE = $(GOPATH)/src/$(PACKAGE) +PATH := $(PATH):$(GOBIN) + +export TF_DATA_DIR ?= $(CURDIR)/.terraform +export TF_CLI_ARGS_init ?= -get-plugins=true +export GOPATH + +.PHONY: all +## Default target +all: test + +ifneq (,$(wildcard /sbin/apk)) +## Install go, if not installed +$(GOEXE): + apk add --update go +endif + +ifeq ($(shell uname -s),Linux) +## Install all `dep`, if not installed +$(GOBIN)/dep: + @mkdir -p $(GOBIN) + @curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh +endif + +## Prepare the GOPATH +$(BASE): $(GOEXE) + @mkdir -p $(dir $@) + @ln -sf $(CURDIR) $@ + +## Download vendor dependencies to vendor/ +$(BASE)/vendor: $(BASE) $(GOBIN)/dep + cd $(BASE) && dep ensure + +.PHONY : init +## Initialize tests +init: $(BASE)/vendor + +.PHONY : test +## Run tests +test: init + cd $(BASE) && go test -v -timeout 30m -run TestExamplesComplete + +.PHONY : clean +## Clean up files +clean: + rm -rf .gopath/ vendor/ $(TF_DATA_DIR) diff --git a/test/src/examples_complete_test.go b/test/src/examples_complete_test.go new file mode 100644 index 00000000..20f8aca8 --- /dev/null +++ b/test/src/examples_complete_test.go @@ -0,0 +1,184 @@ +package test + +import ( + "encoding/json" + "testing" + + "github.com/gruntwork-io/terratest/modules/terraform" + "github.com/stretchr/testify/assert" +) + +// Test the Terraform module in examples/complete using Terratest. +func TestExamplesComplete(t *testing.T) { + t.Parallel() + + // We need to create the ALB first because terraform does not wwait for it to be in the ready state before creating ECS target group + terraformOptions := &terraform.Options{ + // The path to where our Terraform code is located + TerraformDir: "../../examples/complete", + Upgrade: true, + // Variables to pass to our Terraform code using -var-file options + VarFiles: []string{"fixtures.us-east-2.tfvars"}, + Targets: []string{"module.label", "module.vpc", "module.subnets", "module.alb"}, + } + + // At the end of the test, run `terraform destroy` to clean up any resources that were created + defer terraform.Destroy(t, terraformOptions) + + // This will run `terraform init` and `terraform apply` and fail the test if there are any errors + terraform.InitAndApply(t, terraformOptions) + + terraformOptions.Targets = nil + + // This will run `terraform init` and `terraform apply` and fail the test if there are any errors + terraform.Apply(t, terraformOptions) + + // Run `terraform output` to get the value of an output variable + vpcCidr := terraform.Output(t, terraformOptions, "vpc_cidr") + // Verify we're getting back the outputs we expect + assert.Equal(t, "172.16.0.0/16", vpcCidr) + + // Run `terraform output` to get the value of an output variable + privateSubnetCidrs := terraform.OutputList(t, terraformOptions, "private_subnet_cidrs") + // Verify we're getting back the outputs we expect + assert.Equal(t, []string{"172.16.0.0/19", "172.16.32.0/19"}, privateSubnetCidrs) + + // Run `terraform output` to get the value of an output variable + publicSubnetCidrs := terraform.OutputList(t, terraformOptions, "public_subnet_cidrs") + // Verify we're getting back the outputs we expect + assert.Equal(t, []string{"172.16.96.0/19", "172.16.128.0/19"}, publicSubnetCidrs) + + // Run `terraform output` to get the value of an output variable + albName := terraform.Output(t, terraformOptions, "alb_name") + // Verify we're getting back the outputs we expect + assert.Equal(t, "eg-test-ecs-web-app", albName) + + // Run `terraform output` to get the value of an output variable + albHttpListenerArn := terraform.Output(t, terraformOptions, "alb_http_listener_arn") + // Verify we're getting back the outputs we expect + assert.Contains(t, albHttpListenerArn, "listener/app/eg-test-ecs-web-app") + + // Run `terraform output` to get the value of an output variable + albIngressTargetGroupName := terraform.Output(t, terraformOptions, "alb_ingress_target_group_name") + // Verify we're getting back the outputs we expect + assert.Equal(t, "eg-test-ecs-web-app", albIngressTargetGroupName) + + // Run `terraform output` to get the value of an output variable + albAccessLogsBucketId := terraform.Output(t, terraformOptions, "alb_access_logs_bucket_id") + // Verify we're getting back the outputs we expect + assert.Equal(t, "eg-test-ecs-web-app-alb-access-logs", albAccessLogsBucketId) + + // Run `terraform output` to get the value of an output variable + containerDefinitionJsonMap := terraform.OutputRequired(t, terraformOptions, "container_definition_json_map") + // Verify we're getting back the outputs we expect + var jsonObject map[string]interface{} + err := json.Unmarshal([]byte(containerDefinitionJsonMap), &jsonObject) + assert.NoError(t, err) + assert.Equal(t, "eg-test-ecs-web-app", jsonObject["name"]) + assert.Equal(t, "cloudposse/default-backend", jsonObject["image"]) + assert.Equal(t, 512, int((jsonObject["memory"]).(float64))) + assert.Equal(t, 128, int((jsonObject["memoryReservation"]).(float64))) + assert.Equal(t, 256, int((jsonObject["cpu"]).(float64))) + assert.Equal(t, true, jsonObject["essential"]) + assert.Equal(t, false, jsonObject["readonlyRootFilesystem"]) + + // Run `terraform output` to get the value of an output variable + codebuildCacheBucketName := terraform.Output(t, terraformOptions, "codebuild_cache_bucket_name") + // Verify we're getting back the outputs we expect + assert.Contains(t, codebuildCacheBucketName, "eg-test-ecs-web-app-build") + + // Run `terraform output` to get the value of an output variable + codebuildProjectName := terraform.Output(t, terraformOptions, "codebuild_project_name") + // Verify we're getting back the outputs we expect + assert.Equal(t, "eg-test-ecs-web-app-build", codebuildProjectName) + + // Run `terraform output` to get the value of an output variable + codebuildRoleId := terraform.Output(t, terraformOptions, "codebuild_role_id") + // Verify we're getting back the outputs we expect + assert.Equal(t, "eg-test-ecs-web-app-build", codebuildRoleId) + + // Run `terraform output` to get the value of an output variable + codepipelineId := terraform.Output(t, terraformOptions, "codepipeline_id") + // Verify we're getting back the outputs we expect + assert.Equal(t, "eg-test-ecs-web-app-codepipeline", codepipelineId) + + // Run `terraform output` to get the value of an output variable + ecrRepositoryName := terraform.Output(t, terraformOptions, "ecr_repository_name") + // Verify we're getting back the outputs we expect + assert.Equal(t, "eg-test-ecs-web-app-ecr", ecrRepositoryName) + + // Run `terraform output` to get the value of an output variable + ecsTaskRoleName := terraform.Output(t, terraformOptions, "ecs_task_role_name") + // Verify we're getting back the outputs we expect + assert.Equal(t, "eg-test-ecs-web-app-task", ecsTaskRoleName) + + // Run `terraform output` to get the value of an output variable + ecsTaskExecRoleName := terraform.Output(t, terraformOptions, "ecs_task_exec_role_name") + // Verify we're getting back the outputs we expect + assert.Equal(t, "eg-test-ecs-web-app-exec", ecsTaskExecRoleName) + + // Run `terraform output` to get the value of an output variable + ecsServiceName := terraform.Output(t, terraformOptions, "ecs_service_name") + // Verify we're getting back the outputs we expect + assert.Equal(t, "eg-test-ecs-web-app", ecsServiceName) + + // Run `terraform output` to get the value of an output variable + ecsExecRolePolicyName := terraform.Output(t, terraformOptions, "ecs_exec_role_policy_name") + // Verify we're getting back the outputs we expect + assert.Equal(t, "eg-test-ecs-web-app-exec", ecsExecRolePolicyName) + + // Run `terraform output` to get the value of an output variable + ecsCloudwatchAutoscalingScaleDownPolicyArn := terraform.Output(t, terraformOptions, "ecs_cloudwatch_autoscaling_scale_down_policy_arn") + // Verify we're getting back the outputs we expect + assert.Contains(t, ecsCloudwatchAutoscalingScaleDownPolicyArn, "policyName/eg-test-ecs-web-app-down") + + // Run `terraform output` to get the value of an output variable + ecsCloudwatchAutoscalingScaleUpPolicyArn := terraform.Output(t, terraformOptions, "ecs_cloudwatch_autoscaling_scale_up_policy_arn") + // Verify we're getting back the outputs we expect + assert.Contains(t, ecsCloudwatchAutoscalingScaleUpPolicyArn, "policyName/eg-test-ecs-web-app-up") + + // Run `terraform output` to get the value of an output variable + ecsAlarmsCpuUtilizationHighCloudwatchMetricAlarmId := terraform.Output(t, terraformOptions, "ecs_alarms_cpu_utilization_high_cloudwatch_metric_alarm_id") + // Verify we're getting back the outputs we expect + assert.Equal(t, "eg-test-ecs-web-app-cpu-utilization-high", ecsAlarmsCpuUtilizationHighCloudwatchMetricAlarmId) + + // Run `terraform output` to get the value of an output variable + ecsAlarmsCpuUtilizationLowCloudwatchMetricAlarmId := terraform.Output(t, terraformOptions, "ecs_alarms_cpu_utilization_low_cloudwatch_metric_alarm_id") + // Verify we're getting back the outputs we expect + assert.Equal(t, "eg-test-ecs-web-app-cpu-utilization-low", ecsAlarmsCpuUtilizationLowCloudwatchMetricAlarmId) + + // Run `terraform output` to get the value of an output variable + ecsAlarmsMemoryUtilizationHighCloudwatchMetricAlarmId := terraform.Output(t, terraformOptions, "ecs_alarms_memory_utilization_high_cloudwatch_metric_alarm_id") + // Verify we're getting back the outputs we expect + assert.Equal(t, "eg-test-ecs-web-app-memory-utilization-high", ecsAlarmsMemoryUtilizationHighCloudwatchMetricAlarmId) + + // Run `terraform output` to get the value of an output variable + ecsAlarmsMemoryUtilizationLowCloudwatchMetricAlarmId := terraform.Output(t, terraformOptions, "ecs_alarms_memory_utilization_low_cloudwatch_metric_alarm_id") + // Verify we're getting back the outputs we expect + assert.Equal(t, "eg-test-ecs-web-app-memory-utilization-low", ecsAlarmsMemoryUtilizationLowCloudwatchMetricAlarmId) + + // Run `terraform output` to get the value of an output variable + httpcodeElb5xxCountCloudwatchMetricAlarmId := terraform.Output(t, terraformOptions, "httpcode_elb_5xx_count_cloudwatch_metric_alarm_id") + // Verify we're getting back the outputs we expect + assert.Equal(t, "eg-test-ecs-web-app-elb-5xx-count-high", httpcodeElb5xxCountCloudwatchMetricAlarmId) + + // Run `terraform output` to get the value of an output variable + httpcodeTarget3xxCountCloudwatchMetricAlarmId := terraform.Output(t, terraformOptions, "httpcode_target_3xx_count_cloudwatch_metric_alarm_id") + // Verify we're getting back the outputs we expect + assert.Equal(t, "eg-test-ecs-web-app-3xx-count-high", httpcodeTarget3xxCountCloudwatchMetricAlarmId) + + // Run `terraform output` to get the value of an output variable + httpcodeTarget4xxCountCloudwatchMetricAlarmId := terraform.Output(t, terraformOptions, "httpcode_target_4xx_count_cloudwatch_metric_alarm_id") + // Verify we're getting back the outputs we expect + assert.Equal(t, "eg-test-ecs-web-app-4xx-count-high", httpcodeTarget4xxCountCloudwatchMetricAlarmId) + + // Run `terraform output` to get the value of an output variable + httpcodeTarget5xxCountCloudwatchMetricAlarmId := terraform.Output(t, terraformOptions, "httpcode_target_5xx_count_cloudwatch_metric_alarm_id") + // Verify we're getting back the outputs we expect + assert.Equal(t, "eg-test-ecs-web-app-5xx-count-high", httpcodeTarget5xxCountCloudwatchMetricAlarmId) + + // Run `terraform output` to get the value of an output variable + targetResponseTimeAverageCloudwatchMetricAlarmId := terraform.Output(t, terraformOptions, "target_response_time_average_cloudwatch_metric_alarm_id") + // Verify we're getting back the outputs we expect + assert.Equal(t, "eg-test-ecs-web-app-target-response-high", targetResponseTimeAverageCloudwatchMetricAlarmId) +} diff --git a/variables.tf b/variables.tf index d86c9590..b91d6a90 100644 --- a/variables.tf +++ b/variables.tf @@ -1,637 +1,652 @@ -variable "name" { - type = "string" - description = "Name (unique identifier for app or service)" +variable "region" { + type = string + description = "AWS Region for S3 bucket" } variable "namespace" { - type = "string" + type = string description = "Namespace (e.g. `eg` or `cp`)" -} - -variable "delimiter" { - type = "string" - description = "The delimiter to be used in labels" - default = "-" + default = "" } variable "stage" { - type = "string" + type = string description = "Stage (e.g. `prod`, `dev`, `staging`)" + default = "" +} + +variable "name" { + type = string + description = "Name of the application" +} + +variable "delimiter" { + type = string + default = "-" + description = "Delimiter between `namespace`, `stage`, `name` and `attributes`" } variable "attributes" { - type = "list" - description = "List of attributes to add to label" + type = list(string) + description = "Additional attributes (_e.g._ \"1\")" default = [] } variable "tags" { - type = "map" - description = "Map of key-value pairs to use for tags" + type = map(string) + description = "Additional tags (_e.g._ { BusinessUnit : ABC })" default = {} } variable "codepipeline_enabled" { - type = "string" + type = bool description = "A boolean to enable/disable AWS Codepipeline and ECR" - default = "true" + default = true } variable "container_image" { - type = "string" + type = string description = "The default container image to use in container definition" default = "cloudposse/default-backend" } variable "container_cpu" { - type = "string" + type = number description = "The vCPU setting to control cpu limits of container. (If FARGATE launch type is used below, this must be a supported vCPU size from the table here: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-cpu-memory-error.html)" - default = "256" + default = 256 } variable "container_memory" { - type = "string" + type = number description = "The amount of RAM to allow container to use in MB. (If FARGATE launch type is used below, this must be a supported Memory size from the table here: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-cpu-memory-error.html)" - default = "512" + default = 512 } variable "container_memory_reservation" { - type = "string" - description = "The amount of RAM (Soft Limit) to allow container to use in MB. This value must be less than container_memory if set" - default = "" + type = number + description = "The amount of RAM (Soft Limit) to allow container to use in MB. This value must be less than `container_memory` if set" + default = 128 } variable "container_port" { - type = "string" + type = number description = "The port number on the container bound to assigned host_port" - default = "80" + default = 80 } variable "port_mappings" { - type = "list" + type = list(object({ + containerPort = number + hostPort = number + protocol = string + })) + description = "The port mappings to configure for the container. This is a list of maps. Each map should contain \"containerPort\", \"hostPort\", and \"protocol\", where \"protocol\" is one of \"tcp\" or \"udp\". If using containers in a task with the awsvpc or host network mode, the hostPort can either be left blank or set to the same value as the containerPort" - default = [{ - "containerPort" = 80 - "hostPort" = 80 - "protocol" = "tcp" - }] + default = [ + { + containerPort = 80 + hostPort = 80 + protocol = "tcp" + } + ] } variable "desired_count" { - type = "string" + type = number description = "The desired number of tasks to start with. Set this to 0 if using DAEMON Service type. (FARGATE does not suppoert DAEMON Service type)" - default = "1" -} - -variable "host_port" { - type = "string" - description = "The port number to bind container_port to on the host" - default = "" + default = 1 } variable "launch_type" { - type = "string" + type = string description = "The ECS launch type (valid options: FARGATE or EC2)" default = "FARGATE" } variable "environment" { - type = "list" - description = "The environment variables for the task definition. This is a list of maps" - default = [] + type = list(object({ + name = string + value = string + })) + description = "The environment variables to pass to the container. This is a list of maps" + default = null } variable "secrets" { - type = "list" - description = "The secrets for the task definition. This is a list of maps" - default = [] -} - -variable "protocol" { - type = "string" - description = "The protocol used for the port mapping. Options: `tcp` or `udp`" - default = "tcp" + type = list(object({ + name = string + valueFrom = string + })) + description = "The secrets to pass to the container. This is a list of maps" + default = null } +# https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_HealthCheck.html variable "healthcheck" { - type = "map" - description = "A map containing command (string), interval (duration in seconds), retries (1-10, number of times to retry before marking container unhealthy, and startPeriod (0-300, optional grace period to wait, in seconds, before failed healthchecks count toward retries)" - default = {} + type = object({ + command = list(string) + retries = number + timeout = number + interval = number + startPeriod = number + }) + description = "A map containing command (string), timeout, interval (duration in seconds), retries (1-10, number of times to retry before marking container unhealthy), and startPeriod (0-300, optional grace period to wait, in seconds, before failed healthchecks count toward retries)" + default = null } variable "health_check_grace_period_seconds" { - type = "string" + type = number description = "Seconds to ignore failing load balancer health checks on newly instantiated tasks to prevent premature shutdown, up to 7200. Only valid for services configured to use load balancers" - default = "0" -} - -variable "alb_target_group_arn" { - type = "string" - description = "Pass target group down to module" - default = "" + default = 0 } variable "alb_target_group_alarms_enabled" { - type = "string" + type = bool description = "A boolean to enable/disable CloudWatch Alarms for ALB Target metrics" - default = "false" + default = false } variable "alb_target_group_alarms_3xx_threshold" { - type = "string" + type = number description = "The maximum number of 3XX HTTPCodes in a given period for ECS Service" - default = "25" + default = 25 } variable "alb_target_group_alarms_4xx_threshold" { - type = "string" + type = number description = "The maximum number of 4XX HTTPCodes in a given period for ECS Service" - default = "25" + default = 25 } variable "alb_target_group_alarms_5xx_threshold" { - type = "string" + type = number description = "The maximum number of 5XX HTTPCodes in a given period for ECS Service" - default = "25" + default = 25 } variable "alb_target_group_alarms_response_time_threshold" { - type = "string" + type = number description = "The maximum ALB Target Group response time" - default = "0.5" + default = 0.5 } variable "alb_target_group_alarms_period" { - type = "string" + type = number description = "The period (in seconds) to analyze for ALB CloudWatch Alarms" - default = "300" + default = 300 } variable "alb_target_group_alarms_evaluation_periods" { - type = "string" + type = number description = "The number of periods to analyze for ALB CloudWatch Alarms" - default = "1" + default = 1 } variable "alb_target_group_alarms_alarm_actions" { - type = "list" + type = list(string) description = "A list of ARNs (i.e. SNS Topic ARN) to execute when ALB Target Group alarms transition into an ALARM state from any other state" default = [] } variable "alb_target_group_alarms_ok_actions" { - type = "list" + type = list(string) description = "A list of ARNs (i.e. SNS Topic ARN) to execute when ALB Target Group alarms transition into an OK state from any other state" default = [] } variable "alb_target_group_alarms_insufficient_data_actions" { - type = "list" + type = list(string) description = "A list of ARNs (i.e. SNS Topic ARN) to execute when ALB Target Group alarms transition into an INSUFFICIENT_DATA state from any other state" default = [] } -variable "alb_name" { - type = "string" - description = "Name of the ALB for the Target Group" - default = "" -} - variable "alb_arn_suffix" { - type = "string" + type = string description = "ARN suffix of the ALB for the Target Group" default = "" } variable "alb_security_group" { - type = "string" + type = string description = "Security group of the ALB" } variable "alb_ingress_healthcheck_path" { - type = "string" + type = string description = "The path of the healthcheck which the ALB checks" default = "/" } variable "alb_ingress_listener_unauthenticated_priority" { - type = "string" - default = "1000" + type = number + default = 1000 description = "The priority for the rules without authentication, between 1 and 50000 (1 being highest priority). Must be different from `alb_ingress_listener_authenticated_priority` since a listener can't have multiple rules with the same priority" } variable "alb_ingress_listener_authenticated_priority" { - type = "string" - default = "300" + type = number + default = 300 description = "The priority for the rules with authentication, between 1 and 50000 (1 being highest priority). Must be different from `alb_ingress_listener_unauthenticated_priority` since a listener can't have multiple rules with the same priority" } variable "alb_ingress_unauthenticated_hosts" { - type = "list" + type = list(string) default = [] description = "Unauthenticated hosts to match in Hosts header" } variable "alb_ingress_authenticated_hosts" { - type = "list" + type = list(string) default = [] description = "Authenticated hosts to match in Hosts header" } variable "alb_ingress_unauthenticated_paths" { - type = "list" + type = list(string) default = [] description = "Unauthenticated path pattern to match (a maximum of 1 can be defined)" } variable "alb_ingress_authenticated_paths" { - type = "list" + type = list(string) default = [] description = "Authenticated path pattern to match (a maximum of 1 can be defined)" } variable "vpc_id" { - type = "string" + type = string description = "The VPC ID where resources are created" } variable "aws_logs_region" { - type = "string" + type = string description = "The region for the AWS Cloudwatch Logs group" } +variable "log_driver" { + type = string + description = "The log driver to use for the container. If using Fargate launch type, only supported value is awslogs" + default = "awslogs" +} + variable "ecs_alarms_enabled" { - type = "string" + type = bool description = "A boolean to enable/disable CloudWatch Alarms for ECS Service metrics" - default = "false" + default = false } variable "ecs_cluster_arn" { - type = "string" + type = string description = "The ECS Cluster ARN where ECS Service will be provisioned" } variable "ecs_cluster_name" { - type = "string" + type = string description = "The ECS Cluster Name to use in ECS Code Pipeline Deployment step" } variable "ecs_alarms_cpu_utilization_high_threshold" { - type = "string" + type = number description = "The maximum percentage of CPU utilization average" - default = "80" + default = 80 } variable "ecs_alarms_cpu_utilization_high_evaluation_periods" { - type = "string" + type = number description = "Number of periods to evaluate for the alarm" - default = "1" + default = 1 } variable "ecs_alarms_cpu_utilization_high_period" { - type = "string" + type = number description = "Duration in seconds to evaluate for the alarm" - default = "300" + default = 300 } variable "ecs_alarms_cpu_utilization_high_alarm_actions" { - type = "list" + type = list(string) description = "A list of ARNs (i.e. SNS Topic ARN) to notify on CPU Utilization High Alarm action" default = [] } variable "ecs_alarms_cpu_utilization_high_ok_actions" { - type = "list" + type = list(string) description = "A list of ARNs (i.e. SNS Topic ARN) to notify on CPU Utilization High OK action" default = [] } variable "ecs_alarms_cpu_utilization_low_threshold" { - type = "string" + type = number description = "The minimum percentage of CPU utilization average" - default = "20" + default = 20 } variable "ecs_alarms_cpu_utilization_low_evaluation_periods" { - type = "string" + type = number description = "Number of periods to evaluate for the alarm" - default = "1" + default = 1 } variable "ecs_alarms_cpu_utilization_low_period" { - type = "string" + type = number description = "Duration in seconds to evaluate for the alarm" - default = "300" + default = 300 } variable "ecs_alarms_cpu_utilization_low_alarm_actions" { - type = "list" + type = list(string) description = "A list of ARNs (i.e. SNS Topic ARN) to notify on CPU Utilization Low Alarm action" default = [] } variable "ecs_alarms_cpu_utilization_low_ok_actions" { - type = "list" + type = list(string) description = "A list of ARNs (i.e. SNS Topic ARN) to notify on CPU Utilization Low OK action" default = [] } variable "ecs_alarms_memory_utilization_high_threshold" { - type = "string" + type = number description = "The maximum percentage of Memory utilization average" - default = "80" + default = 80 } variable "ecs_alarms_memory_utilization_high_evaluation_periods" { - type = "string" + type = number description = "Number of periods to evaluate for the alarm" - default = "1" + default = 1 } variable "ecs_alarms_memory_utilization_high_period" { - type = "string" + type = number description = "Duration in seconds to evaluate for the alarm" - default = "300" + default = 300 } variable "ecs_alarms_memory_utilization_high_alarm_actions" { - type = "list" + type = list(string) description = "A list of ARNs (i.e. SNS Topic ARN) to notify on Memory Utilization High Alarm action" default = [] } variable "ecs_alarms_memory_utilization_high_ok_actions" { - type = "list" + type = list(string) description = "A list of ARNs (i.e. SNS Topic ARN) to notify on Memory Utilization High OK action" default = [] } variable "ecs_alarms_memory_utilization_low_threshold" { - type = "string" + type = number description = "The minimum percentage of Memory utilization average" - default = "20" + default = 20 } variable "ecs_alarms_memory_utilization_low_evaluation_periods" { - type = "string" + type = number description = "Number of periods to evaluate for the alarm" - default = "1" + default = 1 } variable "ecs_alarms_memory_utilization_low_period" { - type = "string" + type = number description = "Duration in seconds to evaluate for the alarm" - default = "300" + default = 300 } variable "ecs_alarms_memory_utilization_low_alarm_actions" { - type = "list" + type = list(string) description = "A list of ARNs (i.e. SNS Topic ARN) to notify on Memory Utilization Low Alarm action" default = [] } variable "ecs_alarms_memory_utilization_low_ok_actions" { - type = "list" + type = list(string) description = "A list of ARNs (i.e. SNS Topic ARN) to notify on Memory Utilization Low OK action" default = [] } variable "ecs_security_group_ids" { - type = "list" + type = list(string) description = "Additional Security Group IDs to allow into ECS Service" default = [] } variable "ecs_private_subnet_ids" { - type = "list" + type = list(string) description = "List of Private Subnet IDs to provision ECS Service onto" } variable "github_oauth_token" { - type = "string" + type = string description = "GitHub Oauth Token with permissions to access private repositories" default = "" } variable "github_webhooks_token" { - type = "string" + type = string description = "GitHub OAuth Token with permissions to create webhooks. If not provided, can be sourced from the `GITHUB_TOKEN` environment variable" default = "" } variable "github_webhook_events" { - type = "list" + type = list(string) description = "A list of events which should trigger the webhook. See a list of [available events](https://developer.github.com/v3/activity/events/types/)" default = ["push"] } variable "repo_owner" { - type = "string" + type = string description = "GitHub Organization or Username" default = "" } variable "repo_name" { - type = "string" + type = string description = "GitHub repository name of the application to be built and deployed to ECS" default = "" } variable "branch" { - type = "string" - description = "Branch of the GitHub repository, e.g. master" + type = string + description = "Branch of the GitHub repository, e.g. `master`" default = "" } variable "badge_enabled" { - type = "string" - default = "false" + type = bool + default = false description = "Generates a publicly-accessible URL for the projects build badge. Available as badge_url attribute when enabled" } variable "build_image" { + type = string default = "aws/codebuild/docker:17.09.0" description = "Docker image for build environment, _e.g._ `aws/codebuild/docker:docker:17.09.0`" } variable "build_timeout" { - type = "string" - default = "60" + type = number + default = 60 description = "How long in minutes, from 5 to 480 (8 hours), for AWS CodeBuild to wait until timing out any related build that does not get marked as completed" } variable "buildspec" { - default = "" + type = string description = "Declaration to use for building the project. [For more info](http://docs.aws.amazon.com/codebuild/latest/userguide/build-spec-ref.html)" + default = "" } variable "autoscaling_enabled" { - type = "string" + type = bool description = "A boolean to enable/disable Autoscaling policy for ECS Service" - default = "false" + default = false } variable "autoscaling_dimension" { - type = "string" + type = string description = "Dimension to autoscale on (valid options: cpu, memory)" default = "memory" } variable "autoscaling_min_capacity" { - type = "string" + type = number description = "Minimum number of running instances of a Service" - default = "1" + default = 1 } variable "autoscaling_max_capacity" { - type = "string" + type = number description = "Maximum number of running instances of a Service" - default = "2" + default = 2 } variable "autoscaling_scale_up_adjustment" { - type = "string" + type = number description = "Scaling adjustment to make during scale up event" - default = "1" + default = 1 } variable "autoscaling_scale_up_cooldown" { - type = "string" + type = number description = "Period (in seconds) to wait between scale up events" - default = "60" + default = 60 } variable "autoscaling_scale_down_adjustment" { - type = "string" + type = number description = "Scaling adjustment to make during scale down event" - default = "-1" + default = -1 } variable "autoscaling_scale_down_cooldown" { - type = "string" + type = number description = "Period (in seconds) to wait between scale down events" - default = "300" + default = 300 } -# https://www.terraform.io/docs/configuration/variables.html -# It is recommended you avoid using boolean values and use explicit strings variable "poll_source_changes" { - type = "string" - default = "false" + type = bool + default = false description = "Periodically check the location of your source content and run the pipeline if changes are detected" } variable "webhook_enabled" { + type = bool description = "Set to false to prevent the module from creating any webhook resources" - default = "true" + default = true } variable "webhook_target_action" { + type = string description = "The name of the action in a pipeline you want to connect to the webhook. The action must be from the source (first) stage of the pipeline" default = "Source" } variable "webhook_authentication" { + type = string description = "The type of authentication to use. One of IP, GITHUB_HMAC, or UNAUTHENTICATED" default = "GITHUB_HMAC" } variable "webhook_filter_json_path" { + type = string description = "The JSON path to filter on" default = "$.ref" } variable "webhook_filter_match_equals" { + type = string description = "The value to match on (e.g. refs/heads/{Branch})" default = "refs/heads/{Branch}" } variable "alb_ingress_unauthenticated_listener_arns" { - type = "list" - default = [] + type = list(string) description = "A list of unauthenticated ALB listener ARNs to attach ALB listener rules to" + default = [] } variable "alb_ingress_unauthenticated_listener_arns_count" { - type = "string" - default = "0" + type = number description = "The number of unauthenticated ARNs in `alb_ingress_unauthenticated_listener_arns`. This is necessary to work around a limitation in Terraform where counts cannot be computed" + default = 0 } variable "alb_ingress_authenticated_listener_arns" { - type = "list" - default = [] + type = list(string) description = "A list of authenticated ALB listener ARNs to attach ALB listener rules to" + default = [] } variable "alb_ingress_authenticated_listener_arns_count" { - type = "string" - default = "0" + type = number description = "The number of authenticated ARNs in `alb_ingress_authenticated_listener_arns`. This is necessary to work around a limitation in Terraform where counts cannot be computed" + default = 0 } variable "authentication_type" { - type = "string" - default = "" + type = string description = "Authentication type. Supported values are `COGNITO` and `OIDC`" + default = "" } variable "authentication_cognito_user_pool_arn" { - type = "string" + type = string description = "Cognito User Pool ARN" default = "" } variable "authentication_cognito_user_pool_client_id" { - type = "string" + type = string description = "Cognito User Pool Client ID" default = "" } variable "authentication_cognito_user_pool_domain" { - type = "string" + type = string description = "Cognito User Pool Domain. The User Pool Domain should be set to the domain prefix (`xxx`) instead of full domain (https://xxx.auth.us-west-2.amazoncognito.com)" default = "" } variable "authentication_oidc_client_id" { - type = "string" + type = string description = "OIDC Client ID" default = "" } variable "authentication_oidc_client_secret" { - type = "string" + type = string description = "OIDC Client Secret" default = "" } variable "authentication_oidc_issuer" { - type = "string" + type = string description = "OIDC Issuer" default = "" } variable "authentication_oidc_authorization_endpoint" { - type = "string" + type = string description = "OIDC Authorization Endpoint" default = "" } variable "authentication_oidc_token_endpoint" { - type = "string" + type = string description = "OIDC Token Endpoint" default = "" } variable "authentication_oidc_user_info_endpoint" { - type = "string" + type = string description = "OIDC User Info Endpoint" default = "" } variable "codepipeline_s3_bucket_force_destroy" { + type = bool description = "A boolean that indicates all objects should be deleted from the CodePipeline artifact store S3 bucket so that the bucket can be destroyed without error" default = false } diff --git a/versions.tf b/versions.tf new file mode 100644 index 00000000..9840ed75 --- /dev/null +++ b/versions.tf @@ -0,0 +1,10 @@ +terraform { + required_version = "~> 0.12.0" + + required_providers { + aws = "~> 2.0" + template = "~> 2.0" + null = "~> 2.0" + local = "~> 1.3" + } +}