diff --git a/README.md b/README.md index 0f19c86..afbced4 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,7 @@ What this module does not provision: ### GitHub Repo Scopes -This module accepts two GitHub tokens: +This module accepts two GitHub OAuth tokens: 1. `github_oauth_token` with permissions to pull private repos. Used by CodePipeline to clone repos before the build, and by the atlantis server to clone repos and comment on Pull Requests. @@ -104,7 +104,6 @@ This module accepts two GitHub tokens: 2. `github_webhooks_token` with permissions to create GitHub webhooks. Only used by [Terraform GitHub Provider](https://www.terraform.io/docs/providers/github/index.html) when provisioning the module. - It must be provided either in the `github_webhooks_token` variable, or it can also be sourced from the `GITHUB_TOKEN` environment variable. The token needs the following OAuth scopes: @@ -127,6 +126,15 @@ We suggest the following steps when creating the tokens and provisioning the mod **IMPORTANT:** Do not commit the tokens to source control (_e.g._ via `terraform.tvfars`). +**NOTE:** If the two tokens are not provided (left empty), they will be looked up from SSM Parameter Store. +You can write `atlantis atlantis_gh` and `github_webhooks_token` to SSM Parameter Store before provisioning the module. +For example, by using [chamber](https://github.com/segmentio/chamber): + +```sh + chamber write atlantis atlantis_gh_token "....." + chamber write atlantis github_webhooks_token "....." +``` + ## Usage @@ -260,9 +268,10 @@ Available targets: | ecs_cluster_arn | ARN of the ECS cluster to deploy Atlantis | string | - | yes | | ecs_cluster_name | Name of the ECS cluster to deploy Atlantis | string | - | yes | | enabled | Whether to create the resources. Set to `false` to prevent the module from creating any resources | string | `false` | no | -| github_oauth_token | GitHub Oauth token. If not provided the token is looked up from SSM. | string | `` | no | -| github_oauth_token_ssm_name | SSM param name to lookup GitHub OAuth token if not provided | 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 | +| github_oauth_token | GitHub OAuth token. If not provided the token is looked up from SSM | string | `` | no | +| github_oauth_token_ssm_name | SSM param name to lookup `github_oauth_token` if not provided | string | `` | no | +| github_webhooks_token | GitHub OAuth Token with permissions to create webhooks. If not provided the token is looked up from SSM | string | `` | no | +| github_webhooks_token_ssm_name | SSM param name to lookup `github_webhooks_token` if not provided | string | `` | no | | healthcheck_path | Healthcheck path | string | `/healthz` | no | | hostname | Atlantis URL | string | `` | no | | kms_key_id | KMS key ID used to encrypt SSM SecureString parameters | string | `` | no | diff --git a/README.yaml b/README.yaml index 7a71348..ca25fb1 100644 --- a/README.yaml +++ b/README.yaml @@ -111,7 +111,7 @@ introduction: |- ### GitHub Repo Scopes - This module accepts two GitHub tokens: + This module accepts two GitHub OAuth tokens: 1. `github_oauth_token` with permissions to pull private repos. Used by CodePipeline to clone repos before the build, and by the atlantis server to clone repos and comment on Pull Requests. @@ -125,7 +125,6 @@ introduction: |- 2. `github_webhooks_token` with permissions to create GitHub webhooks. Only used by [Terraform GitHub Provider](https://www.terraform.io/docs/providers/github/index.html) when provisioning the module. - It must be provided either in the `github_webhooks_token` variable, or it can also be sourced from the `GITHUB_TOKEN` environment variable. The token needs the following OAuth scopes: @@ -148,6 +147,15 @@ introduction: |- **IMPORTANT:** Do not commit the tokens to source control (_e.g._ via `terraform.tvfars`). + **NOTE:** If the two tokens are not provided (left empty), they will be looked up from SSM Parameter Store. + You can write `atlantis atlantis_gh` and `github_webhooks_token` to SSM Parameter Store before provisioning the module. + For example, by using [chamber](https://github.com/segmentio/chamber): + + ```sh + chamber write atlantis atlantis_gh_token "....." + chamber write atlantis github_webhooks_token "....." + ``` + # How to use this project usage: |- diff --git a/docs/terraform.md b/docs/terraform.md index ccd91e4..426c57a 100644 --- a/docs/terraform.md +++ b/docs/terraform.md @@ -60,9 +60,10 @@ | ecs_cluster_arn | ARN of the ECS cluster to deploy Atlantis | string | - | yes | | ecs_cluster_name | Name of the ECS cluster to deploy Atlantis | string | - | yes | | enabled | Whether to create the resources. Set to `false` to prevent the module from creating any resources | string | `false` | no | -| github_oauth_token | GitHub Oauth token. If not provided the token is looked up from SSM. | string | `` | no | -| github_oauth_token_ssm_name | SSM param name to lookup GitHub OAuth token if not provided | 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 | +| github_oauth_token | GitHub OAuth token. If not provided the token is looked up from SSM | string | `` | no | +| github_oauth_token_ssm_name | SSM param name to lookup `github_oauth_token` if not provided | string | `` | no | +| github_webhooks_token | GitHub OAuth Token with permissions to create webhooks. If not provided the token is looked up from SSM | string | `` | no | +| github_webhooks_token_ssm_name | SSM param name to lookup `github_webhooks_token` if not provided | string | `` | no | | healthcheck_path | Healthcheck path | string | `/healthz` | no | | hostname | Atlantis URL | string | `` | no | | kms_key_id | KMS key ID used to encrypt SSM SecureString parameters | string | `` | no | diff --git a/main.tf b/main.tf index 739dedb..562c18e 100644 --- a/main.tf +++ b/main.tf @@ -1,7 +1,14 @@ +# 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 #-------------------------------------------------------------- terraform { - required_version = ">= 0.10.7" + required_version = "~> 0.11.0" } # Data @@ -11,6 +18,11 @@ data "aws_ssm_parameter" "atlantis_gh_token" { name = "${local.github_oauth_token_ssm_name}" } +data "aws_ssm_parameter" "github_webhooks_token" { + count = "${local.enabled && length(var.github_webhooks_token) == 0 ? 1 : 0}" + name = "${local.github_webhooks_token_ssm_name}" +} + data "aws_kms_key" "chamber_kms_key" { count = "${local.enabled && length(var.kms_key_id) == 0 ? 1 : 0}" key_id = "${local.kms_key_id}" @@ -19,16 +31,23 @@ data "aws_kms_key" "chamber_kms_key" { # Locals #-------------------------------------------------------------- locals { - enabled = "${var.enabled == "true" ? true : false}" - atlantis_gh_webhook_secret = "${length(var.atlantis_gh_webhook_secret) > 0 ? var.atlantis_gh_webhook_secret : join("", random_string.atlantis_gh_webhook_secret.*.result)}" - atlantis_webhook_url = "${format(var.atlantis_webhook_format, local.hostname)}" - atlantis_url = "${format(var.atlantis_url_format, local.hostname)}" - attributes = "${concat(list(var.short_name), var.attributes)}" - default_hostname = "${join("", aws_route53_record.default.*.fqdn)}" + enabled = "${var.enabled == "true" ? true : false}" + atlantis_gh_webhook_secret = "${length(var.atlantis_gh_webhook_secret) > 0 ? var.atlantis_gh_webhook_secret : join("", random_string.atlantis_gh_webhook_secret.*.result)}" + atlantis_webhook_url = "${format(var.atlantis_webhook_format, local.hostname)}" + atlantis_url = "${format(var.atlantis_url_format, local.hostname)}" + attributes = "${concat(list(var.short_name), var.attributes)}" + default_hostname = "${join("", aws_route53_record.default.*.fqdn)}" + hostname = "${length(var.hostname) > 0 ? var.hostname : local.default_hostname}" + kms_key_id = "${length(var.kms_key_id) > 0 ? var.kms_key_id : format("alias/%s-%s-chamber", var.namespace, var.stage)}" +} + +# GitHub tokens +locals { github_oauth_token = "${length(join("", data.aws_ssm_parameter.atlantis_gh_token.*.value)) > 0 ? join("", data.aws_ssm_parameter.atlantis_gh_token.*.value) : var.github_oauth_token}" github_oauth_token_ssm_name = "${length(var.github_oauth_token_ssm_name) > 0 ? var.github_oauth_token_ssm_name : format(var.chamber_format, var.chamber_service, "atlantis_gh_token")}" - hostname = "${length(var.hostname) > 0 ? var.hostname : local.default_hostname}" - kms_key_id = "${length(var.kms_key_id) > 0 ? var.kms_key_id : format("alias/%s-%s-chamber", var.namespace, var.stage)}" + + github_webhooks_token = "${length(join("", data.aws_ssm_parameter.github_webhooks_token.*.value)) > 0 ? join("", data.aws_ssm_parameter.github_webhooks_token.*.value) : var.github_webhooks_token}" + github_webhooks_token_ssm_name = "${length(var.github_webhooks_token_ssm_name) > 0 ? var.github_webhooks_token_ssm_name : format(var.chamber_format, var.chamber_service, "github_webhooks_token")}" } # Modules @@ -47,7 +66,7 @@ module "ssh_key_pair" { module "webhooks" { source = "git::https://github.com/cloudposse/terraform-github-repository-webhooks.git?ref=tags/0.4.0" - github_token = "${var.github_webhooks_token}" + github_token = "${local.github_webhooks_token}" webhook_secret = "${local.atlantis_gh_webhook_secret}" webhook_url = "${local.atlantis_webhook_url}" enabled = "${local.enabled}" @@ -57,7 +76,7 @@ module "webhooks" { } module "web_app" { - source = "git::https://github.com/cloudposse/terraform-aws-ecs-web-app.git?ref=tags/0.21.0" + source = "git::https://github.com/cloudposse/terraform-aws-ecs-web-app.git?ref=tags/0.22.0" namespace = "${var.namespace}" stage = "${var.stage}" name = "${var.name}" @@ -111,7 +130,7 @@ module "web_app" { alb_ingress_healthcheck_path = "${var.healthcheck_path}" github_oauth_token = "${local.github_oauth_token}" - github_webhooks_token = "${var.github_webhooks_token}" + github_webhooks_token = "${local.github_webhooks_token}" repo_owner = "${var.repo_owner}" repo_name = "${var.repo_name}" branch = "${var.branch}" @@ -282,6 +301,16 @@ resource "aws_ssm_parameter" "atlantis_gh_token" { value = "${local.github_oauth_token}" } +resource "aws_ssm_parameter" "github_webhooks_token" { + count = "${local.enabled ? 1 : 0}" + description = "GitHub OAuth token with permission to create webhooks" + key_id = "${join("", data.aws_kms_key.chamber_kms_key.*.id)}" + name = "${local.github_webhooks_token_ssm_name}" + overwrite = "${var.overwrite_ssm_parameter}" + type = "SecureString" + value = "${local.github_webhooks_token}" +} + resource "aws_security_group_rule" "egress_http" { count = "${local.enabled ? 1 : 0}" cidr_blocks = ["0.0.0.0/0"] diff --git a/variables.tf b/variables.tf index deda96f..c77bbab 100644 --- a/variables.tf +++ b/variables.tf @@ -40,19 +40,25 @@ variable "default_backend_image" { variable "github_oauth_token" { type = "string" - description = "GitHub Oauth token. If not provided the token is looked up from SSM." + description = "GitHub OAuth token. If not provided the token is looked up from SSM" default = "" } variable "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" + description = "GitHub OAuth Token with permissions to create webhooks. If not provided the token is looked up from SSM" default = "" } variable "github_oauth_token_ssm_name" { type = "string" - description = "SSM param name to lookup GitHub OAuth token if not provided" + description = "SSM param name to lookup `github_oauth_token` if not provided" + default = "" +} + +variable "github_webhooks_token_ssm_name" { + type = "string" + description = "SSM param name to lookup `github_webhooks_token` if not provided" default = "" }