Skip to content

Commit 56e7c6e

Browse files
authored
feat: update container definition including additional parameters to configure (#148)
1 parent 726454d commit 56e7c6e

11 files changed

+583
-33
lines changed

.pre-commit-config.yaml

+1-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ repos:
44
hooks:
55
- id: terraform_fmt
66
- id: terraform_docs
7-
- id: terraform_validate
87
- repo: git://github.com/pre-commit/pre-commit-hooks
9-
rev: v2.5.0
8+
rev: v3.1.0
109
hooks:
1110
- id: check-merge-conflict

README.md

+30-5
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ See `README.md` in `examples` for Github or Gitlab for complete details.
1919

2020
## Terraform versions
2121

22-
Terraform 0.12. Pin module version to `~> v2.0`. Submit pull-requests to `master` branch.
22+
Terraform 0.12 or newer. Pin module version to `~> v2.0`. Submit pull-requests to `master` branch.
2323

24-
Terraform 0.11. Pin module version to `~> v1.0`. Submit pull-requests to `terraform011` branch.
24+
Terraform 0.11. Pin module version to `~> v1.0`.
2525

2626
### Before using Atlantis and the code in this repository please make sure that you have read and understood the security implications described in [the official Atlantis documentation](https://www.runatlantis.io/docs/security.html).
2727

@@ -57,7 +57,7 @@ $ cd terraform-aws-atlantis
5757
### Run Atlantis as a Terraform module
5858

5959
This way allows integration with your existing Terraform configurations.
60-
60+
6161
```hcl
6262
module "atlantis" {
6363
source = "terraform-aws-modules/atlantis/aws"
@@ -157,19 +157,23 @@ allow_github_webhooks = true
157157

158158
## Examples
159159

160+
* [Complete Atlantis with GitHub webhook](https://github.com/terraform-aws-modules/terraform-aws-atlantis/tree/master/examples/github-complete)
160161
* [GitHub repository webhook for Atlantis](https://github.com/terraform-aws-modules/terraform-aws-atlantis/tree/master/examples/github-repository-webhook)
161162
* [GitLab repository webhook for Atlantis](https://github.com/terraform-aws-modules/terraform-aws-atlantis/tree/master/examples/gitlab-repository-webhook)
162163

163164
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
164165
## Requirements
165166

166-
No requirements.
167+
| Name | Version |
168+
|------|---------|
169+
| terraform | >= 0.12.7, < 0.14 |
170+
| aws | >= 2.68, < 4.0 |
167171

168172
## Providers
169173

170174
| Name | Version |
171175
|------|---------|
172-
| aws | n/a |
176+
| aws | >= 2.68, < 4.0 |
173177
| random | n/a |
174178

175179
## Inputs
@@ -210,33 +214,49 @@ No requirements.
210214
| certificate\_arn | ARN of certificate issued by AWS ACM. If empty, a new ACM certificate will be created and validated using Route53 DNS | `string` | `""` | no |
211215
| cidr | The CIDR block for the VPC which will be created if `vpc_id` is not specified | `string` | `""` | no |
212216
| cloudwatch\_log\_retention\_in\_days | Retention period of Atlantis CloudWatch logs | `number` | `7` | no |
217+
| command | The command that is passed to the container | `list(string)` | `null` | no |
218+
| container\_depends\_on | The dependencies defined for container startup and shutdown. A container can contain multiple dependencies. When a dependency is defined for container startup, for container shutdown it is reversed. The condition can be one of START, COMPLETE, SUCCESS or HEALTHY | <pre>list(object({<br> containerName = string<br> condition = string<br> }))</pre> | `null` | no |
213219
| container\_memory\_reservation | The amount of memory (in MiB) to reserve for the container | `number` | `128` | no |
214220
| create\_route53\_record | Whether to create Route53 record for Atlantis | `bool` | `true` | no |
215221
| custom\_container\_definitions | A list of valid container definitions provided as a single valid JSON document. By default, the standard container definition is used. | `string` | `""` | no |
216222
| custom\_environment\_secrets | List of additional secrets the container will use (list should contain maps with `name` and `valueFrom`) | <pre>list(object(<br> {<br> name = string<br> valueFrom = string<br> }<br> ))</pre> | `[]` | no |
217223
| custom\_environment\_variables | List of additional environment variables the container will use (list should contain maps with `name` and `value`) | <pre>list(object(<br> {<br> name = string<br> value = string<br> }<br> ))</pre> | `[]` | no |
224+
| docker\_labels | The configuration options to send to the `docker_labels` | `map(string)` | `null` | no |
225+
| ecs\_container\_insights | Controls if ECS Cluster has container insights enabled | `bool` | `false` | no |
218226
| ecs\_service\_assign\_public\_ip | Should be true, if ECS service is using public subnets (more info: https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_cannot_pull_image.html) | `bool` | `false` | no |
219227
| ecs\_service\_deployment\_maximum\_percent | The upper limit (as a percentage of the service's desiredCount) of the number of running tasks that can be running in a service during a deployment | `number` | `200` | no |
220228
| ecs\_service\_deployment\_minimum\_healthy\_percent | The lower limit (as a percentage of the service's desiredCount) of the number of running tasks that must remain running and healthy in a service during a deployment | `number` | `50` | no |
221229
| ecs\_service\_desired\_count | The number of instances of the task definition to place and keep running | `number` | `1` | no |
222230
| ecs\_task\_cpu | The number of cpu units used by the task | `number` | `256` | no |
223231
| ecs\_task\_memory | The amount (in MiB) of memory used by the task | `number` | `512` | no |
232+
| entrypoint | The entry point that is passed to the container | `list(string)` | `null` | no |
233+
| essential | Determines whether all other containers in a task are stopped, if this container fails or stops for any reason. Due to how Terraform type casts booleans in json it is required to double quote this value | `bool` | `true` | no |
234+
| firelens\_configuration | The FireLens configuration for the container. This is used to specify and configure a log router for container logs. For more details, see https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_FirelensConfiguration.html | <pre>object({<br> type = string<br> options = map(string)<br> })</pre> | `null` | no |
224235
| github\_webhooks\_cidr\_blocks | List of CIDR blocks used by GitHub webhooks | `list(string)` | <pre>[<br> "140.82.112.0/20",<br> "185.199.108.0/22",<br> "192.30.252.0/22"<br>]</pre> | no |
225236
| internal | Whether the load balancer is internal or external | `bool` | `false` | no |
237+
| mount\_points | Container mount points. This is a list of maps, where each map should contain a `containerPath` and `sourceVolume`. The `readOnly` key is optional. | `list` | `[]` | no |
226238
| name | Name to use on all resources created (VPC, ALB, etc) | `string` | `"atlantis"` | no |
227239
| policies\_arn | A list of the ARN of the policies you want to apply | `list(string)` | <pre>[<br> "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"<br>]</pre> | no |
228240
| private\_subnet\_ids | A list of IDs of existing private subnets inside the VPC | `list(string)` | `[]` | no |
229241
| private\_subnets | A list of private subnets inside the VPC | `list(string)` | `[]` | no |
230242
| public\_subnet\_ids | A list of IDs of existing public subnets inside the VPC | `list(string)` | `[]` | no |
231243
| public\_subnets | A list of public subnets inside the VPC | `list(string)` | `[]` | no |
244+
| readonly\_root\_filesystem | Determines whether a container is given read-only access to its root filesystem. Due to how Terraform type casts booleans in json it is required to double quote this value | `bool` | `false` | no |
245+
| repository\_credentials | Container repository credentials; required when using a private repo. This map currently supports a single key; "credentialsParameter", which should be the ARN of a Secrets Manager's secret holding the credentials | `map(string)` | `null` | no |
232246
| route53\_record\_name | Name of Route53 record to create ACM certificate in and main A-record. If null is specified, var.name is used instead. Provide empty string to point root domain name to ALB. | `string` | `null` | no |
233247
| route53\_zone\_name | Route53 zone name to create ACM certificate in and main A-record, without trailing dot | `string` | `""` | no |
234248
| security\_group\_ids | List of one or more security groups to be added to the load balancer | `list(string)` | `[]` | no |
235249
| ssm\_kms\_key\_arn | ARN of KMS key to use for encryption and decryption of SSM Parameters. Required only if your key uses a custom KMS key and not the default key | `string` | `""` | no |
250+
| start\_timeout | Time duration (in seconds) to wait before giving up on resolving dependencies for a container | `number` | `30` | no |
251+
| stop\_timeout | Time duration (in seconds) to wait before the container is forcefully killed if it doesn't exit normally on its own | `number` | `30` | no |
236252
| tags | A map of tags to use on all resources | `map(string)` | `{}` | no |
253+
| ulimits | Container ulimit settings. This is a list of maps, where each map should contain "name", "hardLimit" and "softLimit" | <pre>list(object({<br> name = string<br> hardLimit = number<br> softLimit = number<br> }))</pre> | `null` | no |
254+
| user | The user to run as inside the container. Can be any of these formats: user, user:group, uid, uid:gid, user:gid, uid:group. The default (null) will use the container's configured `USER` directive or root if not set. | `string` | `null` | no |
255+
| volumes\_from | A list of VolumesFrom maps which contain "sourceContainer" (name of the container that has the volumes to mount) and "readOnly" (whether the container can write to the volume) | <pre>list(object({<br> sourceContainer = string<br> readOnly = bool<br> }))</pre> | `[]` | no |
237256
| vpc\_id | ID of an existing VPC where resources will be created | `string` | `""` | no |
238257
| webhook\_ssm\_parameter\_name | Name of SSM parameter to keep webhook secret | `string` | `"/atlantis/webhook/secret"` | no |
239258
| whitelist\_unauthenticated\_cidr\_blocks | List of allowed CIDR blocks to bypass authentication | `list(string)` | `[]` | no |
259+
| working\_directory | The working directory to run commands inside the container | `string` | `null` | no |
240260

241261
## Outputs
242262

@@ -249,7 +269,12 @@ No requirements.
249269
| atlantis\_url\_events | Webhook events URL of Atlantis |
250270
| ecs\_security\_group | Security group assigned to ECS Service in network configuration |
251271
| ecs\_task\_definition | Task definition for ECS service (used for external triggers) |
272+
| private\_subnet\_ids | IDs of the VPC private subnets that were created or passed in |
273+
| public\_subnet\_ids | IDs of the VPC public subnets that were created or passed in |
252274
| task\_role\_arn | The Atlantis ECS task role arn |
275+
| task\_role\_id | The Atlantis ECS task role id |
276+
| task\_role\_name | The Atlantis ECS task role name |
277+
| task\_role\_unique\_id | The stable and unique string identifying the Atlantis ECS task role. |
253278
| vpc\_id | ID of the VPC that was created or passed in |
254279
| webhook\_secret | Webhook secret |
255280

examples/github-complete/README.md

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Complete Atlantis example with GitHub Webhooks
2+
3+
Configuration in this directory creates the necessary infrastructure and resources for running Atlantis on Fargate plus GitHub repository webhooks configured to Atlantis URL.
4+
5+
An existing Route53 hosted zone and domain is required to deploy this example.
6+
7+
GitHub's personal access token can be generated at https://github.com/settings/tokens
8+
9+
## Usage
10+
11+
To run this code you need to copy `terraform.tfvars.sample` into `terraform.tfvars` and update the values locally or specify them using environment variables (`TF_VAR_github_token=xxx`, `TF_VAR_github_organization=xxx`, etc.). Once ready, execute:
12+
13+
```bash
14+
$ terraform init
15+
$ terraform plan
16+
$ terraform apply
17+
```
18+
19+
Note - if you receive the following error when running apply:
20+
21+
`Error: InvalidParameterException: The new ARN and resource ID format must be enabled to add tags to the service. Opt in to the new format and try again. "atlantiscomplete"`
22+
23+
Go to https://eu-west-1.console.aws.amazon.com/ecs/home?region=eu-west-1#/settings (update for your region of use) and change `Container instance`, `Service`, and `Task` to `Enabled`.
24+
25+
⚠️ This example will create resources which cost money. Run `terraform destroy` when you don't need these resources. ⚠️
26+
27+
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
28+
## Requirements
29+
30+
No requirements.
31+
32+
## Providers
33+
34+
| Name | Version |
35+
|------|---------|
36+
| aws | n/a |
37+
38+
## Inputs
39+
40+
| Name | Description | Type | Default | Required |
41+
|------|-------------|------|---------|:--------:|
42+
| allowed\_repo\_names | Repositories that Atlantis will listen for events from and a webhook will be installed | `list(string)` | n/a | yes |
43+
| domain | Route53 domain name to use for ACM certificate. Route53 zone for this domain should be created in advance | `string` | n/a | yes |
44+
| github\_organization | Github organization | `string` | n/a | yes |
45+
| github\_token | Github token | `string` | n/a | yes |
46+
| github\_user | Github user for Atlantis to utilize when performing Github activities | `string` | n/a | yes |
47+
| personal\_ip | Your current, personally ip to restrict access to Atlantis UI ending with `/32` for subnet | `string` | n/a | yes |
48+
| region | AWS region where resources will be created | `string` | `"us-east-1"` | no |
49+
50+
## Outputs
51+
52+
| Name | Description |
53+
|------|-------------|
54+
| atlantis\_allowed\_repo\_names | Git repositories where webhook should be created |
55+
| atlantis\_url | URL of Atlantis |
56+
| ecs\_task\_definition | Task definition for ECS service (used for external triggers) |
57+
| github\_webhook\_secret | Github webhook secret |
58+
| github\_webhook\_urls | Github webhook URL |
59+
| task\_role\_arn | The Atlantis ECS task role arn |
60+
61+
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

examples/github-complete/main.tf

+213
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
provider "aws" {
2+
region = var.region
3+
}
4+
5+
locals {
6+
tags = {
7+
Owner = "user"
8+
Environment = "dev"
9+
}
10+
}
11+
12+
##############################################################
13+
# Data sources for existing resources
14+
##############################################################
15+
16+
data "aws_caller_identity" "current" {}
17+
18+
data "aws_region" "current" {}
19+
20+
data "aws_elb_service_account" "current" {}
21+
22+
##############################################################
23+
# Atlantis Service
24+
##############################################################
25+
26+
module "atlantis" {
27+
source = "../../"
28+
29+
name = "atlantiscomplete"
30+
31+
# VPC
32+
cidr = "10.20.0.0/16"
33+
azs = ["${var.region}a", "${var.region}b", "${var.region}c"]
34+
private_subnets = ["10.20.1.0/24", "10.20.2.0/24", "10.20.3.0/24"]
35+
public_subnets = ["10.20.101.0/24", "10.20.102.0/24", "10.20.103.0/24"]
36+
37+
# ECS
38+
ecs_container_insights = true
39+
ecs_task_cpu = 512
40+
ecs_task_memory = 1024
41+
container_memory_reservation = 256
42+
43+
entrypoint = ["docker-entrypoint.sh"]
44+
command = ["server"]
45+
working_directory = "/tmp"
46+
docker_labels = {
47+
"org.opencontainers.image.title" = "Atlantis"
48+
"org.opencontainers.image.description" = "A self-hosted golang application that listens for Terraform pull request events via webhooks."
49+
"org.opencontainers.image.url" = "https://github.com/runatlantis/atlantis/blob/master/Dockerfile"
50+
}
51+
start_timeout = 30
52+
stop_timeout = 30
53+
54+
user = "atlantis"
55+
readonly_root_filesystem = false # atlantis currently mutable access to root filesystem
56+
ulimits = [{
57+
name = "nofile"
58+
softLimit = 4096
59+
hardLimit = 16384
60+
}]
61+
62+
# DNS
63+
route53_zone_name = var.domain
64+
65+
# Atlantis
66+
atlantis_github_user = var.github_user
67+
atlantis_github_user_token = var.github_token
68+
atlantis_repo_whitelist = ["github.com/${var.github_organization}/*"]
69+
atlantis_allowed_repo_names = var.allowed_repo_names
70+
71+
# ALB access
72+
alb_ingress_cidr_blocks = [var.personal_ip]
73+
alb_logging_enabled = true
74+
alb_log_bucket_name = module.atlantis_access_log_bucket.this_s3_bucket_id
75+
alb_log_location_prefix = "atlantis-alb"
76+
77+
allow_unauthenticated_access = true
78+
allow_github_webhooks = true
79+
allow_repo_config = true
80+
81+
tags = local.tags
82+
}
83+
84+
################################################################################
85+
# GitHub Webhooks
86+
################################################################################
87+
88+
module "github_repository_webhook" {
89+
source = "../../modules/github-repository-webhook"
90+
91+
github_organization = var.github_organization
92+
github_token = var.github_token
93+
94+
atlantis_allowed_repo_names = module.atlantis.atlantis_allowed_repo_names
95+
96+
webhook_url = module.atlantis.atlantis_url_events
97+
webhook_secret = module.atlantis.webhook_secret
98+
}
99+
################################################################################
100+
# ALB Access Log Bucket + Policy
101+
################################################################################
102+
103+
module "atlantis_access_log_bucket" {
104+
source = "terraform-aws-modules/s3-bucket/aws"
105+
version = "~> 1.9"
106+
107+
bucket = "${data.aws_caller_identity.current.account_id}-atlantis-access-logs-${data.aws_region.current.name}"
108+
109+
attach_policy = true
110+
policy = data.aws_iam_policy_document.atlantis_access_log_bucket_policy.json
111+
112+
block_public_acls = true
113+
block_public_policy = true
114+
ignore_public_acls = true
115+
restrict_public_buckets = true
116+
117+
force_destroy = true
118+
119+
tags = local.tags
120+
121+
server_side_encryption_configuration = {
122+
rule = {
123+
apply_server_side_encryption_by_default = {
124+
sse_algorithm = "AES256"
125+
}
126+
}
127+
}
128+
129+
lifecycle_rule = [
130+
{
131+
id = "all"
132+
enabled = true
133+
134+
transition = [
135+
{
136+
days = 30
137+
storage_class = "ONEZONE_IA"
138+
}, {
139+
days = 60
140+
storage_class = "GLACIER"
141+
}
142+
]
143+
144+
expiration = {
145+
days = 90
146+
}
147+
148+
noncurrent_version_expiration = {
149+
days = 30
150+
}
151+
},
152+
]
153+
}
154+
155+
data "aws_iam_policy_document" "atlantis_access_log_bucket_policy" {
156+
statement {
157+
sid = "LogsLogDeliveryWrite"
158+
effect = "Allow"
159+
actions = ["s3:PutObject"]
160+
resources = [
161+
"${module.atlantis_access_log_bucket.this_s3_bucket_arn}/*/AWSLogs/${data.aws_caller_identity.current.account_id}/*"
162+
]
163+
164+
principals {
165+
type = "AWS"
166+
identifiers = [
167+
# https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-access-logs.html#access-logging-bucket-permissions
168+
data.aws_elb_service_account.current.arn,
169+
]
170+
}
171+
}
172+
173+
statement {
174+
sid = "AWSLogDeliveryWrite"
175+
effect = "Allow"
176+
actions = ["s3:PutObject"]
177+
resources = [
178+
"${module.atlantis_access_log_bucket.this_s3_bucket_arn}/*/AWSLogs/${data.aws_caller_identity.current.account_id}/*"
179+
]
180+
181+
principals {
182+
type = "Service"
183+
identifiers = [
184+
"delivery.logs.amazonaws.com"
185+
]
186+
}
187+
188+
condition {
189+
test = "StringEquals"
190+
variable = "s3:x-amz-acl"
191+
192+
values = [
193+
"bucket-owner-full-control"
194+
]
195+
}
196+
}
197+
198+
statement {
199+
sid = "AWSLogDeliveryAclCheck"
200+
effect = "Allow"
201+
actions = ["s3:GetBucketAcl"]
202+
resources = [
203+
module.atlantis_access_log_bucket.this_s3_bucket_arn
204+
]
205+
206+
principals {
207+
type = "Service"
208+
identifiers = [
209+
"delivery.logs.amazonaws.com"
210+
]
211+
}
212+
}
213+
}

0 commit comments

Comments
 (0)