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

feat: support AWS SSM tailscaled state #41

Merged
merged 13 commits into from
Nov 21, 2024
Merged
90 changes: 90 additions & 0 deletions .coderabbit.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Docs: https://docs.coderabbit.ai/configure-coderabbit
# Schema: https://coderabbit.ai/integrations/schema.v2.json
# Support: https://discord.gg/GsXnASn26c

language: en

tone_instructions: |
Provide feedback in a professional, friendly, constructive, and concise tone.
Offer clear, specific suggestions and best practices to help enhance the code quality and promote learning.

early_access: true

knowledge_base:
# The scope of learnings to use for the knowledge base.
# `local` uses the repository's learnings,
# `global` uses the organization's learnings,
# `auto` uses repository's learnings for public repositories and organization's learnings for private repositories.
# Default value: `auto`
learnings:
scope: global
issues:
scope: global
pull_requests:
scope: global

reviews:
profile: chill
auto_review:
# Ignore reviewing if the title of the pull request contains any of these keywords (case-insensitive)
ignore_title_keywords:
- wip
- draft
- test
# Set the commit status to 'pending' when the review is in progress and 'success' when it is complete.
commit_status: false
# Post review details on each review. Additionally, post a review status when a review is skipped in certain cases.
review_status: false
path_instructions:
- path: "**/*.tf"
instructions: |
You're a Terraform expert who has thoroughly studied all the documentation from Hashicorp https://developer.hashicorp.com/terraform/docs and OpenTofu https://opentofu.org/docs/.
You have a strong grasp of Terraform syntax and prioritize providing accurate and insightful code suggestions.
As a fan of the Cloud Posse / SweetOps ecosystem, you incorporate many of their best practices https://docs.cloudposse.com/best-practices/terraform/ while balancing them with general Terraform guidelines.
tools:
# By default, all tools are enabled.
# Masterpoint uses Trunk (https://trunk.io) so we do not need a lot of this feedback due to overlap.
shellcheck:
enabled: false
ruff:
enabled: false
markdownlint:
enabled: false
github-checks:
enabled: false
languagetool:
enabled: false
biome:
enabled: false
hadolint:
enabled: false
swiftlint:
enabled: false
phpstan:
enabled: false
golangci-lint:
enabled: false
yamllint:
enabled: false
gitleaks:
enabled: false
checkov:
enabled: false
detekt:
enabled: false
eslint:
enabled: false
rubocop:
enabled: false
buf:
enabled: false
regal:
enabled: false
actionlint:
enabled: false
pmd:
enabled: false
cppcheck:
enabled: false
circleci:
enabled: false
8 changes: 4 additions & 4 deletions .github/workflows/trunk-upgrade.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
name: Weekly Trunk Upgrade
name: Monthly Trunk Upgrade
on:
schedule:
# Every Monday @ 5am
- cron: 0 5 * * 1
# On the first day of every month @ 8am
- cron: 0 8 1 * *
# Allows us to manually run the workflow from Actions UI
workflow_dispatch: {}
permissions: read-all
Expand All @@ -18,7 +18,7 @@ jobs:
uses: actions/checkout@v4

- name: Trunk Upgrade
uses: trunk-io/trunk-action/upgrade@d5b1b61d0beee562512f530a278b6a2931fba857
uses: trunk-io/trunk-action/upgrade@2eaee169140ec559bd556208f9f99cdfdf468da8 # v1.1.18
with:
base: main
reviewers: "@masterpointio/masterpoint-internal"
Expand Down
8 changes: 5 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@
.terraform
.terraform.tfstate.lock.info

**/.idea
**/*.iml

# Cloud Posse Build Harness https://github.com/cloudposse/build-harness
**/.build-harness
**/build-harness

# Crash log files
crash.log
test.log

# Random
**/.idea
**/*.iml
.DS_Store
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,11 @@ Here is an example of using this module:

## Modules

| Name | Source | Version |
| -------------------------------------------------------------------------------------------------------- | --------------------------- | ------- |
| <a name="module_tailscale_subnet_router"></a> [tailscale_subnet_router](#module_tailscale_subnet_router) | masterpointio/ssm-agent/aws | 1.2.0 |
| <a name="module_this"></a> [this](#module_this) | cloudposse/label/null | 0.25.0 |
| Name | Source | Version |
| -------------------------------------------------------------------------------------------------------- | ---------------------------------- | ------- |
| <a name="module_ssm_state"></a> [ssm_state](#module_ssm_state) | cloudposse/ssm-parameter-store/aws | 0.13.0 |
| <a name="module_tailscale_subnet_router"></a> [tailscale_subnet_router](#module_tailscale_subnet_router) | masterpointio/ssm-agent/aws | 1.2.0 |
| <a name="module_this"></a> [this](#module_this) | cloudposse/label/null | 0.25.0 |

## Resources

Expand Down Expand Up @@ -126,6 +127,7 @@ Here is an example of using this module:
| <a name="input_session_logging_kms_key_alias"></a> [session_logging_kms_key_alias](#input_session_logging_kms_key_alias) | Alias name for `session_logging` KMS Key.<br> This is only applied if 2 conditions are met: (1) `session_logging_kms_key_arn` is unset,<br> (2) `session_logging_encryption_enabled` = true. | `string` | `"alias/session_logging"` | no |
| <a name="input_session_logging_ssm_document_name"></a> [session_logging_ssm_document_name](#input_session_logging_ssm_document_name) | Name for `session_logging` SSM document.<br> This is only applied if 2 conditions are met: (1) `session_logging_enabled` = true,<br> (2) `create_run_shell_document` = true. | `string` | `"SSM-SessionManagerRunShell-Tailscale"` | no |
| <a name="input_ssh_enabled"></a> [ssh_enabled](#input_ssh_enabled) | Enable SSH access to the Tailscale Subnet Router EC2 instance. Defaults to true. | `bool` | `true` | no |
| <a name="input_ssm_state_enabled"></a> [ssm_state_enabled](#input_ssm_state_enabled) | Control is tailscaled state (including preferences and keys) is stored in AWS SSM.<br>See more in the [docs](https://tailscale.com/kb/1278/tailscaled#flags-to-tailscaled). | `bool` | `false` | no |
| <a name="input_stage"></a> [stage](#input_stage) | ID element. Usually used to indicate role, e.g. 'prod', 'staging', 'source', 'build', 'test', 'deploy', 'release' | `string` | `null` | no |
| <a name="input_subnet_ids"></a> [subnet_ids](#input_subnet_ids) | The Subnet IDs which the Tailscale Subnet Router EC2 instance will run in. These _should_ be private subnets. | `list(string)` | n/a | yes |
| <a name="input_tags"></a> [tags](#input_tags) | Additional tags (e.g. `{'BusinessUnit': 'XYZ'}`).<br>Neither the tag keys nor the tag values will be modified by this module. | `map(string)` | `{}` | no |
Expand Down
2 changes: 2 additions & 0 deletions examples/complete/fixtures.us-east-2.tfvars
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ region = "us-east-1"
availability_zones = ["us-east-1a", "us-east-1b"]
ipv4_primary_cidr_block = "172.16.0.0/16"

ssm_state_enabled = true

# Replace these values with your own
tailnet = "orgname.org.github"
oauth_client_id = "OAUTH_CLIENT_ID"
Expand Down
30 changes: 27 additions & 3 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@ locals {
prefixed_primary_tag = "tag:${local.primary_tag}"
prefixed_additional_tags = [for tag in var.additional_tags : "tag:${tag}"]

ssm_state_param_name = var.ssm_state_enabled ? "/tailscale/${module.this.id}/state" : null
ssm_state_flag = var.ssm_state_enabled ? "--state=${module.ssm_state[0].arn_map[local.ssm_state_param_name]}" : ""

tailscale_tags = concat([local.prefixed_primary_tag], local.prefixed_additional_tags)

tailscaled_extra_flags_enabled = length(var.tailscaled_extra_flags) > 0
tailscaled_extra_flags = join(" ", compact(concat(var.tailscaled_extra_flags, [local.ssm_state_flag])))
tailscaled_extra_flags_enabled = length(local.tailscaled_extra_flags) > 0

tailscale_up_extra_flags_enabled = length(var.tailscale_up_extra_flags) > 0

userdata = templatefile("${path.module}/userdata.sh.tmpl", {
Expand All @@ -18,7 +23,7 @@ locals {
tags = join(",", local.tailscale_tags)

tailscaled_extra_flags_enabled = local.tailscaled_extra_flags_enabled
tailscaled_extra_flags = join(" ", var.tailscaled_extra_flags)
tailscaled_extra_flags = local.tailscaled_extra_flags
tailscale_up_extra_flags_enabled = local.tailscale_up_extra_flags_enabled
tailscale_up_extra_flags = join(" ", var.tailscale_up_extra_flags)
})
Expand All @@ -29,7 +34,7 @@ locals {
# trivy:ignore:AVD-AWS-0090
module "tailscale_subnet_router" {
source = "masterpointio/ssm-agent/aws"
version = "1.2.0"
version = "1.2.0" #TODO: Update version when this is merged https://github.com/masterpointio/terraform-aws-ssm-agent/pull/29
gberenice marked this conversation as resolved.
Show resolved Hide resolved

context = module.this.context
tags = module.this.tags
Expand Down Expand Up @@ -63,3 +68,22 @@ resource "tailscale_tailnet_key" "default" {
# A device is automatically tagged when it is authenticated with this key.
tags = local.tailscale_tags
}

module "ssm_state" {
count = var.ssm_state_enabled ? 1 : 0
source = "cloudposse/ssm-parameter-store/aws"
version = "0.13.0"
ignore_value_changes = true

parameter_write = [
{
name = local.ssm_state_param_name
type = "SecureString"
overwrite = "true"
value = "{}"
description = "Tailscaled state of ${module.this.id} subnet router."
}
]
context = module.this.context
tags = module.this.tags
}
4 changes: 2 additions & 2 deletions userdata.sh.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ sudo yum-config-manager --add-repo https://pkgs.tailscale.com/stable/amazon-linu
sudo yum install -y tailscale

%{ if tailscaled_extra_flags_enabled == true }
echo "Exporting FLAGS to environment variable..."
export FLAGS=${tailscaled_extra_flags}%
echo "Exporting FLAGS to /etc/default/tailscaled..."
sudo sed -i "s|^FLAGS=.*|FLAGS=\"${tailscaled_extra_flags}\"|" /etc/default/tailscaled
gberenice marked this conversation as resolved.
Show resolved Hide resolved
%{ endif }

# Setup tailscale
Expand Down
9 changes: 9 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -180,3 +180,12 @@ variable "tailscale_up_extra_flags" {
See more in the [docs](https://tailscale.com/kb/1241/tailscale-up).
EOT
}

variable "ssm_state_enabled" {
gberenice marked this conversation as resolved.
Show resolved Hide resolved
default = false
type = bool
description = <<-EOT
Control is tailscaled state (including preferences and keys) is stored in AWS SSM.
gberenice marked this conversation as resolved.
Show resolved Hide resolved
See more in the [docs](https://tailscale.com/kb/1278/tailscaled#flags-to-tailscaled).
EOT
}
Loading