Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[terraform] #874: terraform module for GCP #886

Merged
merged 40 commits into from
Jan 24, 2023
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
1a8dfa1
[terraform] #874: terraform module for gcp
barroco Nov 7, 2022
fd3f911
Add desired db versions as a variable
barroco Nov 8, 2022
7b01880
Format and simplify commons
barroco Nov 8, 2022
72fe8cc
Fix variable name consistency
barroco Nov 8, 2022
5648242
Default crdb_node_count to 3
barroco Nov 16, 2022
21626b9
Add required crdb_node_count to example definitions
barroco Nov 16, 2022
9eb2641
Add /build/workspace to the repository
barroco Nov 16, 2022
5493115
Add a note about GCP login
barroco Nov 16, 2022
f13ba23
Merge branch 'master' into 874-terraform-gke
barroco Dec 12, 2022
b1b99e6
Reorganize the files to use composition instead of encapsulation
barroco Dec 29, 2022
3a49f03
Move README temporarily to terraform-google-dss
barroco Dec 29, 2022
0a8b8ce
Refactor variables and use module composition for terraform-google-dss
barroco Dec 29, 2022
44dff5e
Add utility to manage variables of tf modules
barroco Dec 29, 2022
455da9d
Update variables and example.tfvars
barroco Dec 29, 2022
1828ec0
Format
barroco Dec 29, 2022
6746038
Fix examples
barroco Dec 29, 2022
18fe366
Remove redundant crdb_internal_addresses and adapt make-certs to hand…
barroco Dec 29, 2022
499d218
Fix link in readme
barroco Dec 29, 2022
14a4358
Fix link in readme
barroco Dec 29, 2022
b30c35e
Update documentation
barroco Dec 29, 2022
92f61c5
Fix link in readme
barroco Dec 29, 2022
a17c626
Update deploy/infrastructure/modules/terraform-google-dss/README.md
barroco Jan 18, 2023
4fa696e
Update deploy/infrastructure/modules/terraform-google-dss/README.md
barroco Jan 18, 2023
eddb767
Update deploy/infrastructure/modules/terraform-google-dss/README.md
barroco Jan 18, 2023
0e2b3f4
Apply suggestions from code review regarding default values
barroco Jan 18, 2023
063505f
Merge remote-tracking branch 'origin/master' into 874-terraform-gke
barroco Jan 18, 2023
724d8ca
Add missing cd as suggested in PR
barroco Jan 18, 2023
210cf52
Update deploy/infrastructure/modules/terraform-google-dss/terraform.e…
barroco Jan 18, 2023
27c27a4
Merge remote-tracking branch 'orbitalize/874-terraform-gke' into 874-…
barroco Jan 18, 2023
3efeac4
Address PR comments
barroco Jan 19, 2023
6133a33
TF format
barroco Jan 19, 2023
d22575d
Add latest value for image variable
barroco Jan 19, 2023
53664cd
Add latest value for image and revert default for kubernetes_namespace
barroco Jan 19, 2023
4c1fafa
Fail bash script in case of error
barroco Jan 19, 2023
4470768
Improve instructions
barroco Jan 19, 2023
18ad194
Expose cluster context as outpu
barroco Jan 19, 2023
b1fb933
Fix key path
barroco Jan 19, 2023
4a4b66b
Propose test key by default in example file
barroco Jan 19, 2023
fc06a69
Split step 3 in instructions as suggested in PR
barroco Jan 23, 2023
f3380c2
Clarify cluster context folder.
barroco Jan 23, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added build/workspace/.gitkeep
Empty file.
5 changes: 5 additions & 0 deletions deploy/infrastructure/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.terraform/
.terraform*
terraform.tfstate
terraform.tfstate.backup
personal/
11 changes: 11 additions & 0 deletions deploy/infrastructure/dependencies/terraform-commons-dss/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# terraform-commons-dss

This folder contains a terraform module which gathers resources required by all cloud providers.

It currently consists of the automatic generation of the tanka configuration to deploy
the Kubernetes resources as well as the scripts required to generate the certificates
and operate the cluster.

## Configuration

See [variables.tf](variables.tf).
62 changes: 62 additions & 0 deletions deploy/infrastructure/dependencies/terraform-commons-dss/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
locals {
workspace_location = abspath("${path.module}/../../../../build/workspace/${var.kubernetes_context_name}")
}

resource "local_file" "tanka_config_main" {
content = templatefile("${path.module}/templates/main.jsonnet.tmp", {
root_path = path.module
VAR_NAMESPACE = var.kubernetes_namespace
VAR_CLUSTER_CONTEXT = var.kubernetes_context_name
VAR_ENABLE_SCD = var.enable_scd
VAR_CRDB_HOSTNAME_SUFFIX = var.crdb_hostname_suffix
VAR_CRDB_LOCALITY = var.crdb_locality
VAR_CRDB_NODE_IPS = join(",", [for i in var.crdb_internal_nodes[*].ip : "'${i}'"])
VAR_INGRESS_NAME = var.ip_gateway
VAR_CRDB_EXTERNAL_NODES = join(",", [for a in var.crdb_external_nodes : "'${a}'"])
VAR_STORAGE_CLASS = var.kubernetes_storage_class
VAR_DOCKER_IMAGE_NAME = var.image
VAR_APP_HOSTNAME = var.app_hostname
VAR_PUBLIC_KEY_PEM_PATH = var.authorization.public_key_pem_path != null ? var.authorization.public_key_pem_path : ""
VAR_JWKS_ENDPOINT = var.authorization.jwks != null ? var.authorization.jwks.endpoint : ""
VAR_JWKS_KEY_ID = var.authorization.jwks != null ? var.authorization.jwks.key_id : ""
VAR_DESIRED_RID_DB_VERSION = var.desired_rid_db_version
VAR_DESIRED_SCD_DB_VERSION = var.desired_scd_db_version
VAR_SHOULD_INIT = var.should_init
})
filename = "${local.workspace_location}/main.jsonnet"
}

resource "local_file" "tanka_config_spec" {
content = templatefile("${path.module}/templates/spec.json.tmp", {
root_path = path.module
namespace = var.kubernetes_namespace
cluster_context = var.kubernetes_context_name
api_server = var.kubernetes_api_endpoint
})
filename = "${local.workspace_location}/spec.json"
}

resource "local_file" "make_certs" {
content = templatefile("${path.module}/templates/make-certs.sh.tmp", {
cluster_context = var.kubernetes_context_name
namespace = var.kubernetes_namespace
node_address = join(" ", var.crdb_internal_nodes[*].dns)
joining_pool = length(var.crdb_external_nodes) > 0
})
filename = "${local.workspace_location}/make-certs.sh"
}

resource "local_file" "apply_certs" {
content = templatefile("${path.module}/templates/apply-certs.sh.tmp", {
cluster_context = var.kubernetes_context_name
namespace = var.kubernetes_namespace
})
filename = "${local.workspace_location}/apply-certs.sh"
}

resource "local_file" "get_credentials" {
content = templatefile("${path.module}/templates/get-credentials.sh.tmp", {
get_credentials_cmd = var.kubernetes_get_credentials_cmd
})
filename = "${local.workspace_location}/get-credentials.sh"
}
10 changes: 10 additions & 0 deletions deploy/infrastructure/dependencies/terraform-commons-dss/output.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
output "generated_files_location" {
value = <<-EOT
Generated files location:
- workspace: ${local.workspace_location}
- main.jsonnet: ${abspath(local_file.tanka_config_main.filename)}
- spec.json: ${abspath(local_file.tanka_config_spec.filename)}
- make-certs.sh: ${abspath(local_file.make_certs.filename)}
- apply-certs.sh: ${abspath(local_file.apply_certs.filename)}
EOT
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/usr/bin/env bash

# This file was automatically generated by terraform-commons-dss.
# Do not edit it directly.

set -eo pipefail

OS=$(uname)
if [[ "$OS" == "Darwin" ]]; then
# OSX uses BSD readlink
BASEDIR="$(dirname "$0")"
else
BASEDIR=$(readlink -e "$(dirname "$0")")
fi
cd "$BASEDIR/../.." || exit 1

./apply-certs.sh ${cluster_context} ${namespace}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/usr/bin/env bash

# This file was automatically generated by terraform-commons-dss.
# Do not edit it directly.

set -eo pipefail

OS=$(uname)
if [[ "$OS" == "Darwin" ]]; then
# OSX uses BSD readlink
BASEDIR="$(dirname "$0")"
else
BASEDIR=$(readlink -e "$(dirname "$0")")
fi
cd "$BASEDIR/../.." || exit 1

${get_credentials_cmd}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// This file was automatically generated by terraform-commons-dss.
// Do not edit it directly.

local dss = import '../../deploy/dss.libsonnet';
local metadataBase = import '../../deploy/metadata_base.libsonnet';

// All VAR_* values below must be replaced with appropriate values; see
// dss/build/README.md for more information.

local metadata = metadataBase {
namespace: '${VAR_NAMESPACE}',
clusterName: '${VAR_CLUSTER_CONTEXT}',
enable_istio: false,
single_cluster: false,
enableScd: ${VAR_ENABLE_SCD}, // <-- This boolean value is VAR_ENABLE_SCD
cockroach+: {
hostnameSuffix: '${VAR_CRDB_HOSTNAME_SUFFIX}',
locality: '${VAR_CRDB_LOCALITY}',
nodeIPs: [${VAR_CRDB_NODE_IPS}],
shouldInit: ${VAR_SHOULD_INIT},
JoinExisting: [${VAR_CRDB_EXTERNAL_NODES}],
storageClass: '${VAR_STORAGE_CLASS}',
},
backend+: {
ipName: '${VAR_INGRESS_NAME}',
image: '${VAR_DOCKER_IMAGE_NAME}',
pubKeys: ['${VAR_PUBLIC_KEY_PEM_PATH}'],
jwksEndpoint: '${VAR_JWKS_ENDPOINT}',
jwksKeyIds: ['${VAR_JWKS_KEY_ID}'],
hostname: '${VAR_APP_HOSTNAME}',
dumpRequests: true,
},
schema_manager+: {
image: '${VAR_DOCKER_IMAGE_NAME}',
desired_rid_db_version: '${VAR_DESIRED_RID_DB_VERSION}',
desired_scd_db_version: '${VAR_DESIRED_SCD_DB_VERSION}',
},
prometheus+: {
storageClass: '${VAR_STORAGE_CLASS}',
},
};

dss.all(metadata)
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/usr/bin/env bash

# This file was automatically generated by terraform-commons-dss.
# Do not edit it directly.

set -eo pipefail

%{ if joining_pool }
CA_CERT=$${1:?Please, provide the CA certificate of the pool to join as first argument. See /build/README.md for more details.}
CA_CERT_ARG=" --ca-cert-to-join $${CA_CERT}"
%{ else }
CA_CERT_ARG=""
%{ endif }

OS=$(uname)
if [[ "$OS" == "Darwin" ]]; then
# OSX uses BSD readlink
BASEDIR="$(dirname "$0")"
else
BASEDIR=$(readlink -e "$(dirname "$0")")
fi
cd "$BASEDIR/../.." || exit 1

python ./make-certs.py --cluster-context ${cluster_context} --namespace ${namespace} --node-address ${node_address}$${CA_CERT_ARG}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"apiVersion": "tanka.dev/v1alpha1",
"kind": "Environment",
"metadata": {
"name": "${cluster_context}"
},
"spec": {
"apiServer": "${api_server}",
"namespace": "${namespace}"
}
}
143 changes: 143 additions & 0 deletions deploy/infrastructure/dependencies/terraform-commons-dss/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
# This file has been automatically generated by /deploy/infrastructure/utils/generate_terraform_variables.py.
# Please do not modify manually.

variable "image" {
type = string
description = <<EOT
Full name of the docker image built in the section above. build.sh prints this name as
the last thing it does when run with DOCKER_URL set. It should look something like
gcr.io/your-project-id/dss:2020-07-01-46cae72cf if you built the image yourself as
documented in /build/README.md, or docker.io/interuss/dss.
EOT
default = "docker.io/interuss/dss:v0.6.0"
}

variable "authorization" {
type = object({
public_key_pem_path = optional(string)
jwks = optional(object({
endpoint = string
key_id = string
}))
})
description = <<-EOT
One of `public_key_pem_path` or `jwks` should be provided but not both.
- public_key_pem_path
If providing the access token public key via JWKS, do not provide this parameter.
If providing a .pem file directly as the public key to validate incoming access tokens, specify the name
of this .pem file here as /public-certs/YOUR-KEY-NAME.pem replacing YOUR-KEY-NAME as appropriate. For instance,
if using the provided us-demo.pem, use the path /public-certs/us-demo.pem. Note that your .pem file should built
in the docker image or mounted manually.
Example:
{
public_key_pem_path = "/public-certs/us-demo.pem"
}
- jwks
If providing a .pem file directly as the public key to validate incoming access tokens, do not provide this parameter.
- endpoint
If providing the access token public key via JWKS, specify the JWKS endpoint here.
Example: https://auth.example.com/.well-known/jwks.json
- key_id:
If providing the access token public key via JWKS, specify the kid (key ID) of they appropriate key in the JWKS file referenced above.
Example:
{
jwks = {
endpoint = "https://auth.example.com/.well-known/jwks.json"
key_id = "9C6DF78B-77A7-4E89-8990-E654841A7826"
}
}
EOT

validation {
condition = (var.authorization.jwks == null && var.authorization.public_key_pem_path != null) || (var.authorization.jwks != null && var.authorization.public_key_pem_path == null)
error_message = "Public key to validate incoming access tokens shall be provided exclusively either with a .pem file or via JWKS."
}
}

variable "enable_scd" {
type = bool
description = "Set this boolean true to enable ASTM strategic conflict detection functionality"
default = true
}

variable "should_init" {
type = bool
description = <<-EOT
Set to false if joining an existing pool, true if creating the first DSS instance
for a pool. When set true, this can initialize the data directories on your cluster,
and prevent you from joining an existing pool.
Example: true
EOT
default = false
}

variable "desired_rid_db_version" {
type = string
description = "Desired RID DB schema version"
default = "4.0.0"
}

variable "desired_scd_db_version" {
type = string
description = "Desired SCD DB schema version"
default = "3.1.0"
}

variable "crdb_locality" {
type = string
description = <<-EOT
Unique name for your DSS instance. Currently, we recommend "<ORG_NAME>_<CLUSTER_NAME>",
and the = character is not allowed. However, any unique (among all other participating
DSS instances) value is acceptable.
Example: <ORGNAME_CLUSTER_NAME>
EOT
}

variable "crdb_external_nodes" {
type = list(string)
description = <<-EOT
Fully-qualified domain name of existing CRDB nodes outside of the cluster if you are joining an existing pool.
EOT
default = []
}

variable "kubernetes_storage_class" {
type = string
description = <<-EOT
Kubernetes Storage Class to use for CockroachDB and Prometheus volumes. You can
check your cluster's possible values with kubectl get storageclass.
This value may be cloud provider specific.
Example for GCP: standard
EOT
}

variable "kubernetes_namespace" {
type = string
description = "Namespace where to deploy Kubernetes resources. Only default is supported at the moment."
default = "default"

# TODO: Adapt current deployment scripts in /build/deploy to support default is supported for the moment.
validation {
condition = var.kubernetes_namespace == "default"
error_message = "Only default namespace is supported at the moment"
}
}

variable "app_hostname" {
type = string
description = <<-EOT
Fully-qualified domain name of your HTTPS Gateway ingress endpoint.
Example: dss.example.com.
EOT
}

variable "crdb_hostname_suffix" {
type = string
description = <<-EOT
The domain name suffix shared by all of your CockroachDB nodes.
For instance, if your CRDB nodes were addressable at 0.db.example.com,
1.db.example.com and 2.db.example.com, then VAR_CRDB_HOSTNAME_SUFFIX would be db.example.com.
Example: db.example.com
EOT
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Variables used to interface with other modules of type terraform-*-kubernetes.

variable "kubernetes_cloud_provider_name" {
type = string
description = "Cloud provider name"
}

variable "kubernetes_get_credentials_cmd" {
type = string
description = "Command to get credentials to access the Kubernetes cluster"
}

variable "kubernetes_context_name" {
type = string
description = "Cluster context name used by kubectl to access the Kubernetes cluster"
}

variable "kubernetes_api_endpoint" {
type = string
description = "Kubernetes cluster API endpoint"
}

# Hostnames and DNS
variable "crdb_internal_nodes" {
type = list(object({
dns = string
ip = string
}))
description = "List of the IP addresses and related dns for the Cockroach DB nodes"
}

variable "ip_gateway" {
type = string
description = "IP of the gateway used by the DSS service"
}
Loading