Skip to content

runatlantis/terraform-gce-atlantis

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Atlantis on Google Compute Engine

Header

This Terraform module deploys various resources to run Atlantis on Google Compute Engine.

Feature highlights

  • Container-Optimized OS - Atlantis runs as a Docker container on a container optimized VM.

  • Managed Instance Group - The VM instance is part of a MIG (Managed Instance Group), this ensures that Atlantis is always up and running.

  • External HTTPS Load Balancer - A Layer 7 load balancer is created together with a managed SSL certificate for the provided domain.

  • Identity-Aware Proxy - The Atlantis UI can be protected by Google Cloud Identity-Aware Proxy, this adds an additional layer of security by requiring users to authenticate with their Google account.

  • Custom port for Atlantis - This module features the ability to run Atlantis on a custom port, simply set the ATLANTIS_PORT environment variable.

  • Separate Persistent Data Disk - The VM instance has a separate attached persistent data disk attached to it to ensure that Atlantis data is persisted and not lost if the VM is deleted or terminated.

  • Shielded VM - A Shielded VM is a VM that's hardened by a set of security controls that help defend against rootkits and bootkits. Using a Shielded VM helps protect enterprise workloads from threats like remote attacks, privilege escalation, and malicious insiders.

  • Cloud Armor - Use Google Cloud Armor security policies to protect the default backend service from distributed denial-of-service (DDoS) and other web-based attacks. Security policies can be configured manually, with configurable match conditions and actions in a security policy. Google Cloud Armor also features preconfigured security policies, which cover a variety of use cases.

  • Confidential VM - A Confidential VM is a type of Compute Engine VM that ensures that your data and applications stay private and encrypted even while in use. You can use a Confidential VM as part of your security strategy so you do not expose sensitive data or workloads during processing. Note that Confidential VM does not support live migration, so if this feature is enabled, onHostMaintenance will be set to TERMINATE.

Prerequisites

This module expects that you already own or create the below resources yourself.

  • Google network, subnetwork and a Cloud NAT
  • Service account
  • Domain

If you prefer an example that includes the above resources, see complete example.

Example Usage

Here are some examples to choose from. Look at the prerequisites above to find one that is appropriate for your configuration.

module "atlantis" {
  source  = "runatlantis/atlantis/gce"
  # insert the 7 required variables here
}

How to deploy

See main.tf and the server-atlantis.yaml.

Important

  • 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.

After it's successfully deployed

Once you're done, see Configuring Webhooks for Atlantis

Configuring Atlantis

Atlantis offers the ability to configure everything through environment variables.

The module exposes a variable: var.env_vars where you can pass any environment variable you want.

env_vars = {
  ATLANTIS_EXAMPLE = "example"
}

For an overview of all possible environment variables, see: Atlantis Server Configuration

Setting sensitive environment variables

See secured environment variables for an example on how to deal with sensitive values in environment variables.

Service Account

As Google recommends custom service accounts and permissions granted via IAM Roles. We advice that you bring your own service account.

Note that you must grant the relevant permissions to your service account yourself, e.g. Storage related permissions for the Terraform state bucket and other permissions in order to create resources through Terraform.

Permissions

The roles/logging.logWriter & roles/monitoring.metricWriter roles should be attached to the service account in order to write logs to Cloud Logging and ingest metric data into Cloud Monitoring.

See main.tf

DNS Record

This example uses Cloud DNS to add an A record containing the load balancer IP address. If you don't use Cloud DNS, please add the A record using the load balancer IP address on the platform where you've registered your domain.

It's a requirement to add the A record to the domain record set in order to sucessfully provision the certificate!

Example

If you use Cloud DNS and own a managed zone for your domain, use the IP address that's part of the module output to create the A record.

See main.tf

Identity-Aware Proxy

Google Cloud's Identity-Aware Proxy (IAP) is a service that can be used to secure the Atlantis UI by authenticating users with Google Accounts

Enabling IAP

To enable IAP, you will need to configure the OAuth Consent Screen and create OAuth credentials, as described in the Enabling IAP guide.

Once you have the OAuth credentials, you can set the iap variable to use them.

iap = {
  oauth2_client_id     = data.google_secret_manager_secret_version.atlantis_client_id.secret_data
  oauth2_client_secret = data.google_secret_manager_secret_version.atlantis_client_secret.secret_data
}

What's exactly protected?

With IAP enabled, all requests to Atlantis will be protected, except for those made to the /events path, which is used for webhooks between platforms such as GitHub and BitBucket.

Permissions

To grant a user access to your IAP-protected Atlantis deployment, you will need to give them the roles/iap.httpsResourceAccessor role.

resource "google_iap_web_iam_member" "member" {
  project = "<your-project-id>"
  role = "roles/iap.httpsResourceAccessor"
  member = "user:jane@example.com"
}

FAQ

When sending an HTTP request, I'm receiving an ERR_EMPTY_RESPONSE error

We expect you to use HTTPS because we are not routing or redirecting any HTTP requests.

My VM experienced an outage and is taking some time to restart

It may take up to three minutes for the Managed Instance Group to safely shut down and recreate the VM before it is considered healthy again.

Even though terraform apply worked correctly, I'm receiving an ERR_SSL_VERSION_OR_CIPHER_MISMATCH error

This error indicates that the Google Cloud Managed SSL certificate is not yet fully provisioned. If all configurations are correct, it may take up to 25 minutes for the certificate to be provisioned. You can check the status of the certificate in the Google Cloud Console.

Requirements

Name Version
terraform >= 0.13.0
cloudinit >=2.2.0
google >=4.79.0
google-beta >=4.79.0
random >=3.4.3

Providers

Name Version
cloudinit >=2.2.0
google >=4.79.0
google-beta >=4.79.0
random >=3.4.3

Modules

Name Source Version
container terraform-google-modules/container-vm/google 3.1.1

Resources

Name Type
google-beta_google_compute_instance_group_manager.default resource
google_compute_backend_service.default resource
google_compute_backend_service.iap resource
google_compute_firewall.lb_health_check resource
google_compute_global_address.default resource
google_compute_global_forwarding_rule.https resource
google_compute_health_check.default resource
google_compute_health_check.default_instance_group_manager resource
google_compute_instance_template.default resource
google_compute_managed_ssl_certificate.default resource
google_compute_route.public_internet resource
google_compute_target_https_proxy.default resource
google_compute_url_map.default resource
random_string.random resource
cloudinit_config.config data source
google_compute_image.cos data source
google_netblock_ip_ranges.this data source

Inputs

Name Description Type Default Required
block_project_ssh_keys_enabled Blocks the use of project-wide publich SSH keys bool false no
default_backend_security_policy Name of the security policy to apply to the default backend service string null no
disk_kms_key_self_link The self link of the encryption key that is stored in Google Cloud KMS string null no
domain Domain to associate Atlantis with and to request a managed SSL certificate for. Without https:// string n/a yes
enable_confidential_vm Enable Confidential VM. If true, on host maintenance will be set to TERMINATE bool false no
enable_oslogin Enables OS Login service on the VM bool false no
env_vars Key-value pairs representing environment variables and their respective values map(any) n/a yes
expose_metrics_publicly Exposes the /metrics endpoint publicly even if Atlantis is protected by IAP bool false no
google_logging_enabled Enable Google Cloud Logging bool true no
google_logging_use_fluentbit Enable Google Cloud Logging using Fluent Bit bool false no
google_monitoring_enabled Enable Google Cloud Monitoring bool true no
iap Settings for enabling Cloud Identity Aware Proxy to protect the Atlantis UI
object({
oauth2_client_id = string
oauth2_client_secret = string
})
null no
iap_backend_security_policy Name of the security policy to apply to the IAP backend service string null no
image Docker image. This is most often a reference to a container located in a container registry string "ghcr.io/runatlantis/atlantis:latest" no
labels Key-value pairs representing labels attaching to instance & instance template map(any) {} no
machine_image The machine image to create VMs with, if not specified, latest cos_cloud/cos_stable is used string null no
machine_type The machine type to run Atlantis on string "n2-standard-2" no
name Custom name that's used during resource creation string n/a yes
network Name of the network string n/a yes
persistent_disk_size_gb The size of the persistent disk that Atlantis uses to store its data on number 50 no
project The ID of the project in which the resource belongs string null no
region The region that resources should be created in string n/a yes
service_account Service account to attach to the instance running Atlantis
object({
email = string,
scopes = list(string)
})
{
"email": "",
"scopes": [
"cloud-platform"
]
}
no
shared_vpc Whether to deploy within a shared VPC
object({
host_project_id = string
})
null no
shielded_instance_config Shielded VM provides verifiable integrity to prevent against malware and rootkits
object({
enable_integrity_monitoring = optional(bool)
enable_vtpm = optional(bool)
enable_secure_boot = optional(bool)
})
{
"enable_integrity_monitoring": true,
"enable_secure_boot": true,
"enable_vtpm": true
}
no
spot_machine_enabled A Spot VM is discounted Compute Engine capacity that may be preemptively stopped or deleted by Compute Engine if the capacity is needed bool false no
ssl_policy The SSL policy name that the certificate must follow string null no
startup_script A startup script that runs during the boot cycle when you first launch an instance string null no
subnetwork Name of the subnetwork to attach a network interface to string n/a yes
tags Tags to attach to the instance running Atlantis list(string) [] no
zone The zone that instances should be created in string n/a yes

Outputs

Name Description
cos_image_id The unique identifier of the Container-Optimized OS image used to create the Compute Engine instance.
iap_backend_service_name Name of the optional IAP-enabled backend service
ip_address The IPv4 address of the load balancer
managed_ssl_certificate_certificate_id The unique identifier of the Google Managed SSL certificate
managed_ssl_certificate_expire_time Expire time of the Google Managed SSL certificate