Skip to content

Commit fb6ae51

Browse files
committed
feat: init commit
0 parents  commit fb6ae51

14 files changed

+1003
-0
lines changed

.github/.dependabot.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: "github-actions"
4+
directory: "/"
5+
schedule:
6+
interval: "daily"

.github/workflows/release.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: release
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
release:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- name: Checkout Code
16+
uses: actions/checkout@v3
17+
- name: Bump Version
18+
id: tag_version
19+
uses: mathieudutour/github-tag-action@v6.1
20+
with:
21+
github_token: ${{ secrets.GITHUB_TOKEN }}
22+
default_bump: minor
23+
custom_release_rules: bug:patch:Fixes,chore:patch:Chores,docs:patch:Documentation,feat:minor:Features,refactor:minor:Refactors,test:patch:Tests,ci:patch:Development,dev:patch:Development
24+
- name: Create Release
25+
uses: ncipollo/release-action@v1.12.0
26+
with:
27+
tag: ${{ steps.tag_version.outputs.new_tag }}
28+
name: ${{ steps.tag_version.outputs.new_tag }}
29+
body: ${{ steps.tag_version.outputs.changelog }}

.github/workflows/semantic-check.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
name: semantic-check
2+
on:
3+
pull_request_target:
4+
types:
5+
- opened
6+
- edited
7+
- synchronize
8+
9+
permissions:
10+
contents: read
11+
pull-requests: read
12+
13+
jobs:
14+
main:
15+
name: Semantic Commit Message Check
16+
runs-on: ubuntu-latest
17+
steps:
18+
- name: Checkout Code
19+
uses: actions/checkout@v3
20+
- uses: amannn/action-semantic-pull-request@v5.2.0
21+
name: Check PR for Semantic Commit Message
22+
env:
23+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
24+
with:
25+
requireScope: false
26+
validateSingleCommit: true

.github/workflows/test.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: test
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- main
7+
8+
jobs:
9+
test:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- name: Checkout Code
13+
uses: actions/checkout@v3
14+
- name: Terraform Setup
15+
run: |
16+
terraform init
17+
- name: Lint Terraform
18+
uses: reviewdog/action-tflint@master
19+
with:
20+
github_token: ${{ secrets.github_token }}
21+
filter_mode: "nofilter"

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 CruxStack LLC
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# terraform-aws-teleport-node
2+
3+
Provision a small, self-healing fleet of EC2 instances that automatically join
4+
an **existing Teleport Cloud** cluster. The nodes can run the Teleport **Node,
5+
App, or Database** services and implements AWS EC2 best practices.
6+
7+
---
8+
9+
## Features
10+
11+
* **One-Command Deploy** – Launches an Auto Scaling Group behind the scenes;
12+
nodes bootstrap themselves via cloud-init and join Teleport Cloud
13+
automatically.
14+
* **Always-latest Build** – Each instance queries the Teleport download
15+
endpoint and installs the newest stable Cloud release at boot.
16+
* **Spot-friendly** – Supports mixed-instance/spot policies for cost savings.
17+
* **Integrated Observability** – System, cloud-init and Teleport logs are
18+
streamed to a dedicated CloudWatch Log Group; optional SSM session
19+
transcripts to S3.
20+
* **Database Service Ready** – IAM & RDS/Redshift permissions wired in when
21+
`tp_config.db_service.enabled = true`, enabling discovery and IAM auth.
22+
* **Hygienic Networking & IAM** – No public IPs, IMDSv2 enforced, least-priv
23+
policies, single inbound rule limited to the SG itself for Teleport gossip.
24+
25+
---
26+
27+
## Usage
28+
29+
```hcl
30+
module "teleport_nodes" {
31+
source = "github.com/cruxstack/terraform-aws-teleport-node"
32+
version = "x.x.x"
33+
34+
tp_domain = "acme.teleport.sh"
35+
tp_join_config = {
36+
token_name = "iam-role"
37+
}
38+
39+
vpc_id = "vpc-1234567890abcdef"
40+
vpc_subnet_ids = ["subnet-1234abcd", "subnet-5678efgh"]
41+
}
42+
```
43+
44+
---
45+
46+
## Inputs
47+
In addition to the variables documented below, this module includes several
48+
other optional variables (e.g., `name`, `tags`, etc.) provided by the
49+
`cloudposse/label/null` module. Please refer to its [documentation](https://registry.terraform.io/modules/cloudposse/label/null/latest)
50+
for more details on these variables.
51+
52+
| Name | Description | Type | Default | Required |
53+
| ---------------------------------------- | --------------------------------------------------------------------------------------- | :-------------------: | :--------------------: | :------: |
54+
| `tp_domain` | Teleport Cloud cluster FQDN (e.g. `example.teleport.sh`). | `string` || **yes** |
55+
| `tp_join_config` | Join token config.<br>`token_name` (required) and optional `method` (`iam` \| `token`). | `object({...})` || **yes** |
56+
| `tp_edition` | Teleport edition (`cloud`, `ent`, …). | `string` | `"cloud"` | no |
57+
| `tp_config` | Extra Teleport service configuration (enable DB/App/SSH, label rules, etc.). | `object({...})` | `{}` | no |
58+
| `instance_capacity` | ASG desired/min/max. | `object({...})` | `{ min = 1, max = 3 }` | no |
59+
| `instance_types` | List of allowed instance types & weights. | `list(object({...}))` | see `variables.tf` | no |
60+
| `instance_key_name` | Existing EC2 key-pair name (ssh access). | `string` | `""` | no |
61+
| `instance_spot` | Spot settings (`enabled`, `allocation_strategy`). | `object({...})` | `{ enabled = true }` | no |
62+
| `logs_bucket_name` | S3 bucket for generic logs (unused by SSM). | `string` | `""` | no |
63+
| `ssm_sessions` | Toggle SSM logging and target bucket. | `object({...})` | `{ enabled = false }` | no |
64+
| `vpc_id` | Target VPC ID. | `string` || **yes** |
65+
| `vpc_subnet_ids` | Subnet IDs for the ASG. | `list(string)` | `[]` | **yes** |
66+
| `vpc_security_group_ids` | Extra SGs to attach. | `list(string)` | `[]` | no |
67+
| `experimental_mode` | Shorter CW log retention & zero-health refresh for dev. | `bool` | `false` | no |
68+
69+
---
70+
71+
## Outputs
72+
73+
| Name | Description |
74+
| --------------------- | ----------------------------------------------- |
75+
| `teleport_version` | The Teleport version installed on the nodes. |
76+
| `teleport_config` | Fully-rendered Teleport YAML that was injected. |
77+
| `security_group_id` | ID of the generated node SG. |
78+
| `security_group_name` | Name of the generated node SG. |
79+

assets/cloud-config.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#cloud-config
2+
packages:
3+
- amazon-cloudwatch-agent
4+
package_update: true
5+
package_upgrade: true
6+
write_files:
7+
- path: /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d/user.json
8+
content: ${cloudwatch_agent_config_encoded}
9+
encoding: base64
10+
permissions: "0644"

assets/cloudwatch-agent-config.json

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
{
2+
"agent": {
3+
"run_as_user": "cwagent"
4+
},
5+
"logs": {
6+
"logs_collected": {
7+
"files": {
8+
"collect_list": [
9+
{
10+
"file_path": "/opt/aws/amazon-cloudwatch-agent/logs/amazon-cloudwatch-agent.log",
11+
"log_group_name": "${log_group_name}",
12+
"log_stream_name": "/ec2/instance/{instance_id}/amazon-cloudwatch-agent.log",
13+
"timestamp_format": "%Y-%m-%dT%H:%M:%SZ"
14+
},
15+
{
16+
"file_path": "/var/log/dmesg",
17+
"log_group_name": "${log_group_name}",
18+
"log_stream_name": "/ec2/instance/{instance_id}/dmesg"
19+
},
20+
{
21+
"file_path": "/var/log/messages",
22+
"log_group_name": "${log_group_name}",
23+
"log_stream_name": "/ec2/instance/{instance_id}/messages",
24+
"timestamp_format": "%b %d %H:%M:%S"
25+
},
26+
{
27+
"file_path": "/var/log/cloud-init.log",
28+
"log_group_name": "${log_group_name}",
29+
"log_stream_name": "/ec2/instance/{instance_id}/cloud-init.log",
30+
"multi_line_start_pattern": "\\w+ \\d{2} \\d{2}:\\d{2}:\\d{2} cloud-init\\[[\\w]+]:",
31+
"timestamp_format": "%B %d %H:%M:%S",
32+
"timezone": "UTC"
33+
},
34+
{
35+
"file_path": "/var/log/cloud-init-output.log",
36+
"log_group_name": "${log_group_name}",
37+
"log_stream_name": "/ec2/instance/{instance_id}/cloud-init-output.log",
38+
"multi_line_start_pattern": "Cloud-init v. \\d+.\\d+-\\d+"
39+
},
40+
{
41+
"file_path": "/var/lib/teleport/teleport.log",
42+
"log_group_name": "${log_group_name}",
43+
"log_stream_name": "/ec2/instance/{instance_id}/teleport",
44+
"timestamp_format": "%Y-%m-%dT%H:%M:%S.%fZ",
45+
"multi_line_start_pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T"
46+
}
47+
]
48+
}
49+
}
50+
}
51+
}
52+

assets/provision.sh

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#!/bin/bash -xe
2+
3+
# ---------------------------------------------------------------------- fns ---
4+
5+
function cwagent_ctl {
6+
/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl "$@"
7+
}
8+
export -f cwagent_ctl
9+
10+
# ------------------------------------------------------------------- script ---
11+
12+
yum update -y
13+
14+
chmod 644 /var/log/cloud-init-output.log
15+
chmod 644 /var/log/messages
16+
17+
cwagent_ctl -a fetch-config -s -m ec2 \
18+
-c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d/user.json

assets/userdata.sh

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#!/bin/bash
2+
# shellcheck disable=SC2034,2154
3+
4+
# --------------------------------------------------------- terraform inputs ---
5+
6+
TELEPORT_EDITION=${tp_edition}
7+
TELEPORT_DOMAIN=${tp_domain}
8+
TELEPORT_CONFIG_ENCODED=${tp_config_encoded}
9+
10+
# ------------------------------------------------------------------- script ---
11+
12+
echo "AWS_DEFAULT_REGION=us-east-1" >>/etc/default/teleport
13+
14+
TELEPORT_VERSION="$(curl "https://$TELEPORT_DOMAIN/v1/webapi/automaticupgrades/channel/stable/cloud/version" | sed 's/v//')"
15+
16+
echo "$TELEPORT_CONFIG_ENCODED" | base64 -d >/etc/teleport.yaml
17+
curl https://cdn.teleport.dev/install.sh | bash -s $TELEPORT_VERSION $TELEPORT_EDITION
18+
19+
sudo systemctl enable teleport
20+
sudo systemctl start teleport

0 commit comments

Comments
 (0)