Skip to content

Commit

Permalink
Aurora Cluster support (#332)
Browse files Browse the repository at this point in the history
  • Loading branch information
sandrampeter authored Jun 4, 2024
1 parent 502906b commit 4e713e4
Show file tree
Hide file tree
Showing 16 changed files with 590 additions and 2 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ The resources created are:
We have included documentation and reference examples for additional common installation scenarios for TFE, as well as examples for supporting resources that lack official modules.

- [Example: Deploying with an existing, custom image](./examples/existing-image)
- [Example: Deploying with AWS Aurora RDS cluster instance](./examples/standalone-aurora)
- [Example: Deploying behind a proxy (coming soon...)](./examples/behind-proxy)
- [Example: Deploying into an existing private network (coming soon...)](./examples/existing-private-network)
- [Example: Deploying while managing DNS outside of AWS (coming soon...)](./examples/external-dns)
Expand Down
54 changes: 54 additions & 0 deletions examples/standalone-aurora/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Example: Standalone with AWS Aurora RDS

## About this example

This example for Terraform Enterprise creates a TFE installation with the
following traits:

- External mode
- a small VM machine type (m5.xlarge)
- Red Hat 7.9 as the VM image
- a publicly accessible HTTP load balancer with TLS termination
- an access key for accessing S3
- AWS Aurora RDS with one reader and writer instance.

## Pre-requisites

This test assumes the following resources already exist:

- Valid DNS Zone managed in Route53
- Valid AWS ACM certificate
- a TFE license on a filepath accessible by tests

## How to Use This Module

### Deployment

1. Read the entire [README.md](../../README.md) of the root module.
2. Ensure account meets module prerequisites from above.
3. Clone repository.
4. Change directory into desired example folder.
5. Create a local `terraform.auto.tfvars` file and instantiate the required inputs as required in the respective `./examples/standalone-rhel-aurora/variables.tf` including the path to the license under the `license_file` variable value.
6. Authenticate against the AWS provider. See [instructions](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#authentication-and-configuration).
7. Initialize terraform and apply the module configurations using the commands below:

NOTE: `terraform plan` will print out the execution plan which describes the actions Terraform will take in order to build your infrastructure to match the module configuration. If anything in the plan seems incorrect or dangerous, it is safe to abort here and not proceed to `terraform apply`.

```
terraform init
terraform plan
terraform apply
```
## Post-deployment Tasks
The build should take approximately 10-15 minutes to deploy. Once the module has completed, give the platform another 10 minutes or so prior to attempting to interact with it in order for all containers to start up.
Unless amended, this example will not create an initial admin user using the IACT, but it does output the URL for your convenience. Follow the advice in this document to create the initial admin user, and log into the system using this user in order to configure it for use.
### Connecting to the TFE Application
1. Navigate to the URL supplied via the `login_url` Terraform output. (It may take several minutes for this to be available after initial deployment. You may monitor the progress of cloud init if desired on one of the instances)
2. Enter a `username`, `email`, and `password` for the initial user.
3. Click `Create an account`.
4. After the initial user is created you may access the TFE Application normally using the URL supplied via `login_url` Terraform output.
18 changes: 18 additions & 0 deletions examples/standalone-aurora/data.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0

data "aws_ami" "ubuntu" {
most_recent = true

filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
}

filter {
name = "virtualization-type"
values = ["hvm"]
}

owners = ["099720109477"] # Canonical
}
7 changes: 7 additions & 0 deletions examples/standalone-aurora/locals.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0

locals {
friendly_name_prefix = random_string.friendly_name.id
network_private_subnet_cidrs = ["10.0.32.0/20", "10.0.48.0/20", "10.0.112.0/20"]
}
65 changes: 65 additions & 0 deletions examples/standalone-aurora/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0

# Random string to prepend resources
# ----------------------------------
resource "random_string" "friendly_name" {
length = 4
upper = false # Some AWS resources do not accept uppercase characters.
numeric = false
special = false
}

# Store TFE License as secret
# ---------------------------
module "secrets" {
source = "../../fixtures/secrets"
tfe_license = {
name = "${local.friendly_name_prefix}-tfe-license"
path = var.license_file
}
}

# Key Management Service
# ----------------------
module "kms" {
source = "../../fixtures/kms"
key_alias = "${local.friendly_name_prefix}-key"
}

# Standalone with Aurora database
# -------------------------------
module "standalone_aurora" {
source = "../../"

acm_certificate_arn = var.acm_certificate_arn
domain_name = var.domain_name
distribution = "ubuntu"
friendly_name_prefix = local.friendly_name_prefix
tfe_license_secret_id = module.secrets.tfe_license_secret_id

# Standalone, Aurora Database Example
enable_aurora = true
aurora_cluster_instance_replica_count = var.aurora_cluster_instance_replica_count
aurora_cluster_instance_enable_single = var.aurora_cluster_instance_enable_single
aurora_db_password = var.aurora_db_password
aurora_db_username = var.aurora_db_username

ami_id = data.aws_ami.ubuntu.id
bypass_preflight_checks = true
health_check_grace_period = 3000
iact_subnet_list = ["0.0.0.0/0"]
iam_role_policy_arns = ["arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore", "arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess"]
instance_type = "m5.4xlarge"
kms_key_arn = module.kms.key
load_balancing_scheme = "PUBLIC"
network_private_subnet_cidrs = local.network_private_subnet_cidrs
node_count = 1
operational_mode = "external"
redis_encryption_at_rest = false
redis_encryption_in_transit = true
redis_use_password_auth = true
tfe_subdomain = local.friendly_name_prefix
vm_certificate_secret_id = var.certificate_pem_secret_id
vm_key_secret_id = var.private_key_pem_secret_id
}
23 changes: 23 additions & 0 deletions examples/standalone-aurora/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0

output "login_url" {
value = module.standalone_aurora.tfe_url
description = "The URL to the TFE application."
}

output "tfe_console_url" {
value = "${module.standalone_aurora.tfe_url}:8800"
description = "Terraform Enterprise Console URL"
}

output "ptfe_health_check" {
value = "${module.standalone_aurora.tfe_url}/_health_check"
description = "The URL with path to access the TFE instance health check."
}

output "replicated_console_password" {
value = module.standalone_aurora.replicated_dashboard_password
description = "The password for the TFE console"
sensitive = true
}
9 changes: 9 additions & 0 deletions examples/standalone-aurora/terraform.tfvars.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
acm_certificate_arn = "arn:aws:acm:<region>:<account_id>:certificate/<certificate_name>"
certificate_pem_secret_id = "arn:aws:secretsmanager:<region>:<account_id>:secret:<secret_name>"
private_key_pem_secret_id = "arn:aws:secretsmanager:<region>:<account_id>:secret:<secret_name>"
domain_name = "my.domain.com"
license_file = "/files/license.rli"
aurora_cluster_instance_enable_single = "true"
aurora_cluster_instance_replica_count = 0
aurora_db_username = "hashicorp"
aurora_db_password = "xxxxxxxxx"
52 changes: 52 additions & 0 deletions examples/standalone-aurora/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0

variable "acm_certificate_arn" {
type = string
description = "The ARN of an existing ACM certificate."
}

variable "domain_name" {
type = string
description = "Domain for creating the Terraform Enterprise subdomain on."
}

variable "license_file" {
type = string
description = "The local path to the Terraform Enterprise license."
}

variable "private_key_pem_secret_id" {
type = string
description = "The secrets manager secret ID of the Base64 & PEM encoded TLS private key for tfe."
}

variable "certificate_pem_secret_id" {
type = string
description = "The secrets manager secret ID of the Base64 & PEM encoded TLS certificate for tfe."
}

variable "aurora_db_password" {
type = string
description = "PostgreSQL instance username. No special characters."
}

variable "aurora_db_username" {
type = string
description = "PostgreSQL instance username. No special characters."

validation {
condition = can(regex("^[a-zA-Z0-9]+$", var.aurora_db_username))
error_message = "The db_name must only contain alphanumeric characters."
}
}

variable "aurora_cluster_instance_enable_single" {
type = bool
description = "Creates only a single AWS RDS Aurora Cluster Instance."
}

variable "aurora_cluster_instance_replica_count" {
type = number
description = "Number of extra cluster instances to create. Should be 0 if `aurora_cluster_instance_enable_single` is set to `true`."
}
16 changes: 16 additions & 0 deletions examples/standalone-aurora/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0

terraform {
required_version = ">= 0.14"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
random = {
source = "hashicorp/random"
version = "~> 3.1"
}
}
}
13 changes: 11 additions & 2 deletions locals.tf
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ locals {
enable_airgap = var.airgap_url == null && var.tfe_license_bootstrap_airgap_package_path != null
enable_external = var.operational_mode == "external" || var.operational_mode == "active-active"
enable_disk = var.operational_mode == "disk"
enable_database_module = local.enable_external
enable_database_module = local.enable_external && var.enable_aurora == false
enable_object_storage_module = local.enable_external
enable_redis_module = var.operational_mode == "active-active"
fdo_operational_mode = var.operational_mode
Expand All @@ -19,7 +19,16 @@ locals {
network_public_subnets = var.deploy_vpc ? module.networking[0].network_public_subnets : var.network_public_subnets
network_private_subnet_cidrs = var.deploy_vpc ? module.networking[0].network_private_subnet_cidrs : var.network_private_subnet_cidrs

database = try(
database = var.enable_aurora ? try(
module.aurora_database[0],
{
name = null
password = null
endpoint = null
username = null
parameters = null
}
) : try(
module.database[0],
{
name = null
Expand Down
27 changes: 27 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,33 @@ module "database" {
kms_key_arn = local.kms_key_arn
}

# -----------------------------------------------------------------------------
# AWS Aurora PostreSQL Database Cluster
# -----------------------------------------------------------------------------
module "aurora_database" {
source = "./modules/aurora_database_cluster"
count = var.enable_aurora ? 1 : 0

engine_version = var.aurora_postgres_engine_version
db_size = var.aurora_db_size
aurora_db_username = var.aurora_db_username
aurora_db_password = var.aurora_db_password
aurora_cluster_instance_replica_count = var.aurora_cluster_instance_replica_count
aurora_cluster_instance_enable_single = var.aurora_cluster_instance_enable_single

db_backup_retention = var.aurora_db_backup_retention
db_backup_window = var.db_backup_window
db_name = var.db_name
db_parameters = var.db_parameters

friendly_name_prefix = var.friendly_name_prefix
network_id = local.network_id
network_private_subnet_cidrs = var.network_private_subnet_cidrs
network_subnets_private = local.network_private_subnets
tfe_instance_sg = module.vm.tfe_instance_sg
kms_key_id = local.kms_key_arn
}

# ------------------------------------------------------------------------------------
# Docker Compose File Config for TFE on instance(s) using Flexible Deployment Options
# ------------------------------------------------------------------------------------
Expand Down
Loading

0 comments on commit 4e713e4

Please sign in to comment.