Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

doc: use gcp-get-secret to retrieve the sensitive values at startup #30

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

This file was deleted.

15 changes: 9 additions & 6 deletions examples/secured-env-vars/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
FROM binxio/gcp-get-secret:latest

FROM ghcr.io/runatlantis/atlantis:latest
COPY --from=0 /gcp-get-secret /usr/local/bin/

ARG ATLANTIS_GH_USER
ARG ATLANTIS_GH_TOKEN
ARG ATLANTIS_GH_WEBHOOK_SECRET

ENV ATLANTIS_GH_USER $ATLANTIS_GH_USER
ENV ATLANTIS_GH_TOKEN $ATLANTIS_GH_TOKEN
ENV ATLANTIS_GH_WEBHOOK_SECRET $ATLANTIS_GH_WEBHOOK_SECRET
# gcp-get-secret will replace the environment variables values
# with the value in the Google Secret Manager secret before exec'ing
# the atlantis entrypoint.
#
# See https://github.com/binxio/gcp-get-secret
ENTRYPOINT ["/usr/local/bin/gcp-get-secret", "docker-entrypoint.sh"]
65 changes: 44 additions & 21 deletions examples/secured-env-vars/README.md
Original file line number Diff line number Diff line change
@@ -1,38 +1,61 @@
# Securing sensitive environment variables

This guide explains how to secure environment variables when using the Atlantis module on Google Cloud Platform. For more information on using this module, see the [`basic example`](https://github.com/bschaatsbergen/atlantis-on-gcp-vm/tree/master/examples/basic).
This guide explains how to secure environment variables when using the Atlantis module on Google Cloud Platform. For more information on using this module, see the [`basic example`](../basic/README.md).

## Prerequisites
## build your own image
To retrieve sensitive values from the Google Secret manager you need to:

You should already have the following resources:
- enable artifact registry in your Google Cloud Project
- build your own image using the [gcp-get-secret](https://github.com/binxio/gcp-get-secret) as entrypoint
- store your secrets in Google Secret Manager.
- set variable values to point to the secret manager secret URL

- An Artifact or Container Registry in Google Cloud.
- A CI/CD system with a secret manager integration (such as GitHub, Gitlab, Jenkins, or Cloud Build).
## Enable artifact registry
To enable artifact registry, type:

## How to deploy
```shell
gcloud services enable artifactregistry.googleapis.com

To deploy the Atlantis module, see [`Dockerfile`](https://github.com/bschaatsbergen/atlantis-on-gcp-vm/tree/master/examples/secured-env-vars/Dockerfile) and the [`main.tf`](https://github.com/bschaatsbergen/atlantis-on-gcp-vm/tree/master/examples/secured-env-vars/main.tf).

## Configuring Atlantis

Atlantis allows you to configure everything using environment variables. However, these variables may contain sensitive values, and are therefore visible in the Google Cloud console when deploying a container. To protect these values, follow the steps below.

### Setting sensitive environment variables
gcloud artifacts repositories \
create atlantis \
--repository-format=docker \
--location=europe \
--description="Atlantis gcp-get-secret"
```

Use a wrapper Atlantis Docker image to set environment variables that contain sensitive values. See the following examples for more details:
## build the image
The build the atlantis image, type the following commands:

- [**Cloud Build**: pull secrets from Google Secret Manager](https://github.com/bschaatsbergen/atlantis-on-gcp-vm/tree/master/examples/secured-env-vars/cloudbuild.yaml)
- [**GitHub Actions**: pull secrets from Google Secret Manager](https://github.com/bschaatsbergen/atlantis-on-gcp-vm/tree/master/examples/secured-env-vars/.github/workflows/docker-gcp-secrets.yaml)
- [**GitHub Actions**: use GitHub secrets](https://github.com/bschaatsbergen/atlantis-on-gcp-vm/tree/master/examples/secured-env-vars/.github/workflows/docker-github-secrets.yaml)
```shell
REPOSITORY=europe-docker.pkg.dev/$(gcloud config get-value project)/atlantis:latest
docker build -t $REPOSITORY -f Dockerfile .
docker push $REPOSITORY
echo "INFO: set the terraform variable image to \"$REPOSITORY\"" >&2
```

### Setting non-sensitive environment variables
## Store the secrets in Google Secret Manager
Add the secrets into the secret manager, using the following script:

```bash
for SECRET in ATLANTIS_GH_USER ATLANTIS_GH_TOKEN ATLANTIS_GH_WEBHOOK_SECRET; do
NAME=$(sed -e 's/_/-/g' | tr '[:upper:]' '[:lower:]')

read "Value for $SECRET:" VALUE
gcloud secrets create $NAME
gcloud secrets versions add --secret $NAME --datafile <(echo -n "$VALUE")
echo "INFO: stored $SECRET as $NAME" >&2
done
```

## set variable values to point to the secret manager secret URL
Use the `var.env_vars` variable to set non-sensitive environment variables.

```hcl
env_vars = {
ATLANTIS_EXAMPLE = "example"
ATLANTIS_GH_USER = "gcp:///atlantis-gh-user"
ATLANTIS_GH_TOKEN = "gcp:///atlantis-gh-token"
ATLANTIS_GH_WEBHOOK_SECRET = "gcp:///atlantis-gh-webhook-secret"
... other ...
}
```

> **Important**: Do **not** specify the same environment variable in both the env_vars and the Dockerfile, as this will cause the deployment to fail.
This will retrieve the value for the environments variables from the Google Secret Manager on startup of Atlantis.
23 changes: 0 additions & 23 deletions examples/secured-env-vars/cloudbuild.yaml

This file was deleted.

23 changes: 14 additions & 9 deletions examples/secured-env-vars/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,20 @@ resource "google_service_account" "atlantis" {
display_name = "Service Account for Atlantis"
}

resource "google_project_iam_member" "atlantis_log_writer" {
role = "roles/logging.logWriter"
member = "serviceAccount:${google_service_account.atlantis.email}"
project = "<your-project-id>"
}

resource "google_project_iam_member" "atlantis_metric_writer" {
role = "roles/monitoring.metricWriter"
resource "google_project_iam_member" "atlantis" {
for_each = set([
"roles/logging.logWriter",
"roles/monitoring.metricWriter",
"roles/secretmanager.secretAccessor",
"roles/artifactregistry.reader",
])
role = each.value
member = "serviceAccount:${google_service_account.atlantis.email}"
project = "<your-project-id>"
}


# As your DNS records might be managed at another registrar's site, we create the DNS record outside of the module.
# This record is mandatory in order to provision the managed SSL certificate successfully.
resource "google_dns_record_set" "default" {
Expand All @@ -41,11 +43,14 @@ module "atlantis" {
email = "<your-service-account-email>"
scopes = ["cloud-platform"]
}
# Declare the non-sensitive environment variables here
# The sensitive environment variables are set in the Dockerfile!
env_vars = {
ATLANTIS_REPO_ALLOWLIST = "github.com/<your-github-handle>/*"
ATLANTIS_ATLANTIS_URL = "https://<your-domain>"
# the sensitive value will contain an URL in the form of
# gcp:///<secret-name>. See https://github.com/binxio/gcp-get-secret
ATLANTIS_GH_USER = "gcp:///atlantis-gh-user"
ATLANTIS_GH_TOKEN = "gcp:///atlantis-gh-token"
ATLANTIS_GH_WEBHOOK_SECRET = "gcp:///atlantis-gh-webhook-secret"
}
domain = "<your-domain>"
}