A Terraform provider for Dokploy
Plugin-framework provider covering projects, environments, applications, Compose stacks, managed databases, domains, mounts, ports, redirects, basic auth, registries, SSH keys, certificates and backup destinations, over Dokploy's tRPC-over-REST API. The shim package exposes the provider to other Go modules, which is how pulumi-dokploy bridges it.
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
# Secrets Manager Auto Rotation Enabled Check
|
||||
|
||||
## Source Sentinel Policy
|
||||
`secretsmanager-auto-rotation-enabled-check.sentinel`
|
||||
|
||||
## Conversion Quality
|
||||
`Limited`
|
||||
|
||||
## Why this is limited
|
||||
The Sentinel policy uses `tfconfig/v2` reference metadata to determine whether each `aws_secretsmanager_secret` is connected to an `aws_secretsmanager_secret_rotation` resource through `config.secret_id`. Current tfpolicy guidance does not expose equivalent config-level reference metadata.
|
||||
|
||||
## What the tfpolicy approximation does
|
||||
The tfpolicy version uses `core::getresources()` to collect `aws_secretsmanager_secret_rotation` resources and matches them to secrets by planned `secret_id` / `id` values.
|
||||
|
||||
## Limitations encountered
|
||||
- This is value matching, not true Terraform graph reasoning
|
||||
- It may fail or behave differently when secret identifiers are not resolved yet during creation
|
||||
- It does not preserve Sentinel's module-aware reference reconstruction exactly
|
||||
@@ -0,0 +1,22 @@
|
||||
# Approximation of HashiCorp PCI DSS Sentinel example: secretsmanager-auto-rotation-enabled-check.sentinel
|
||||
# Exact conversion quality: Limited
|
||||
|
||||
locals {
|
||||
all_secret_rotations = core::getresources("aws_secretsmanager_secret_rotation", {})
|
||||
rotation_secret_ids = {
|
||||
for rotation in local.all_secret_rotations :
|
||||
core::try(rotation.secret_id, "") => true
|
||||
}
|
||||
}
|
||||
|
||||
resource_policy "aws_secretsmanager_secret" "secretsmanager_auto_rotation_enabled_check" {
|
||||
locals {
|
||||
secret_id = core::try(attrs.id, "")
|
||||
has_rotation = core::try(local.rotation_secret_ids[local.secret_id], false)
|
||||
}
|
||||
|
||||
enforce {
|
||||
condition = local.has_rotation
|
||||
error_message = "Secrets Manager secrets should have a matching aws_secretsmanager_secret_rotation resource"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
# This policy requires resources of type `aws_secretsmanager_secret` should be configured for automatic rotation.
|
||||
|
||||
# Copyright IBM Corp. 2025
|
||||
# SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
# Imports
|
||||
|
||||
import "tfconfig/v2" as tfconfig
|
||||
import "tfresources" as tf
|
||||
import "report" as report
|
||||
import "collection" as collection
|
||||
import "collection/maps" as maps
|
||||
import "strings"
|
||||
|
||||
# Constants
|
||||
|
||||
const = {
|
||||
"policy_name": "secretsmanager-auto-rotation-enabled-check",
|
||||
"message": "Secrets Manager secrets should be configured for automatic rotation. Refer to https://docs.aws.amazon.com/securityhub/latest/userguide/secretsmanager-controls.html#secretsmanager-1 for more details.",
|
||||
"resource_aws_secretsmanager_secret": "aws_secretsmanager_secret",
|
||||
"resource_aws_secretsmanager_secret_rotation": "aws_secretsmanager_secret_rotation",
|
||||
"kms_master_key_id": "kms_master_key_id",
|
||||
"sqs_managed_sse_enabled": "sqs_managed_sse_enabled",
|
||||
"module_prefix": "module.",
|
||||
}
|
||||
|
||||
# Functions
|
||||
|
||||
get_referenced_resource_address = func(res, attr) {
|
||||
references_list = maps.get(res, attr, [])
|
||||
if references_list.references is empty or references_list.references is not defined {
|
||||
return ""
|
||||
}
|
||||
referenced_address = references_list.references[1]
|
||||
if strings.has_prefix(res.address, const.module_prefix) {
|
||||
referenced_address = res.module_address + "." + referenced_address
|
||||
}
|
||||
return referenced_address
|
||||
}
|
||||
|
||||
# Variables
|
||||
|
||||
secret_resources = tf.config(tfconfig.resources).type(const.resource_aws_secretsmanager_secret).resources
|
||||
secret_rotation_complaint_resources = tf.config(tfconfig.resources).type(const.resource_aws_secretsmanager_secret_rotation).resources
|
||||
|
||||
secret_addresses = map secret_rotation_complaint_resources as _, res {
|
||||
get_referenced_resource_address(res, "config.secret_id")
|
||||
}
|
||||
|
||||
violations = filter secret_resources as _, res {
|
||||
res.address not in secret_addresses
|
||||
}
|
||||
|
||||
summary = {
|
||||
"policy_name": const.policy_name,
|
||||
"violations": map violations as _, v {
|
||||
{
|
||||
"address": v.address,
|
||||
"module_address": v.module_address,
|
||||
"message": const.message,
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
# Outputs
|
||||
|
||||
print(report.generate_policy_report(summary))
|
||||
|
||||
# Rules
|
||||
|
||||
main = rule {
|
||||
violations is empty
|
||||
}
|
||||
Reference in New Issue
Block a user