Skip to content

Commit

Permalink
Merge pull request #1 from cruxstack/dev
Browse files Browse the repository at this point in the history
feat: add initial project source
  • Loading branch information
sgtoj authored Aug 3, 2023
2 parents 721eeba + 1ff18fe commit c122c3d
Show file tree
Hide file tree
Showing 23 changed files with 2,374 additions and 22 deletions.
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ following tools:
1. Clone and open this repository:

```bash
git clone https://github.com/sgtoj/terraform-aws-teleport-cluster.git
git clone https://github.com/cruxstack/terraform-aws-teleport-cluster.git
code terraform-aws-teleport-cluster
```

Expand Down
71 changes: 53 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,43 +1,78 @@
# Terraform Module: AWS Teleport Cluster
# Terraform Module: Teleport Cluster

This project is under development. See `dev` branch for latest activity.
This Terraform module deploys a Teleport cluster in high availability (HA)
configuration. [Teleport](https://github.com/gravitational/teleport) is a modern
zero-trust solution by Gravitational.

## Prerequisites
### Features

- Terraform v0.13.0 or newer
- An AWS account
- **High Availability**: Deploys Teleport in a highly available configuration to
ensure uninterrupted access.
- **Managed Upgrades**: Supports controlled upgrades to new versions of
Teleport.
- **Secure**: Uses AWS Key Management Service (KMS) to secure sensitive data.
- **Scalable**: Can handle growth in your user base and infrastructure without a
corresponding increase in complexity.
- **Integrated**: Works well with your existing infrastructure by following
CloudPosse's context and labeling patterns.

## Usage

Deploy it using the block below. For the first time deployments, it make take 10
minutes before the web portal is available.

```hcl
```hcl
module "teleport_cluster" {
source = "cruxstack/teleport-cluster/aws"
version = "x.x.x"
# TBD
teleport_letsencrypt_email = "[email protected]"
teleport_runtime_version = "10.3.15"
dns_parent_zone_id = Z0000000000000000000
dns_parent_zone_name = demo.example.com
vpc_id = "vpc-00000000000000"
vpc_subnet_ids = ["subnet-00000000000000", "subnet-11111111111111111", "subnet-22222222222222222"]
vpc_public_subnet_ids = ["subnet-33333333333333", "subnet-44444444444444444", "subnet-55555555555555555"]
teleport_setup_mode = false
}
```

## Requirements

- Terraform 0.13.0 or later
- AWS provider

## Inputs

In addition to the variables documented below, this module includes several
other optional variables (e.g., `name`, `tags`, etc.) provided by the
`cloudposse/label/null` module. Please refer to the [`cloudposse/label` documentation](https://registry.terraform.io/modules/cloudposse/label/null/latest) for more details on these variables.

| Name | Description | Type | Default | Required |
|-------------|-------------|:------:|:-------:|:--------:|
| `placehold` | N/A | string | null | No |
| Name | Description | Type | Default | Required |
|------------------------------|-------------------------------------------------------------------------------------------------------------------|----------------|---------|:--------:|
| `teleport_runtime_version` | The runtime version of Teleport. | `string` | n/a | yes |
| `teleport_letsencrypt_email` | The email address to use for Let's Encrypt. | `string` | n/a | yes |
| `teleport_setup_mode` | Toggle Teleport setup mode. | `bool` | `true` | no |
| `teleport_experimental_mode` | Toggle Teleport experimental mode. | `bool` | `false` | no |
| `instance_config` | Configuration for the instances. Each type (`auth`, `node`, `proxy`) contains an object with `count` and `sizes`. | `object` | `{}` | no |
| `artifacts_bucket_name` | The name of the S3 bucket for artifacts. | `string` | `""` | no |
| `logs_bucket_name` | The name of the S3 bucket for logs. | `string` | `""` | no |
| `dns_parent_zone_id` | The ID of the parent DNS zone. | `string` | n/a | yes |
| `dns_parent_zone_name` | The name of the parent DNS zone. | `string` | n/a | yes |
| `vpc_id` | The ID of the VPC to deploy resources into. | `string` | n/a | yes |
| `vpc_private_subnet_ids` | The IDs of the private subnets in the VPC to deploy resources into. | `list(string)` | n/a | yes |
| `vpc_public_subnet_ids` | The IDs of the public subnets in the VPC to deploy resources into. | `list(string)` | n/a | yes |
| `aws_region_name` | The name of the AWS region. | `string` | `""` | no |
| `aws_account_id` | The ID of the AWS account. | `string` | `""` | no |
| `aws_kv_namespace` | The namespace or prefix for AWS SSM parameters and similar resources. | `string` | `""` | no |

## Outputs
### Outputs

| Name | Description |
|-------------|-------------|
| `placehold` | N/A |
| Name | Description |
|-------------------------|------------------------------------------------------------------|
| `teleport_dns_name` | The DNS name of the Teleport service. |
| `teleport_auth_config` | The configuration details for the Teleport auth service. |
| `teleport_node_config` | The configuration details for the Teleport node service. |
| `teleport_proxy_config` | The configuration details for the Teleport proxy service. |
| `security_group_id` | The ID of the security group created for the Teleport service. |
| `security_group_name` | The name of the security group created for the Teleport service. |

## Contributing

Expand Down
14 changes: 14 additions & 0 deletions assets/image-files/teleport-all-pre-start
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/bash
# shellcheck disable=SC1091
set -e -x

source "/etc/teleport.d/conf"

# copy certificates into place
/bin/aws s3 sync "s3://${TELEPORT_S3_BUCKET}/live/${TELEPORT_DOMAIN_NAME}" /var/lib/teleport

# disable influxdb
systemctl stop telegraf
systemctl stop influxdb
systemctl disable telegraf
systemctl disable influxdb
77 changes: 77 additions & 0 deletions assets/image-files/teleport-generate-config
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#!/bin/bash
# shellcheck disable=SC1091,SC2002
set -e -o pipefail

TELEPORT_CONFIG_TEMPLATE_PATH=/etc/teleport.d/teleport.tmpl.yaml
TELEPORT_CONFIG_PATH=/etc/teleport.yaml

# ================================================================= function ===

get_aws_metadata() {
REQUEST_PATH="${1}"
IMDS_TOKEN=$(curl -m5 -sS -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 300")
curl -m5 -sS -H "\"X-aws-ec2-metadata-token: ${IMDS_TOKEN}\"" "http://169.254.169.254/latest/${REQUEST_PATH}" 2>/dev/null
}

# =================================================================== script ===

# ------------------------------------------------------------------- config ---

if getent passwd teleport >/dev/null 2>&1 && getent group adm >/dev/null 2>&1; then
if [ ! -d /var/lib/teleport ]; then
mkdir -p /var/lib/teleport
fi
chown -R teleport:adm /var/lib/teleport
fi

source "/etc/teleport.d/conf"

echo "${TELEPORT_ROLE}" >> "/etc/teleport.d/role.${TELEPORT_ROLE}"

INSTANCE_HOSTNAME=$(get_aws_metadata "meta-data/local-hostname")
INSTANCE_PRIVATE_IP=$(get_aws_metadata "meta-data/local-ipv4")

export TELEPORT_NODENAME=${INSTANCE_HOSTNAME}
export TELEPORT_ADVERTISE_IP=${INSTANCE_PRIVATE_IP}

cat "$TELEPORT_CONFIG_TEMPLATE_PATH" | envsubst > "${TELEPORT_CONFIG_PATH}"

chmod 664 "${TELEPORT_CONFIG_PATH}"
if getent passwd teleport >/dev/null 2>&1 && getent group adm >/dev/null 2>&1; then
chown teleport:adm ${TELEPORT_CONFIG_PATH}
fi

# ----------------------------------------------------------------- services ---

if [[ "${TELEPORT_ROLE}" == "auth" ]]; then

systemctl enable teleport-ssm-publish-tokens.service teleport-ssm-publish-tokens.timer
systemctl start teleport-ssm-publish-tokens.timer

systemctl enable teleport-get-cert.service teleport-get-cert.timer
systemctl enable teleport-renew-cert.service teleport-renew-cert.timer
systemctl start --no-block teleport-get-cert.timer
systemctl start --no-block teleport-renew-cert.timer

systemctl disable teleport.service
systemctl enable teleport-auth.service
systemctl start --no-block teleport-auth.service

elif [[ "${TELEPORT_ROLE}" == "proxy" ]]; then

systemctl enable teleport-check-cert.service teleport-check-cert.timer
systemctl start --no-block teleport-check-cert.timer

systemctl disable teleport.service
systemctl enable teleport-proxy.service
systemctl start --no-block teleport-proxy.service

elif [[ "${TELEPORT_ROLE}" == "node" ]]; then

systemctl disable teleport.service
systemctl enable teleport-node.service
systemctl start --no-block teleport-node.service

fi


30 changes: 30 additions & 0 deletions assets/image-files/teleport-ssm-publish-tokens
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/bin/bash
# shellcheck disable=SC1091,SC2002
set -e -o pipefail

source /etc/teleport.d/conf

TCTL=/usr/local/bin/tctl

PROXY_TOKEN=$(uuid -v4)
${TCTL} nodes add --roles=proxy --ttl=4h --token="${PROXY_TOKEN}"
aws ssm put-parameter --name "/teleport/${TELEPORT_CLUSTER_NAME}/tokens/proxy" --region "${EC2_REGION}" --type="SecureString" --value="${PROXY_TOKEN}" --overwrite

NODE_TOKEN=$(uuid -v4)
${TCTL} nodes add --roles=node,app,db --ttl=4h --token="${NODE_TOKEN}"
aws ssm put-parameter --name "/teleport/${TELEPORT_CLUSTER_NAME}/tokens/node" --region "${EC2_REGION}" --type="SecureString" --value="${NODE_TOKEN}" --overwrite

KUBE_TOKEN=$(uuid -v4)
${TCTL} nodes add --roles=kube --ttl=4h --token="${KUBE_TOKEN}"
aws ssm put-parameter --name "/teleport/${TELEPORT_CLUSTER_NAME}/tokens/kube" --region "${EC2_REGION}" --type="SecureString" --value="${KUBE_TOKEN}" --overwrite

APP_TOKEN=$(uuid -v4)
${TCTL} nodes add --roles=app --ttl=4h --token="${APP_TOKEN}"
aws ssm put-parameter --name "/teleport/${TELEPORT_CLUSTER_NAME}/tokens/app" --region "${EC2_REGION}" --type="SecureString" --value="${APP_TOKEN}" --overwrite

DATABASE_TOKEN=$(uuid -v4)
${TCTL} nodes add --roles=db --ttl=4h --token="${DATABASE_TOKEN}"
aws ssm put-parameter --name "/teleport/${TELEPORT_CLUSTER_NAME}/tokens/db" --region "${EC2_REGION}" --type="SecureString" --value="${DATABASE_TOKEN}" --overwrite

CA_PIN_HASH=$(tctl status | grep "CA pin" | awk '{print $3}')
aws ssm put-parameter --name "/teleport/${TELEPORT_CLUSTER_NAME}/ca-pin-hash" --region "${EC2_REGION}" --type="String" --value="${CA_PIN_HASH}" --overwrite
44 changes: 44 additions & 0 deletions examples/complete/README.md
Original file line number Diff line number Diff line change
@@ -1 +1,45 @@
# Example: Complete

This directory contains a complete example of how to use the Teleport Cluster
Terraform module in a real-world scenario.

## Overview

This example deploys a Teleport cluster with the following configuration:

- Teleport auth, node, and proxy services deployed in a high-availability (HA)
configuration.
- Deployment into a specified AWS VPC and subnets.

## Usage

To run this example, provide your own values for the following variables in a
`.terraform.tfvars` file:

```hcl
teleport_letsencrypt_email = "[email protected]"
dns_parent_zone_id = "your-dns-zone-id"
dns_parent_zone_name = "your-dns-zone-name"
vpc_id = "your-vpc-id"
vpc_private_subnet_ids = ["your-private-subnet-id"]
vpc_public_subnet_ids = ["your-public-subnet-id"]
```

## Inputs

| Name | Description | Type | Default | Required |
|----------------------------|---------------------------------------------------------------------|----------------|---------|:--------:|
| teleport_letsencrypt_email | The email address to use for Let's Encrypt. | `string` | n/a | yes |
| dns_parent_zone_id | The ID of the parent DNS zone. | `string` | n/a | yes |
| dns_parent_zone_name | The name of the parent DNS zone. | `string` | n/a | yes |
| vpc_id | The ID of the VPC to deploy resources into. | `string` | n/a | yes |
| vpc_private_subnet_ids | The IDs of the private subnets in the VPC to deploy resources into. | `list(string)` | n/a | yes |
| vpc_public_subnet_ids | The IDs of the public subnets in the VPC to deploy resources into. | `list(string)` | n/a | yes |

## Outputs

| Name | Description |
|-------------------------|---------------------------------------|
| teleport_dns_name | The DNS name of the Teleport service. |
| teleport_web_portal_url | The URL of the Teleport web portal. |
```
35 changes: 35 additions & 0 deletions examples/complete/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
locals {}

# ================================================================== example ===

module "teleport_cluster" {
source = "../.."

teleport_experimental_mode = true
teleport_letsencrypt_email = var.teleport_letsencrypt_email
teleport_runtime_version = var.teleport_runtime_version
dns_parent_zone_id = var.dns_parent_zone_id
dns_parent_zone_name = var.dns_parent_zone_name
vpc_id = var.vpc_id
vpc_private_subnet_ids = var.vpc_private_subnet_ids
vpc_public_subnet_ids = var.vpc_public_subnet_ids
teleport_setup_mode = false

context = module.example_label.context # not required
}

# ===================================================== supporting-resources ===

module "example_label" {
source = "cloudposse/label/null"
version = "0.25.0"

name = "tf-example-complete-${random_string.example_random_suffix.result}"
environment = "use1" # us-east-1
}

resource "random_string" "example_random_suffix" {
length = 6
special = false
upper = false
}
9 changes: 9 additions & 0 deletions examples/complete/output.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
output "teleport_dns_name" {
value = module.teleport_cluster.teleport_dns_name
description = "The DNS name of the Teleport service."
}

output "teleport_web_portal_url" {
value = "https://${module.teleport_cluster.teleport_dns_name}/web"
description = "The URL of the Teleport web portal."
}
35 changes: 35 additions & 0 deletions examples/complete/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
variable "teleport_runtime_version" {
type = string
description = "The runtime version of Teleport."
default = "10.3.15"
}

variable "teleport_letsencrypt_email" {
type = string
description = "The email address to use for Let's Encrypt."
}

variable "dns_parent_zone_id" {
type = string
description = "The ID of the parent DNS zone."
}

variable "dns_parent_zone_name" {
type = string
description = "The name of the parent DNS zone."
}

variable "vpc_id" {
type = string
description = "The ID of the VPC to deploy resources into."
}

variable "vpc_private_subnet_ids" {
type = list(string)
description = "The IDs of the private subnets in the VPC to deploy resources into."
}

variable "vpc_public_subnet_ids" {
type = list(string)
description = "The IDs of the public subnets in the VPC to deploy resources into."
}
Loading

0 comments on commit c122c3d

Please sign in to comment.