» Terraform Enterprise Active/Active

When your organization requires increased reliability or performance from Terraform Enterprise that your current single application instance cannot provide, it is time to scale to the Active/Active architecture.

However, the benefits that come with the Active/Active architecture need to be weighed against increasing operation complexity:

  • Hard requirement of a completely automated installation
  • Observability concerns when monitoring multiple instances
  • Custom automation required to manage the lifecycle of application nodes
  • New CLI-based commands vs Replicated Admin Console for administration

» Prerequisite

As mentioned above, the Active/Active architecture requires an existing automated installation of Terraform Enterprise that follows our best practices for deployment.

The primary requirement is an auto scaling group (or equivalent) with a single instance running Terraform Enterprise. This ASG should be behind a load balancer and can be exposed to the public Internet or not depending on your requirements. As mentioned earlier, the installation of the Terraform Enterprise application should be automated completely so that the auto scaling group can be scaled to zero and back to one without human intervention.

The application itself must be using External Services mode to connect to an external PostgreSQL database and object storage.

All admin and application configuration must be automated via your settings files and current with running configuration, i.e. it cannot have been altered via the Replicated Admin Console and not synced to the file. Specifically, you should be using the following configuration files:

  • /etc/replicated.conf - contains the configuration for the Replicated installer
  • /etc/ptfe-settings.json - contains the configuration for the TFE application

The requirement for automation is two-fold. First, the nodes need to be able to spin up and down without human intervention. More importantly though, you will need to ensure configuration is managed in this way going forward as the Replicated Admin Console will be disabled. The Replicated Admin Console does not function correctly when running multiple nodes and must not be used.

» Step 1: Prepare to Externalize Redis

» Prepare Network

There are new access requirements involving ingress and egress:

  • Port 6379 (or the port the external Redis will be configured to use) must be open between the nodes and the Redis service
  • Port 8201 must be open between the nodes to allow Vault to run in High Availability mode
  • Port 8800 should now be closed, as the Replicated Admin Console is no longer available when running multiple nodes

» Provision Redis

Externalizing Redis allows multiple active application nodes. Terraform Enterprise is validated to work with the managed Redis services from AWS, Azure, and GCP.

» Step 2: Update your Configuration File Templates

Before installing, you need to make changes to the templates for the configuration files mentioned earlier in the prerequisites.

» Update Installer Settings

The existing settings for the installer and infrastructure (replicated.conf) are still needed and require to be expanded. Please see documentation for the existing options here.

» Pin Your Version

To upgrade to the Active/Active functionality and for ongoing upgrades, you need to pin your installation to the appropriate release by setting the following:

Key Description Specific Format Required
ReleaseSequence Refers to a version of TFE (v202101-1) on a specific release channel (Active/Active) Yes, integer.

The following example pins the deployment to the the (v202101-1) release of TFE (which is the first to support multiple nodes):

{
  "ReleaseSequence" : 504
}

» Update Application Settings

The existing settings for the Terraform Enterprise application (ptfe-settings.json) are still needed and require to be expanded. Please see documentation for the existing options here.

» Enable Active/Active
Key Required Value Specific Format Required
enable_active_active “1” Yes, string.
{
  "enable_active_active" : {
    "value": "1"
  }
}

» Configure External Redis

The settings for the Terraform Enterprise application must also be expanded to support an external Redis instance:

Key Required Value Specific Format Required
redis_host Hostname of an external Redis instance which is resolvable from the TFE instance Yes, string.
redis_port Port number of your external Redis instance Yes, string.
redis_use_password_auth* Set to ”1”, if you are using a Redis service that requires a password. Yes, string.
redis_pass* Must be set to the password of an external Redis instance if the instance requires password authentication Yes, string.
redis_use_tls* Set to “1” if you are using a Redis service that requires TLS Yes, string.

* Fields marked with an asterisk are only necessary if your particular external Redis instance requires them.

For example:

{
  "redis_host" : {
    "value": "someredis.host.com"
  },
  "redis_port" : {
    "value": "6379"
  },
  "redis_use_password_auth" : {
    "value": "1"
  },
  "redis_pass" : {
    "value": "somepassword"
  },
  "redis_use_tls" : {
    "value": "1"
  }
}

» Add Encryption Password
Key Description Value can change between deployments? Specific Format Required
enc_password Used to encrypt sensitive data (docs) No. Changing will make decrypting existing data impossible. No
{
   "enc_password":{
      "value":"767fee4e6046de48943df2decc55f3cd"
   },
}

» Step 3: Connect to External Redis

Once you are prepared to include the modified configuration options in your configuration files, you must connect a single node to your newly provisioned Redis service by rebuilding your node instance with the new settings.

» Re-provision Terraform Enterprise Instance

Terminate the existing instance by scaling down to zero. Once terminated, you can scale back up to one instance using your revised configuration.

» Wait for Terraform Enterprise to Install

It can take up to 15 minutes for the node to provision and the TFE application to be installed and respond as healthy. You can monitor the status of the node provisioning by watching your auto scaling group in your cloud’s web console. To confirm the successful implementation of the TFE application you can SSH onto the node and run the following command to monitor the installation directly:

replicatedctl app status

Which will output something similar to the following:

[
    {
        "AppID": "218b78fa2bd6f0044c6a1010a51d5852",
        "Sequence": 504,
        "PatchSequence": 0,
        "State": "starting",
        "DesiredState": "started",
        "IsCancellable": false,
        "IsTransitioning": true,
        "LastModifiedAt": "2021-01-07T21:15:11.650385151Z"
    }
]

Installation is complete once isTransitioning is false and State is started.

See Active/Active Administration for more status and troubleshooting commands.

» Validate Application

With installation complete, it is time to validate the new Redis connection. Terraform Enterprise uses Redis both as a cache for API requests and a queue for long running jobs, e.g. Terraform Runs. Test the latter behavior by running real Terraform plans and applies through the system.

Once you are satisfied the application is running as expected, you can move on to step 4 to scale up to two nodes.

» Step 4: Scale to Two Nodes

You can now safely change the number of instances in your Auto Scaling Group ( or equivalent) to two.

» Disable the Replicated Admin Console

Before scaling beyond the first node, you must disable the Replicated Admin Console as mentioned earlier in this guide. This is done by adding the disable-replicated-ui flag as a parameter when you call the install script, as such:

sudo bash ./install.sh disable-replicated-ui

Locate where the install.sh script is run as part of your provisioning/installation process and add the parameter. If there are other parameters on the same line, they should be left in place.

» Scale Down to Zero Nodes

Scale down to zero nodes to fully disable the admin dashboard. Once the existing instance has terminated...

» Scale Up to Two Nodes

Now that you have tested your external Redis connection change the min and max instance count of your Auto Scaling Group to two nodes.

» Wait for Terraform Enterprise to Install

You need to wait up to 15 minutes for the application to respond as healthy on both nodes. Monitor the status of the install with the same methods used previously for one node in Step 3.

» Validate Application

Finally, confirm the application is functioning as expected when running multiple nodes. Run Terraform plan and applies through the system (and any other tests specific to your environment) like you did to validate the application in Step 3.

Confirm the general functionality of the Terraform Enterprise UI to validate the tokens you added in Step 2 are set correctly. Browse the Run interface and your organization's private registry to confirm your application functions as expected.

» Appendix 1: AWS ElasticCache

The following example Terraform configuration shows how to configure a replication group for use with TFE:

In this example, the required variables are:

  • vpc_id is the ID of VPC where TFE application will be deployed
  • subnet_ids are the IDs of Subnets within the VPC to use for the ElastiCache Subnet Group
  • security_group_ids are the IDs of Security Groups within the VPC that will be attached to TFE instances for Redis ingress
  • availability_zones are the zones within the VPC to deploy the ElastiCache setup to
resource "aws_elasticache_subnet_group" "tfe" {
  name       = "tfe-test-elasticache"
  subnet_ids = var.subnet_ids
}

resource "aws_security_group" "redis_ingress" {
  name        = "external-redis-ingress"
  description = "Allow traffic to redis from instances in the associated SGs"
  vpc_id      = var.vpc_id

  ingress {
    description     = "TFE ingress to redis"
    from_port       = 7480
    to_port         = 7480
    protocol        = "tcp"
    security_groups = var.security_group_ids
  }
}

resource "aws_elasticache_replication_group" "tfe" {
  node_type                     = "cache.m4.large"
  replication_group_id          = "tfe-test-redis"
  replication_group_description = "External Redis for TFE."

  apply_immediately          = true
  at_rest_encryption_enabled = true
  auth_token                 = random_pet.redis_password.id
  automatic_failover_enabled = true
  availability_zones         = var.availability_zones
  engine                     = "redis"
  engine_version             = "5.0.6"
  number_cache_clusters      = length(var.availability_zones)
  parameter_group_name       = "default.redis5.0"
  port                       = 7480
  security_group_ids         = [aws_security_group.redis_ingress.id]
  subnet_group_name          = aws_elasticache_subnet_group.tfe.name
  transit_encryption_enabled = true
}

» Appendix 2: GCP Memorystore for Redis

Requirements/Options:

  • authorized_network - The network you wish to deploy the instance into. Internal testing was done using the same network TFE is deployed into. If a different network is used, the customer needs to ensure the two networks are open on port 6379.
  • memory_size_gb - How much memory to allocate to Redis. Initial testing was done with just 1gb configured. Larger deployments may require additional memory. (TFC uses an m4.large, which is just 6gb of memory, for reference.)
  • location_id - What region to deploy into - should be the same one TFE is deployed into. If Standard_HA tier is selected, an alternative_location_id will also need to be provided as a failover location.
  • redis_version - Both 4.0 and 5.0 work without issue but 5.0 is recommended

The default example provided on the provider page can be used to deploy memorystore here. The host output of the resource can then be provided to the terraform module in order to configure connectivity.

You may consider using other options in the configuration depending on your requirements, such as including the auth_enabled flag set to true, which must then be accompanied by including an additional TFE configuration item called redis_password set to the value returned in the auth_string attribute from the memorystore resource.

» Appendix 3: Azure Cache for Redis

The minimum instance size for Redis to be used with TFE is 6 GiB. For Azure, this allows for some minimum configurations across the three tiers using Cache Names for their different Tiers. Our recommendations on cache sizing for Azure Cache for Redis is in the table below:

Basic Standard Premium
Cache Name C3 C0 P2

Make sure you configure the minimum TLS version to the TFE supported version of 1.2 as the Azure resource defaults to 1.0. The default port for Azure Cache for Redis is 6380 and will need to be modified in the Application Settings ptfe-replicated.conf in order for TFE to connect to Azure Cache for Redis.

The default example provided on the provider page can be used to deploy Azure Cache for Redis here. The outputs of the resource can then be provided to the Terraform module in order to configure connectivity