Skip to content

Commit

Permalink
docs: modify secure-env-vars example to use a custom entrypoint
Browse files Browse the repository at this point in the history
Signed-off-by: David Costa <[email protected]>
  • Loading branch information
d-costa committed Nov 11, 2024
1 parent 4cd7dcc commit 6b73685
Show file tree
Hide file tree
Showing 9 changed files with 91 additions and 140 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ See [`main.tf`](https://github.com/runatlantis/terraform-gce-atlantis/tree/maste
- Provisioning the Google Cloud Managed SSL certificate can take up to 25 minutes after the `terraform apply` has finished.

- If you bring your own Docker image (*not using any Atlantis image as base image*), be sure to create an Atlantis user using a uid (user ID) of 100.
- As per Docker spec, the base image's `CMD` will be overridden when you define a new `ENTRYPOINT` through the `command` variable: <https://docs.docker.com/engine/reference/builder/#understand-how-cmd-and-entrypoint-interact>

### After it's successfully deployed

Expand Down Expand Up @@ -232,7 +233,9 @@ You can check the status of the certificate in the Google Cloud Console.

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_args"></a> [args](#input\_args) | Arguments to override the container image default command (CMD). | `list(string)` | `null` | no |
| <a name="input_block_project_ssh_keys_enabled"></a> [block\_project\_ssh\_keys\_enabled](#input\_block\_project\_ssh\_keys\_enabled) | Blocks the use of project-wide publich SSH keys | `bool` | `false` | no |
| <a name="input_command"></a> [command](#input\_command) | Command to override the container image ENTRYPOINT | `list(string)` | `null` | no |
| <a name="input_default_backend_security_policy"></a> [default\_backend\_security\_policy](#input\_default\_backend\_security\_policy) | Name of the security policy to apply to the default backend service | `string` | `null` | no |
| <a name="input_disk_kms_key_self_link"></a> [disk\_kms\_key\_self\_link](#input\_disk\_kms\_key\_self\_link) | The self link of the encryption key that is stored in Google Cloud KMS | `string` | `null` | no |
| <a name="input_domain"></a> [domain](#input\_domain) | Domain to associate Atlantis with and to request a managed SSL certificate for. Without `https://` | `string` | n/a | yes |
Expand Down
53 changes: 0 additions & 53 deletions examples/secure-env-vars/.github/workflows/docker-gcp-secrets.yaml

This file was deleted.

This file was deleted.

9 changes: 0 additions & 9 deletions examples/secure-env-vars/Dockerfile

This file was deleted.

16 changes: 13 additions & 3 deletions examples/secure-env-vars/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,24 @@

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/runatlantis/terraform-gce-atlantis/tree/master/examples/basic).

Additionally, this example uses a GitHub App for authentication, and a custom image entrypoint to set environment variables at container startup time.

- [Prerequisites](#prerequisites)
- [How to deploy](#how-to-deploy)
- [Important](#Important)
- [Important](#important)
- [Setting sensitive environment variables](#setting-sensitive-environment-variables)
- [Setting non sensitive environment variables](#setting-non-sensitive-environment-variables)

## Prerequisites

You should already have the following resources:

- 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).
- Google network, subnetwork and a Cloud NAT
- Service account, [specifics can be found here](../../README.md#service-account)
- Domain, [specifics can be found here](../../README.md#dns-record)
- The secrets for the GitHub app id, secret, and webhook secret.

If you prefer an example that includes the above resources, see [`complete example`](https://github.com/bschaatsbergen/atlantis-on-gcp-vm/tree/master/examples/complete)

## How to deploy

Expand All @@ -22,6 +28,7 @@ To deploy the Atlantis module, see [`Dockerfile`](https://github.com/runatlantis
### Important

- If you bring your own Docker image (not using any Atlantis image as base image), be sure to create an Atlantis user using a uid (user ID) of 100.
- As per Docker spec, the base image's `CMD` will be overridden when you define a new `ENTRYPOINT` through the `command` variable: <https://docs.docker.com/engine/reference/builder/#understand-how-cmd-and-entrypoint-interact>

## Configuring Atlantis

Expand All @@ -35,6 +42,9 @@ Use a wrapper Atlantis Docker image to set environment variables that contain se
- [**GitHub Actions**: pull secrets from Google Secret Manager](https://github.com/runatlantis/terraform-gce-atlantis/tree/master/examples/secure-env-vars/.github/workflows/docker-gcp-secrets.yaml)
- [**GitHub Actions**: use GitHub secrets](https://github.com/runatlantis/terraform-gce-atlantis/tree/master/examples/secure-env-vars/.github/workflows/docker-github-secrets.yaml)

You can export sensitive values in the [`custom-entrypoint.sh.tftpl`](custom-entrypoint.sh.tftpl) script, which will be executed as the container entrypoint.
This strategy allow us to use the base Atlantis image, and to export environment variables that do not appear in the Console (e.g. ATLANTIS_GH_WEBHOOK_SECRET).

### Setting non-sensitive environment variables

Use the `var.env_vars` variable to set non-sensitive environment variables.
Expand Down
23 changes: 0 additions & 23 deletions examples/secure-env-vars/cloudbuild.yaml

This file was deleted.

43 changes: 43 additions & 0 deletions examples/secure-env-vars/custom-entrypoint.sh.tftpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/bin/bash

set -e

mkdir -p ${mount_folder}
chown 100 ${mount_folder}
cat <<'EOF' > "${mount_folder}/${entrypoint_filename}"
#!/bin/bash
set -e
ARCH="x86_64"
apk --no-cache upgrade && apk --no-cache add \
curl \
python3 \
py3-crcmod \
py3-openssl \
bash \
libc6-compat \
openssh-client \
git \
gnupg \
&& curl -O https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-cli-${cloud_sdk_version}-linux-$${ARCH}.tar.gz && \
tar xzf google-cloud-cli-${cloud_sdk_version}-linux-$${ARCH}.tar.gz && \
rm google-cloud-cli-${cloud_sdk_version}-linux-$${ARCH}.tar.gz
export PATH=$PATH:/google-cloud-sdk/bin
gcloud config set core/disable_usage_reporting true
gcloud config set component_manager/disable_update_check true
gcloud config set metrics/environment github_docker_image
gcloud --version
gcloud secrets versions access latest --secret="${app_key_secret_name}" > "${key_file_path}" && chmod 400 "${key_file_path}" && chown 100 "${key_file_path}"
export ATLANTIS_GH_APP_ID=$(gcloud secrets versions access latest --secret="${app_id_secret_name}")
export ATLANTIS_GH_APP_KEY_FILE="${key_file_path}"
export ATLANTIS_GH_WEBHOOK_SECRET=$(gcloud secrets versions access latest --secret="${webhook_secret_secret_name}")
# Call original atlantis entrypoint, passing along all arguments
docker-entrypoint.sh "$@"
EOF

chmod 0755 "${mount_folder}/${entrypoint_filename}"
31 changes: 25 additions & 6 deletions examples/secure-env-vars/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,16 @@ locals {
subnetwork = "<your-subnetwork>"
region = "<your-region>"
zone = "<your-zone>"
image = "<your-image>"
domain = "<example.com>"
managed_zone = "<your-managed-zone>"

github_repo_allow_list = "github.com/example/*"

secret_names = {
app_id = "<your_secret_name_for_app_id>"
app_key = "<your_secret_name_for_app_key>"
webhook = "<your_secret_name_for_webhook>"
}
}

# Create a service account and attach the required Cloud Logging permissions to it.
Expand All @@ -33,7 +38,6 @@ resource "google_project_iam_member" "atlantis_metric_writer" {
module "atlantis" {
source = "runatlantis/atlantis/gce"
name = "atlantis"
image = local.image # Your wrapper Atlantis Docker image
network = local.network
subnetwork = local.subnetwork
region = local.region
Expand All @@ -42,14 +46,29 @@ module "atlantis" {
email = google_service_account.atlantis.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 = local.github_repo_allow_list
ATLANTIS_ATLANTIS_URL = "https://${local.domain}"
ATLANTIS_REPO_ALLOWLIST = local.github_repo_allow_list
ATLANTIS_ATLANTIS_URL = "https://${local.domain}"
ATLANTIS_REPO_CONFIG_JSON = jsonencode(yamldecode(file("${path.module}/server-atlantis.yaml")))
ATLANTIS_WRITE_GIT_CREDS = "true"
}
domain = local.domain
project = local.project_id

image = "ghcr.io/runatlantis/atlantis:latest"
command = ["/home/atlantis/custom-entrypoint.sh"]
args = ["server"]

startup_script = templatefile("${path.module}/custom-entrypoint.sh.tftpl", {
cloud_sdk_version = "455.0.0"
app_key_secret_name = local.secret_names.app_key
app_id_secret_name = local.secret_names.app_id
webhook_secret_secret_name = local.secret_names.webhook
key_file_path = "/home/atlantis/gh_app_key.pem"
mount_folder = "/mnt/disks/gce-containers-mounts/gce-persistent-disks/atlantis-disk-0"
entrypoint_filename = "custom-entrypoint.sh"
})
}

# As your DNS records might be managed at another registrar's site, we create the DNS record outside of the module.
Expand Down
7 changes: 7 additions & 0 deletions examples/secure-env-vars/server-atlantis.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
repos:
- id: /.*/
apply_requirements: [mergeable]
allowed_overrides: [apply_requirements, workflow]
allow_custom_workflows: true
delete_source_branch_on_merge: true

0 comments on commit 6b73685

Please sign in to comment.