diff --git a/.trunk/configs/.checkov.yaml b/.checkov.yaml
similarity index 100%
rename from .trunk/configs/.checkov.yaml
rename to .checkov.yaml
diff --git a/.coderabbit.yaml b/.coderabbit.yaml
index e279a6f..39f44bd 100644
--- a/.coderabbit.yaml
+++ b/.coderabbit.yaml
@@ -7,6 +7,7 @@ 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.
+ Be concise and only comment on significant issues.
early_access: true
@@ -26,21 +27,25 @@ knowledge_base:
reviews:
profile: chill
auto_review:
- # Ignore reviewing if the title of the pull request contains any of these keywords (case-insensitive)
+ # Disable incremental code review on each push
+ auto_incremental_review: false
+ # The keywords are 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.
+ changed_files_summary: false
+ poem: false
+ # Don't post review details on each review.
+ review_status: false
+ sequence_diagrams: false
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.
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 4a035e9..51080ca 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -4,4 +4,4 @@
# Order is important: the last matching pattern takes the most precedence
# These owners will be the default owners for everything
-* @masterpointio/masterpoint-internal
\ No newline at end of file
+* @masterpointio/masterpoint-open-source
\ No newline at end of file
diff --git a/.github/renovate.json5 b/.github/renovate.json5
new file mode 100644
index 0000000..275d017
--- /dev/null
+++ b/.github/renovate.json5
@@ -0,0 +1,64 @@
+{
+ "extends": [
+ "config:best-practices",
+ "github>aquaproj/aqua-renovate-config#2.7.5"
+ ],
+ "enabledManagers": [
+ "terraform",
+ "github-actions"
+ ],
+ "terraform": {
+ "ignorePaths": [
+ "**/context.tf" // Mixin file https://github.com/cloudposse/terraform-null-label/blob/main/exports/context.tf
+ ],
+ "fileMatch": [
+ "\\.tf$",
+ "\\.tofu$"
+ ]
+ },
+ "schedule": [
+ "after 9am on the first day of the month"
+ ],
+ "assigneesFromCodeOwners": true,
+ "dependencyDashboardAutoclose": true,
+ "addLabels": ["{{manager}}"],
+ "packageRules": [
+ {
+ "matchManagers": ["github-actions"],
+ "matchUpdateTypes": ["minor", "patch", "pin", "digest"],
+ "automerge": true,
+ "automergeType": "branch",
+ "groupName": "github-actions-auto-upgrade",
+ "addLabels": ["auto-upgrade"]
+ },
+ {
+ "matchManagers": ["github-actions"],
+ "matchUpdateTypes": ["major"],
+ "groupName": "github-actions-needs-review",
+ "addLabels": ["needs-review"]
+ },
+ {
+ "matchManagers": ["terraform"],
+ "groupName": "tf",
+ "addLabels": ["needs-review"]
+ },
+ {
+ "matchFileNames": ["**/*.tofu", "**/*.tf"],
+ "matchDatasources": ["terraform-provider", "terraform-module"],
+ "registryUrls": ["https://registry.opentofu.org"],
+ "groupName": "tf"
+ },
+ {
+ "matchFileNames": ["**/*.tofu"],
+ "matchDepTypes": ["required_version"],
+ "registryUrls": ["https://registry.opentofu.org"],
+ "groupName": "tf"
+ },
+ {
+ "matchFileNames": ["**/*.tf"],
+ "matchDepTypes": ["required_version"],
+ "registryUrls": ["https://registry.terraform.io"],
+ "groupName": "tf"
+ }
+ ]
+}
diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml
index 092d215..9ed5d6e 100644
--- a/.github/workflows/lint.yaml
+++ b/.github/workflows/lint.yaml
@@ -1,6 +1,10 @@
name: Lint
-on: pull_request
+concurrency:
+ group: lint-${{ github.head_ref || github.run_id }}
+ cancel-in-progress: true
+
+on: pull_request_target
permissions:
actions: read
@@ -13,6 +17,17 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Check out Git repository
- uses: actions/checkout@v4
+ uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Trunk Check
- uses: trunk-io/trunk-action@v1
+ uses: trunk-io/trunk-action@4d5ecc89b2691705fd08c747c78652d2fc806a94 # v1.1.19
+ env:
+ # NOTE: inject the GITHUB_TOKEN for the trunk managed tflint linter
+ # https://github.com/terraform-linters/tflint/blob/master/docs/user-guide/plugins.md#avoiding-rate-limiting
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ conventional-title:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: amannn/action-semantic-pull-request@0723387faaf9b38adef4775cd42cfd5155ed6017 # v5.5.3
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/release-please.yaml b/.github/workflows/release-please.yaml
index 13798ec..6de4368 100644
--- a/.github/workflows/release-please.yaml
+++ b/.github/workflows/release-please.yaml
@@ -8,11 +8,20 @@ on:
permissions:
contents: write
pull-requests: write
+ issues: write
jobs:
release-please:
runs-on: ubuntu-latest
steps:
+ - name: Create Token for MasterpointBot App
+ uses: tibdex/github-app-token@3beb63f4bd073e61482598c45c71c1019b59b73a #v2.1.0
+ id: generate-token
+ with:
+ app_id: ${{ secrets.MP_BOT_APP_ID }}
+ private_key: ${{ secrets.MP_BOT_APP_PRIVATE_KEY }}
+
- uses: googleapis/release-please-action@7987652d64b4581673a76e33ad5e98e3dd56832f #v4.1.3
with:
+ token: ${{ steps.generate-token.outputs.token }}
release-type: terraform-module
diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml
new file mode 100644
index 0000000..330fbbb
--- /dev/null
+++ b/.github/workflows/test.yaml
@@ -0,0 +1,28 @@
+name: TF Test
+
+on:
+ push:
+ branches:
+ - main
+ pull_request_target:
+
+permissions:
+ actions: read
+ checks: write
+ contents: read
+ id-token: write
+ pull-requests: read
+
+jobs:
+ tf-test:
+ name: π§ͺ ${{ matrix.tf }} test
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ tf: [tofu, terraform]
+ steps:
+ - uses: masterpointio/github-action-tf-test@c3b619f3bca9e4f482b9e0fb3166ab3f02d9d54c # v1.0.0
+ with:
+ tf_type: ${{ matrix.tf }}
+ aws_role_arn: ${{ vars.TF_TEST_AWS_ROLE_ARN }}
+ github_token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/trunk-upgrade.yaml b/.github/workflows/trunk-upgrade.yaml
index 8b14fcc..5ea1ae9 100644
--- a/.github/workflows/trunk-upgrade.yaml
+++ b/.github/workflows/trunk-upgrade.yaml
@@ -17,7 +17,7 @@ jobs:
pull-requests: write
steps:
- name: Checkout
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 #v4.1.7
+ uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Create Token for MasterpointBot App
uses: tibdex/github-app-token@3beb63f4bd073e61482598c45c71c1019b59b73a #v2.1.0
@@ -27,8 +27,36 @@ jobs:
private_key: ${{ secrets.MP_BOT_APP_PRIVATE_KEY }}
- name: Upgrade
- uses: trunk-io/trunk-action/upgrade@86b68ffae610a05105e90b1f52ad8c549ef482c2 #v1.1.16
+ id: trunk-upgrade
+ uses: trunk-io/trunk-action/upgrade@4d5ecc89b2691705fd08c747c78652d2fc806a94 # v1.1.19
with:
github-token: ${{ steps.generate-token.outputs.token }}
reviewers: "@masterpointio/masterpoint-internal"
prefix: "chore: "
+
+ - name: Wait for checks to pass + Merge PR
+ if: steps.trunk-upgrade.outputs.pull-request-number != ''
+ env:
+ GH_TOKEN: ${{ steps.generate-token.outputs.token }}
+ PR_NUMBER: ${{ steps.trunk-upgrade.outputs.pull-request-number }}
+ run: |
+ echo "Waiting for required status checks to pass on PR #$PR_NUMBER..."
+ while true; do
+ CHECKS_JSON=$(gh pr checks "$PR_NUMBER" --required --json state,bucket)
+ echo "Current checks status: $CHECKS_JSON"
+
+ if echo "$CHECKS_JSON" | jq -e '.[] | select(.bucket=="fail")' > /dev/null; then
+ echo "One or more required checks have failed. Exiting..."
+ exit 1
+ fi
+
+ FAILED_OR_PENDING_CHECKS=$(echo "$CHECKS_JSON" | jq '[.[] | select(.state!="SUCCESS" or .bucket!="pass")] | length')
+ if [ "$FAILED_OR_PENDING_CHECKS" -eq 0 ]; then
+ echo "All required checks passed. Merging PR https://github.com/${{ github.repository }}/pull/$PR_NUMBER..."
+ gh pr merge "$PR_NUMBER" --squash --delete-branch --admin
+ break
+ else
+ echo "Some required checks are still running or pending. Retrying in 30s..."
+ sleep 30
+ fi
+ done
diff --git a/.gitignore b/.gitignore
index 0807788..4c85809 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,9 +9,14 @@
# Local .terraform directories
**/.terraform/*
+# Ignore the root .terraform.lock.hcl file (Child modules don't want this)
+.terraform.lock.hcl
+!examples/**/.terraform.lock.hcl
+
# IDE/Editor settings
**/.idea
**/*.iml
+.cursor/
.vscode/
*.orig
*.draft
@@ -39,4 +44,8 @@ backend.tf.json
**/*.temp
**/*.bak
**/*.*swp
-**/.DS_Store
\ No newline at end of file
+**/.DS_Store
+
+# Claude Code - we beleive engineers are responsible for the code they push no matter how it's generated.
+# Therefore, configs specific to their coding practices are their responsibilty to judiciously manage.
+.claude/*
diff --git a/.trunk/configs/.markdownlint.yaml b/.markdownlint.yaml
similarity index 82%
rename from .trunk/configs/.markdownlint.yaml
rename to .markdownlint.yaml
index c97ae62..33a98b8 100644
--- a/.trunk/configs/.markdownlint.yaml
+++ b/.markdownlint.yaml
@@ -12,3 +12,8 @@ whitespace: false
# Ignore MD041/first-line-heading/first-line-h1
# Error: First line in a file should be a top-level heading
MD041: false
+
+# Ignore MD013/line-length
+MD013:
+ strict: false
+ line_length: 350
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
deleted file mode 100644
index 3945246..0000000
--- a/.pre-commit-config.yaml
+++ /dev/null
@@ -1,7 +0,0 @@
-# Prerequisites:
-# brew install pre-commit terraform-docs
-repos:
- - repo: https://github.com/antonbabenko/pre-commit-terraform
- rev: v1.88.0
- hooks:
- - id: terraform_docs
diff --git a/.terraform-docs.yaml b/.terraform-docs.yaml
new file mode 100644
index 0000000..710c102
--- /dev/null
+++ b/.terraform-docs.yaml
@@ -0,0 +1,16 @@
+version: 0.20.0
+formatter: markdown table
+
+recursive:
+ enabled: false
+
+settings:
+ lockfile: false
+
+output:
+ file: README.md
+ mode: inject
+ template: |-
+
+ {{ .Content }}
+
diff --git a/.tflint.hcl b/.tflint.hcl
new file mode 100644
index 0000000..f01f0f6
--- /dev/null
+++ b/.tflint.hcl
@@ -0,0 +1,42 @@
+plugin "terraform" {
+ enabled = true
+ preset = "all"
+}
+
+config {
+ format = "compact"
+
+ # Inspect vars passed into "module" blocks. eg, lint AMI value passed into ec2 module.
+ # https://github.com/terraform-linters/tflint/blob/master/docs/user-guide/calling-modules.md
+ call_module_type = "all"
+
+ # default values but keeping them here for clarity
+ disabled_by_default = false
+ force = false
+}
+
+# Installing tflint rulesets from Github requires setting a GITHUB_TOKEN
+# environment variable. Without it, you'll get an error like this:
+# $ tflint --init
+# Installing "aws" plugin...
+# Failed to install a plugin; Failed to fetch GitHub releases: GET https://api.github.com/repos/terraform-linters/tflint-ruleset-aws/releases/tags/v0.39.0: 401 Bad credentials []
+#
+# The solution is to provide a github PAT via a GITHUB_TOKEN env var,
+# export GITHUB_TOKEN=github_pat_120abc123def456ghi789jkl123mno456pqr789stu123vwx456yz789
+#
+# See docs for more info: https://github.com/terraform-linters/tflint/blob/master/docs/user-guide/plugins.md#avoiding-rate-limiting
+plugin "aws" {
+ enabled = true
+ version = "0.39.0"
+ source = "github.com/terraform-linters/tflint-ruleset-aws"
+ deep_check = false
+}
+
+# Allow variables to exist in more files than ONLY variables.tf
+# Example use cases where we prefer for variables to exist in context,
+# - context.tf (applicable to the null-label module)
+# - providers.tf (when passing in secret keys from SOPs - example, github provider)
+# https://github.com/terraform-linters/tflint-ruleset-terraform/blob/main/docs/rules/terraform_standard_module_structure.md
+rule "terraform_standard_module_structure" {
+ enabled = false
+}
\ No newline at end of file
diff --git a/.trunk/.gitignore b/.trunk/.gitignore
index 15966d0..072b680 100644
--- a/.trunk/.gitignore
+++ b/.trunk/.gitignore
@@ -6,4 +6,4 @@
plugins
user_trunk.yaml
user.yaml
-tmp
+tmp
\ No newline at end of file
diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml
index a307378..35c1009 100644
--- a/.trunk/trunk.yaml
+++ b/.trunk/trunk.yaml
@@ -2,17 +2,17 @@
# To learn more about the format of this file, see https://docs.trunk.io/reference/trunk-yaml
version: 0.1
cli:
- version: 1.22.11
+ version: 1.24.0
# Trunk provides extensibility via plugins. (https://docs.trunk.io/plugins)
plugins:
sources:
- id: trunk
- ref: v1.6.7
+ ref: v1.7.0
uri: https://github.com/trunk-io/plugins
# Many linters and tools depend on runtimes - configure them here. (https://docs.trunk.io/runtimes)
runtimes:
enabled:
- - node@18.20.5
+ - node@22.16.0
- python@3.10.8
# This is the section where you manage your linters. (https://docs.trunk.io/check/configuration)
lint:
@@ -20,22 +20,28 @@ lint:
# Incompatible with some Terraform features: https://github.com/tenable/terrascan/issues/1331
- terrascan
enabled:
- - tofu@1.9.0
+ - renovate@40.36.2
+ - tofu@1.9.1
- actionlint@1.7.7
- - checkov@3.2.394
+ - checkov@3.2.435
- git-diff-check
- - markdownlint@0.44.0
+ - markdownlint@0.45.0
- prettier@3.5.3
- - tflint@0.56.0
- - trivy@0.61.0
- - trufflehog@3.88.20
- - yamllint@1.37.0
+ - tflint@0.58.0
+ - trivy@0.63.0
+ - trufflehog@3.88.35
+ - yamllint@1.37.1
ignore:
- linters: [tofu]
paths:
- "**/backend.tf.json"
+ # Ignore CHANGELOG.md as release-please manages this file
+ - linters: [ALL]
+ paths:
+ - "**/CHANGELOG.md"
actions:
enabled:
+ - terraform-docs
- trunk-announce
- trunk-check-pre-push
- trunk-fmt-pre-commit
diff --git a/.trunk/configs/.yamllint.yaml b/.yamllint.yaml
similarity index 100%
rename from .trunk/configs/.yamllint.yaml
rename to .yamllint.yaml
diff --git a/LICENSE b/LICENSE
index 6b571c5..56d75ee 100644
--- a/LICENSE
+++ b/LICENSE
@@ -187,7 +187,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
- Copyright 2024 Masterpoint
+ Copyright 2025 Masterpoint
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/README.md b/README.md
index 87c2da6..e76cf5a 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,12 @@
+[![Banner][banner-image]](https://masterpoint.io/)
+
# terraform-spacelift-aws-integrations
-[](https://github.com/masterpointio/terraform-spacelift-aws-integrations/releases/latest)
+[![Release][release-badge]][latest-release]
+
+π‘ Learn more about Masterpoint [below](#who-we-are-π¦π¨πͺπ ).
+
+## Purpose and Functionality
This root module is responsible for managing the Spacelift Cloud [AWS Integration](https://docs.spacelift.io/integrations/cloud-providers/aws#amazon-web-services-aws) as code.
@@ -40,76 +46,127 @@ module "spacelift_aws_integrations" {
For a complete example, see [examples/complete](./examples/complete/).
+
+
-
## Requirements
-| Name | Version |
-| ------------------------------------------------------------------------ | ------- |
-| [terraform](#requirement_terraform) | >= 1.0 |
-| [spacelift](#requirement_spacelift) | >= 1.0 |
+| Name | Version |
+|------|---------|
+| [terraform](#requirement\_terraform) | >= 1.0 |
+| [spacelift](#requirement\_spacelift) | >= 1.0 |
## Providers
-| Name | Version |
-| ------------------------------------------------------------------ | ------- |
-| [spacelift](#provider_spacelift) | >= 1.0 |
+| Name | Version |
+|------|---------|
+| [spacelift](#provider\_spacelift) | >= 1.0 |
## Modules
-| Name | Source | Version |
-| -------------------------------------------------------------------------------------- | --------------------- | ------- |
-| [integration_label](#module_integration_label) | cloudposse/label/null | 0.25.0 |
-| [this](#module_this) | cloudposse/label/null | 0.25.0 |
+| Name | Source | Version |
+|------|--------|---------|
+| [integration\_label](#module\_integration\_label) | cloudposse/label/null | 0.25.0 |
+| [this](#module\_this) | cloudposse/label/null | 0.25.0 |
## Resources
-| Name | Type |
-| ----------------------------------------------------------------------------------------------------------------------------------------- | -------- |
+| Name | Type |
+|------|------|
| [spacelift_aws_integration.default](https://registry.terraform.io/providers/spacelift-io/spacelift/latest/docs/resources/aws_integration) | resource |
## Inputs
-| Name | Description | Type | Default | Required |
-| ------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------: |
-| [additional_tag_map](#input_additional_tag_map) | Additional key-value pairs to add to each map in `tags_as_list_of_maps`. Not added to `tags` or `id`.
This is for some rare cases where resources want additional configuration of tags
and therefore take a list of maps with tag key, value, and additional configuration. | `map(string)` | `{}` | no |
-| [attributes](#input_attributes) | ID element. Additional attributes (e.g. `workers` or `cluster`) to add to `id`,
in the order they appear in the list. New attributes are appended to the
end of the list. The elements of the list are joined by the `delimiter`
and treated as a single ID element. | `list(string)` | `[]` | no |
-| [aws_integrations](#input_aws_integrations) | Map of AWS integrations with their configurations. |
map(object({| `{}` | no | -| [context](#input_context) | Single object for setting entire context at once.
aws_account_id = string
role_arn = string
external_id = optional(string, null)
duration_seconds = optional(number, 900)
generate_credentials_in_worker = optional(bool, false)
labels = optional(list(string), [])
space_id = optional(string, "root")
}))
{| no | -| [delimiter](#input_delimiter) | Delimiter to be used between ID elements.
"additional_tag_map": {},
"attributes": [],
"delimiter": null,
"descriptor_formats": {},
"enabled": true,
"environment": null,
"id_length_limit": null,
"label_key_case": null,
"label_order": [],
"label_value_case": null,
"labels_as_tags": [
"unset"
],
"name": null,
"namespace": null,
"regex_replace_chars": null,
"stage": null,
"tags": {},
"tenant": null
}
[| no | -| [name](#input_name) | ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'.
"default"
]
map(object({| `{}` | no | +| [context](#input\_context) | Single object for setting entire context at once.
aws_account_id = string
role_arn = string
external_id = optional(string, null)
duration_seconds = optional(number, 900)
generate_credentials_in_worker = optional(bool, false)
labels = optional(list(string), [])
space_id = optional(string, "root")
}))
{| no | +| [delimiter](#input\_delimiter) | Delimiter to be used between ID elements.
"additional_tag_map": {},
"attributes": [],
"delimiter": null,
"descriptor_formats": {},
"enabled": true,
"environment": null,
"id_length_limit": null,
"label_key_case": null,
"label_order": [],
"label_value_case": null,
"labels_as_tags": [
"unset"
],
"name": null,
"namespace": null,
"regex_replace_chars": null,
"stage": null,
"tags": {},
"tenant": null
}
[| no | +| [name](#input\_name) | ID element. Usually the component or solution name, e.g. 'app' or 'jenkins'.
"default"
]