From 6fb6b0c33f7685244492a67d7a77e6049d6a187c Mon Sep 17 00:00:00 2001 From: "Chinmay D. Pai" Date: Tue, 12 Dec 2023 13:27:32 +0530 Subject: [PATCH 1/2] feat: add support to enable mTLS * adds a variable: `enable_tls` on both client and server to enable mTLS config * adds a variable: `tls_certificates` that takes base64 encoded certificate files for `ca_file`, `cert_file`, `key_file` * adds variables: `tls_http_enable` and `tls_rpc_enable` to manually enable TLS for HTTP (default: `false`) and RPC (default: `true`). The default values enable intra-cluster mTLS while allowing end user to access Nomad using CLI without requiring the TLS certificates Right now there's no way to verify if the variables are actually set, since terraform does not support validation based on other variable values. Signed-off-by: Chinmay D. Pai --- modules/nomad-clients/ec2.tf | 4 +++ modules/nomad-clients/launch_template.tf | 4 +++ .../scripts/setup_client.tftpl.sh | 30 +++++++++++++++++ modules/nomad-clients/variables.tf | 32 +++++++++++++++++++ modules/nomad-servers/launch_template.tf | 4 +++ .../scripts/setup_server.tftpl.sh | 30 +++++++++++++++++ modules/nomad-servers/variables.tf | 32 +++++++++++++++++++ 7 files changed, 136 insertions(+) diff --git a/modules/nomad-clients/ec2.tf b/modules/nomad-clients/ec2.tf index 62de02e..925bb92 100644 --- a/modules/nomad-clients/ec2.tf +++ b/modules/nomad-clients/ec2.tf @@ -31,6 +31,10 @@ resource "aws_instance" "nomad_client" { user_data_base64 = base64encode(templatefile("${path.module}/scripts/setup_client.tftpl.sh", { route_53_resolver_address = var.route_53_resolver_address enable_docker_plugin = var.enable_docker_plugin + enable_tls = var.enable_tls + tls_certificates = var.tls_certificates + tls_http_enable = var.tls_http_enable + tls_rpc_enable = var.tls_rpc_enable nomad_join_tag_key = "nomad_ec2_join" nomad_join_tag_value = var.nomad_join_tag_value nomad_client_cfg = templatefile("${path.module}/templates/nomad.tftpl", { diff --git a/modules/nomad-clients/launch_template.tf b/modules/nomad-clients/launch_template.tf index 1db3958..495ce87 100644 --- a/modules/nomad-clients/launch_template.tf +++ b/modules/nomad-clients/launch_template.tf @@ -12,6 +12,10 @@ resource "aws_launch_template" "nomad_client" { user_data = base64encode(templatefile("${path.module}/scripts/setup_client.tftpl.sh", { route_53_resolver_address = var.route_53_resolver_address enable_docker_plugin = var.enable_docker_plugin + enable_tls = var.enable_tls + tls_certificates = var.tls_certificates + tls_http_enable = var.tls_http_enable + tls_rpc_enable = var.tls_rpc_enable nomad_join_tag_key = "nomad_ec2_join" nomad_join_tag_value = var.nomad_join_tag_value nomad_client_cfg = templatefile("${path.module}/templates/nomad.tftpl", { diff --git a/modules/nomad-clients/scripts/setup_client.tftpl.sh b/modules/nomad-clients/scripts/setup_client.tftpl.sh index 7c041d4..d8a3aca 100644 --- a/modules/nomad-clients/scripts/setup_client.tftpl.sh +++ b/modules/nomad-clients/scripts/setup_client.tftpl.sh @@ -180,6 +180,31 @@ plugin "docker" { EOF } +add_tls_to_nomad() { + cat </etc/nomad.d/nomad-agent-ca.pem + ${base64decode(tls_certificates.ca_file)} +EOF + cat </etc/nomad.d/global-client-nomad.pem + ${base64decode(tls_certificates.cert_file)} +EOF + cat </etc/nomad.d/global-client-nomad-key.pem + ${base64decode(tls_certificates.key_file)} +EOF + cat <>/etc/nomad.d/tls.hcl +tls { + http = ${tls_http_enable} + rpc = ${tls_rpc_enable} + + ca_file = "nomad-agent-ca.pem" + cert_file = "global-client-nomad.pem" + key_file = "global-client-nomad-key.pem" + + verify_server_hostname = true + verify_https_client = true +} +EOF +} + log "INFO" "Fetching EC2 Tags from AWS" store_tags @@ -197,6 +222,11 @@ log "INFO" "Adding docker config to Nomad" add_docker_to_nomad %{ endif } +%{ if enable_tls } +log "INFO" "Enabling TLS for Nomad Client" +add_tls_to_nomad +%{ endif } + log "INFO" "Starting Nomad service" start_nomad diff --git a/modules/nomad-clients/variables.tf b/modules/nomad-clients/variables.tf index 2a34c8e..33d9884 100644 --- a/modules/nomad-clients/variables.tf +++ b/modules/nomad-clients/variables.tf @@ -70,6 +70,38 @@ variable "enable_docker_plugin" { default = true } +variable "enable_tls" { + description = "Whether to enable TLS on client nodes" + type = bool + default = false +} + +variable "tls_certificates" { + description = "Base64 encoded certificate files to use for Nomad Client TLS" + type = object({ + ca_file = string + cert_file = string + key_file = string + }) + default = { + ca_file = "" + cert_file = "" + key_file = "" + } +} + +variable "tls_http_enable" { + description = "Enable TLS over HTTP for Nomad Client. Setting this option requires the end-user to set NOMAD_TLS* variables while accessing the CLI" + type = bool + default = false +} + +variable "tls_rpc_enable" { + description = "Enable TLS over RPC for Nomad Clients. This is required for intra-client mTLS." + type = bool + default = true +} + variable "iam_instance_profile" { description = "Name of the existing IAM Instance Profile to use" type = string diff --git a/modules/nomad-servers/launch_template.tf b/modules/nomad-servers/launch_template.tf index e1c2498..75c7010 100644 --- a/modules/nomad-servers/launch_template.tf +++ b/modules/nomad-servers/launch_template.tf @@ -11,6 +11,10 @@ resource "aws_launch_template" "nomad_server" { user_data = base64encode(templatefile("${path.module}/scripts/setup_server.tftpl.sh", { nomad_acl_bootstrap_token = var.nomad_acl_bootstrap_token nomad_acl_enable = var.nomad_acl_enable + enable_tls = var.enable_tls + tls_certificates = var.tls_certificates + tls_http_enable = var.tls_http_enable + tls_rpc_enable = var.tls_rpc_enable nomad_server_cfg = templatefile("${path.module}/templates/nomad.tftpl", { nomad_dc = var.cluster_name aws_region = var.aws_region diff --git a/modules/nomad-servers/scripts/setup_server.tftpl.sh b/modules/nomad-servers/scripts/setup_server.tftpl.sh index 84619ef..61b2bbb 100644 --- a/modules/nomad-servers/scripts/setup_server.tftpl.sh +++ b/modules/nomad-servers/scripts/setup_server.tftpl.sh @@ -116,6 +116,31 @@ wait_for_leader() { return 1 } +add_tls_to_nomad() { + cat </etc/nomad.d/nomad-agent-ca.pem + ${base64decode(tls_certificates.ca_file)} +EOF + cat </etc/nomad.d/global-server-nomad.pem + ${base64decode(tls_certificates.cert_file)} +EOF + cat </etc/nomad.d/global-server-nomad-key.pem + ${base64decode(tls_certificates.key_file)} +EOF + cat <>/etc/nomad.d/tls.hcl +tls { + http = ${tls_http_enable} + rpc = ${tls_rpc_enable} + + ca_file = "nomad-agent-ca.pem" + cert_file = "global-server-nomad.pem" + key_file = "global-server-nomad-key.pem" + + verify_server_hostname = true + verify_https_client = true +} +EOF +} + bootstrap_acl() { # Get the IP address of this node. local ip_address @@ -155,6 +180,11 @@ start_nomad log "INFO" "Waiting for Nomad to be ready" wait_for_leader +%{ if enable_tls } +log "INFO" "Enabling TLS for Nomad Server" +add_tls_to_nomad +%{ endif } + %{ if nomad_acl_enable } log "INFO" "Bootstrapping ACL for Nomad" bootstrap_acl diff --git a/modules/nomad-servers/variables.tf b/modules/nomad-servers/variables.tf index 25a7aa1..f64e599 100644 --- a/modules/nomad-servers/variables.tf +++ b/modules/nomad-servers/variables.tf @@ -81,6 +81,38 @@ variable "ebs_encryption" { default = true } +variable "enable_tls" { + description = "Whether to enable TLS on client nodes" + type = bool + default = false +} + +variable "tls_certificates" { + description = "Base64 encoded certificate files to use for Nomad Server TLS" + type = object({ + ca_file = string + cert_file = string + key_file = string + }) + default = { + ca_file = "" + cert_file = "" + key_file = "" + } +} + +variable "tls_http_enable" { + description = "Enable TLS over HTTP for Nomad Server. Setting this option requires the end-user to set NOMAD_TLS* variables while accessing the CLI" + type = bool + default = false +} + +variable "tls_rpc_enable" { + description = "Enable TLS over RPC for Nomad CLI. This is required for intra-client mTLS." + type = bool + default = true +} + variable "instance_count" { description = "Number of Nomad server instances to run" type = number From e0e700049a1698b50553abaa1f7377e083e29d29 Mon Sep 17 00:00:00 2001 From: "Chinmay D. Pai" Date: Tue, 12 Dec 2023 13:43:32 +0530 Subject: [PATCH 2/2] chore: set verify_https_client based on tls_http_enable this ensures that if tls over http is disabled, then the end users are not required to produce TLS certificates for accessing nomad cluster using CLI Signed-off-by: Chinmay D. Pai --- modules/nomad-clients/scripts/setup_client.tftpl.sh | 2 +- modules/nomad-servers/scripts/setup_server.tftpl.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/nomad-clients/scripts/setup_client.tftpl.sh b/modules/nomad-clients/scripts/setup_client.tftpl.sh index d8a3aca..7feef53 100644 --- a/modules/nomad-clients/scripts/setup_client.tftpl.sh +++ b/modules/nomad-clients/scripts/setup_client.tftpl.sh @@ -200,7 +200,7 @@ tls { key_file = "global-client-nomad-key.pem" verify_server_hostname = true - verify_https_client = true + verify_https_client = ${tls_http_enable} } EOF } diff --git a/modules/nomad-servers/scripts/setup_server.tftpl.sh b/modules/nomad-servers/scripts/setup_server.tftpl.sh index 61b2bbb..5c4898d 100644 --- a/modules/nomad-servers/scripts/setup_server.tftpl.sh +++ b/modules/nomad-servers/scripts/setup_server.tftpl.sh @@ -136,7 +136,7 @@ tls { key_file = "global-server-nomad-key.pem" verify_server_hostname = true - verify_https_client = true + verify_https_client = ${tls_http_enable} } EOF }