Skip to content

Commit 04cd4bb

Browse files
joshmyersosterman
authored andcommitted
Initial implementation of Atlantis ECS module (#1)
* Initial implementation of Atlantis ECS module * add images * Add disclaimers * Add example
1 parent 0f0b161 commit 04cd4bb

File tree

9 files changed

+1032
-7
lines changed

9 files changed

+1032
-7
lines changed

README.md

Lines changed: 181 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
# terraform-aws-ecs-atlantis [![Build Status](https://travis-ci.org/cloudposse/terraform-aws-ecs-atlantis.svg?branch=master)](https://travis-ci.org/cloudposse/terraform-aws-ecs-atlantis) [![Latest Release](https://img.shields.io/github/release/cloudposse/terraform-aws-ecs-atlantis.svg)](https://github.com/cloudposse/terraform-aws-ecs-atlantis/releases/latest) [![Slack Community](https://slack.cloudposse.com/badge.svg)](https://slack.cloudposse.com)
77

88

9-
A Terraform module for deploying Atlantis to an AWS ECS cluster.
9+
![terraform-aws-ecs-atlantis](docs/logo.png)
10+
11+
A Terraform module for deploying [Atlantis](https://runatlantis.io) to an AWS ECS cluster.
1012

1113

1214
---
@@ -20,6 +22,8 @@ This project is part of our comprehensive ["SweetOps"](https://cpco.io/sweetops)
2022
[<img align="right" title="Share on Twitter" src="https://docs.cloudposse.com/images/ionicons/social-twitter-outline-2.0.1-16x16-999999.svg" />][share_twitter]
2123

2224

25+
[![Terraform Open Source Modules](https://docs.cloudposse.com/images/terraform-open-source-modules.svg)][terraform_modules]
26+
2327

2428

2529
It's 100% Open Source and licensed under the [APACHE2](LICENSE).
@@ -30,16 +34,109 @@ It's 100% Open Source and licensed under the [APACHE2](LICENSE).
3034

3135

3236

37+
We literally have [*hundreds of terraform modules*][terraform_modules] that are Open Source and well-maintained. Check them out!
38+
39+
40+
41+
42+
43+
## Screenshots
44+
45+
46+
![demo](docs/example.png)
47+
*Example of a Pull Request comment from running `terraform plan` using `atlantis`*
48+
49+
50+
## Introduction
51+
52+
53+
Atlantis enables GitOps workflows so that teams can collaborate on operations using Pull Requests.
54+
55+
Under the hood, it's a small self-hosted daemon (`#golang`) that listens for Pull Request webhook events from GitHub.
56+
57+
With Atlantis, engineers can run `terraform plan` and `terraform apply` using "chat ops" type comments on the Pull Request.
3358

59+
### Features
3460

61+
This module provisions the following resources:
3562

63+
- ECS Atlantis web application, which includes:
64+
- ECR Docker registry
65+
- ALB target group, listener rule and alarms
66+
- ECS container definition (using a default backend)
67+
- ECS task definition and IAM role
68+
- ECS service and IAM role
69+
- ECS task autoscaling
70+
- ECS SNS based alarms
71+
- ECS Codepipeline to build our Atlantis image on GitHub release
72+
- ECS Codedeploy to deploy our ECS Atlantis web app
73+
- SSH key pair for Atlantis to pull private Github repositories, which are written to SSM for reading with [chamber](https://github.com/segmentio/chamber)
74+
- Route53 alias for Atlantis
75+
- GitHub webhook to trigger Atlantis for a given repository
3676

77+
What this module does not provision:
78+
79+
- ECS Cluster (BYOC)
80+
- ALB
81+
- ACM certificate
82+
- VPC
83+
- Subnets
84+
85+
## Caveats
3786

87+
- This project assumes that the repo being deployed defines a `Dockerfile` which runs `atlantis`. It might not work with the official version of atlantis. We use [`geodesic`](https://github.com/cloudposse/geodesic) as our docker base image.
88+
- This project defines parameters which are not available in the *official version* of `atlantis`. Our [fork](https://github.com/cloudposse/atlantis) implements the ability to restrict `plan` and `apply` to GitHub teams.
89+
90+
91+
### GitHub Repo Scopes
92+
93+
We suggest creating a personal access token for a GitHub bot user with the following scopes:
94+
95+
- `repo`
96+
* `repo:status`
97+
* `repo_deployment`
98+
* `public_repo`
99+
* `repo:invite`
100+
- `admin:repo_hook`
101+
* `write:repo_hook`
102+
* `read:repo_hook`
103+
104+
![GitHub Repo Scopes](docs/github-repo-scopes.png)
105+
106+
**IMPORTANT:** Do not commit this `github_oauth_token` to source control (e.g. via `terraform.tvfars`).
38107

39108
## Usage
40109

110+
111+
**NOTE:** if no `github_oauth_token` is set, this module attempts to look one up from SSM.
112+
41113
```
42-
TODO
114+
module "atlantis" {
115+
source = "git::https://github.com/cloudposse/terraform-aws-ecs-atlantis.git?ref=master"
116+
enabled = "true"
117+
name = "${var.name}"
118+
namespace = "${var.namespace}"
119+
region = "${var.region}"
120+
stage = "${var.stage}"
121+
122+
atlantis_gh_team_whitelist = "admins:*,engineering:plan"
123+
atlantis_gh_user = "atlantis_bot"
124+
atlantis_repo_whitelist = ["github.com/testing.example.co/*"]
125+
126+
alb_arn_suffix = "${module.alb.alb_arn_suffix}"
127+
alb_dns_name = "${module.alb.alb_dns_name}"
128+
alb_listener_arns = ["${module.alb.listener_arns}"]
129+
alb_name = "${module.alb.alb_name}"
130+
alb_zone_id = "${module.alb.alb_zone_id}"
131+
132+
domain_name = "${var.domain_name}"
133+
ecs_cluster_arn = "${aws_ecs_cluster.default.arn}"
134+
ecs_cluster_name = "${aws_ecs_cluster.default.name}"
135+
repo_name = "testing.example.co"
136+
repo_owner = "example_org"
137+
private_subnet_ids = ["${module.subnets.private_subnet_ids}"]
138+
security_group_ids = ["${module.vpc.vpc_default_security_group_id}"]
139+
vpc_id = "${module.vpc.vpc_id}"
43140
}
44141
```
45142

@@ -58,6 +155,74 @@ Available targets:
58155
lint Lint terraform code
59156
60157
```
158+
## Inputs
159+
160+
| Name | Description | Type | Default | Required |
161+
|------|-------------|:----:|:-----:|:-----:|
162+
| alb_arn_suffix | The ARN suffix of the ALB | string | - | yes |
163+
| alb_dns_name | DNS name of ALB | string | - | yes |
164+
| alb_ingress_paths | Path pattern to match (a maximum of 1 can be defined), at least one of hosts or paths must be set | list | `<list>` | no |
165+
| alb_listener_arns | A list of ALB listener ARNs | list | - | yes |
166+
| alb_name | The Name of the ALB | string | - | yes |
167+
| 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 | `<list>` | no |
168+
| 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 | `<list>` | no |
169+
| 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 | `<list>` | no |
170+
| alb_zone_id | The ID of the zone in which ALB is provisioned | string | - | yes |
171+
| atlantis_allow_repo_config | Allow Atlantis to use atlantis.yaml | string | `true` | no |
172+
| atlantis_gh_team_whitelist | Atlantis GitHub team whitelist | string | `` | no |
173+
| atlantis_gh_user | Atlantis GitHub user | string | - | yes |
174+
| atlantis_gh_webhook_secret | Atlantis GitHub webhook secret | string | `` | no |
175+
| atlantis_log_level | Atlantis log level | string | `info` | no |
176+
| atlantis_port | Atlantis container port | string | `4141` | no |
177+
| atlantis_repo_config | Path to atlantis config file | string | `atlantis.yaml` | no |
178+
| atlantis_repo_whitelist | Whitelist of repositories Atlantis will accept webhooks from | list | `<list>` | no |
179+
| atlantis_wake_word | Wake world for Atlantis | string | `atlantis` | no |
180+
| atlantis_webhook_format | Template for the Atlantis webhook URL which is populated with the hostname | string | `https://%s/events` | no |
181+
| attributes | Additional attributes (e.g. `1`) | list | `<list>` | no |
182+
| autoscaling_max_capacity | Atlantis maximum tasks to run | string | `1` | no |
183+
| autoscaling_min_capacity | Atlantis minimum tasks to run | string | `1` | no |
184+
| branch | Atlantis branch of the GitHub repository, _e.g._ `master` | string | `master` | no |
185+
| 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 | `5` | no |
186+
| chamber_format | Format to store parameters in SSM, for consumption with chamber | string | `/%s/%s` | no |
187+
| chamber_service | SSM parameter service name for use with chamber. This is used in chamber_format where /$chamber_service/$parameter would be the default. | string | `atlantis` | no |
188+
| container_cpu | Atlantis CPUs per task | string | `256` | no |
189+
| container_memory | Atlantis memory per task | string | `512` | no |
190+
| default_backend_image | ECS default (bootstrap) image | string | `cloudposse/default-backend:0.1.2` | no |
191+
| delimiter | Delimiter to be used between `namespace`, `stage`, `name` and `attributes` | string | `-` | no |
192+
| desired_count | Atlantis desired number of tasks | string | `1` | no |
193+
| domain_name | A domain name for which the certificate should be issued | string | - | yes |
194+
| ecs_cluster_arn | ARN of the ECS cluster to deploy Atlantis | string | - | yes |
195+
| ecs_cluster_name | Name of the ECS cluster to deploy Atlantis | string | - | yes |
196+
| enabled | Whether to create the resources. Set to `false` to prevent the module from creating any resources | string | `false` | no |
197+
| github_oauth_token | GitHub Oauth token. If not provided the token is looked up from SSM. | string | `` | no |
198+
| github_oauth_token_ssm_name | SSM param name to lookup GitHub OAuth token if not provided | string | `` | no |
199+
| healthcheck_path | Healthcheck path | string | `/healthz` | no |
200+
| hostname | Atlantis URL | string | `` | no |
201+
| kms_key_id | KMS key ID used to encrypt SSM SecureString parameters | string | `` | no |
202+
| name | Application or solution name (e.g. `app`) | string | `ecs` | no |
203+
| namespace | Namespace (e.g. `eg` or `cp`) | string | - | yes |
204+
| overwrite_ssm_parameter | Whether to overwrite an existing SSM parameter | string | `true` | no |
205+
| policy_arn | Permission to grant to atlantis server | string | `arn:aws:iam::aws:policy/AdministratorAccess` | no |
206+
| private_subnet_ids | The private subnet IDs | list | `<list>` | no |
207+
| region | AWS Region for Atlantis deployment | string | `us-west-2` | no |
208+
| repo_name | GitHub repository name of the atlantis to be built and deployed to ECS. | string | - | yes |
209+
| repo_owner | GitHub organization containing the Atlantis repository | string | - | yes |
210+
| security_group_ids | Additional Security Group IDs to allow into ECS Service. | list | `<list>` | no |
211+
| short_name | Alantis Short DNS name (E.g. `atlantis`) | string | `atlantis` | no |
212+
| ssh_private_key_name | Atlantis SSH private key name | string | `atlantis_ssh_private_key` | no |
213+
| ssh_public_key_name | Atlantis SSH public key name | string | `atlantis_ssh_public_key` | no |
214+
| stage | Stage (e.g. `prod`, `dev`, `staging`) | string | - | yes |
215+
| tags | Additional tags (e.g. map(`BusinessUnit`,`XYZ`) | map | `<map>` | no |
216+
| vpc_id | VPC ID for the ECS Cluster | string | - | yes |
217+
| webhook_events | A list of events which should trigger the webhook. | list | `<list>` | no |
218+
| webhook_secret_length | GitHub webhook secret length | string | `32` | no |
219+
220+
## Outputs
221+
222+
| Name | Description |
223+
|------|-------------|
224+
| atlantis_ssh_public_key | Atlantis SSH Public Key |
225+
| badge_url | the url of the build badge when badge_enabled is enabled |
61226

62227

63228

@@ -73,8 +238,8 @@ Are you using this project or any of our other projects? Consider [leaving a tes
73238

74239
Check out these related projects.
75240

76-
- [terraform-aws-ecs-webapp](https://github.com/cloudposse/terraform-aws-ecs-web-app) - Terraform module that implements a web app on ECS and supports autoscaling, CI/CD, monitoring, ALB integration, and much more
77-
- [terraform-aws-ecs-web-app](https://github.com/cloudposse/terraform-aws-alb) - Terraform module to provision a standard ALB for HTTP/HTTP traffic
241+
- [terraform-aws-ecs-web-app](https://github.com/cloudposse/terraform-aws-ecs-web-app) - Terraform module that implements a web app on ECS and supporting AWS resources
242+
- [terraform-aws-alb](https://github.com/cloudposse/terraform-aws-alb) - Terraform module to provision a standard ALB for HTTP/HTTP traffic
78243
- [terraform-aws-alb-ingress](https://github.com/cloudposse/terraform-aws-alb-ingress) - Terraform module to provision an HTTP style ingress rule based on hostname and path for an ALB
79244
- [terraform-aws-codebuild](https://github.com/cloudposse/terraform-aws-codebuild) - Terraform Module to easily leverage AWS CodeBuild for Continuous Integration
80245
- [terraform-aws-ecr](https://github.com/cloudposse/terraform-aws-ecr) - Terraform Module to manage Docker Container Registries on AWS ECR
@@ -85,6 +250,14 @@ Check out these related projects.
85250

86251

87252

253+
254+
## References
255+
256+
For additional context, refer to some of these links.
257+
258+
- [atlantis](https://runatlantis.io) - Official home of the Atlantis project
259+
260+
88261
## Help
89262

90263
**Got a question?**
@@ -111,6 +284,10 @@ We provide [*commercial support*][commercial_support] for all of our [Open Sourc
111284

112285

113286

287+
## Terraform Module Development
288+
289+
Are you interested in custom Terraform module development? Submit your inquiry using [our form][module_development] today and we'll get back to you ASAP.
290+
114291

115292
## Slack Community
116293

0 commit comments

Comments
 (0)