A collection of terraform modules that allow you to deploy and manage cloud-custodian lambda resources using native terraform as opposed to using the cloud-custodian CLI.
This project contains:
- A terraform module to create a cloud custodian lambda policy across multiple regions. The user provides a single cloud-custodian policy in either YAML or JSON format and based on this associated lambda resources are created and managed by terraform. Note: The
varssection with YAML anchors/aliases is only supported in YAML format. Located in the root of this github repository - A terraform module to create multiple cloud custodian lambda policies across multiple regions. The user provides multiple policies in either YAML or JSON format and based on this associated lambda resources are created and managed by terraform. Note: The
varssection with YAML anchors/aliases is only supported in YAML format. Using this module allows you to use the samevarsacross multiple policies. Located in modules/cloud-custodian-lambda-mailer - A terraform module to create cloud custodian lambda mailer. The user provides mailer config in either YAML or JSON format and based on this associated lambda resources are created and managed by terraform. Located in modules/cloud-custodian-lambda-mailer
The modules use python scripts where necessary to transform cloud-custodian config for use in different AWS resources. In order for this to work, you will need to have python3, the cloud custodian python modules and any dependencies installed. The following example uses uv and a virtualenv, but this can be done other ways:
# From the module root which contains uv.lock, pyproject.toml etc
# Install only production dependencies (just c7n)
uv sync --frozen --no-dev
# Activate the virtual environment
source .venv/bin/activate- You will need an S3 bucket to store results
- You will need an IAM role which will run the lambda, this will require permissions to post the report to the S3 bucket, create logs and metrics (if required) in cloudwatch and other permissions specific to the policy.
The example below deploys a single policy which finds security group rules open to port 22 in eu-west-1, us-east-1 and us-east-2:
module "cloud_custodian_lambda" {
source = "./"
regions = [
"eu-west-1",
"us-east-1",
"us-east-2"
]
execution_options = {
# Not really required but if you run custodian run you need to specify -s/--output-dir you'd then have execution-options
# as part of the config.json with the output_dir that was specified
"output_dir" = "s3://<your-custodian-bucket>/output?region=<region>"
}
policies = <<EOF
---
policies:
- name: cloudtrail
mode:
type: cloudtrail
function-prefix: custodian-
execution-options:
metrics_enabled: true
dryrun: false
log_group: /cloud-custodian/policies
output_dir: s3://<your-custodian-bucket>/output
role: arn:aws:iam:::role/<your-iam-role>
events:
- source: ec2.amazonaws.com
event: AuthorizeSecurityGroupIngress
ids: responseElements.securityGroupRuleSet.items[].groupId
- source: ec2.amazonaws.com
event: RevokeSecurityGroupIngress
ids: requestParameters.groupId
resource: security-group
filters:
- and:
- type: ingress
Ports:
- 22
Cidr:
value_type: cidr
op: in
value:
- 0.0.0.0/0
EOF
}There are examples for different policies as well as for using custodian mailer. If your input was JSON then you can get a pretty printed YAML of the policies and output to a file with the following:
terraform output -raw policies_yaml | python3 -c 'import sys, yaml; yaml.Dumper.ignore_aliases = lambda *args: True; print(yaml.safe_dump(yaml.safe_load(sys.stdin), default_flow_style=False))' > policies.yamlAfter this is done you can use the usual cloud custodian commands such as custodian report -s s3://<bucket> policies.yaml to get the results of the policies after they have been run.
See Troubleshooting
| Name | Version |
|---|---|
| terraform | >= 1.5.7 |
| aws | >= 6.0 |
| external | >= 2.0 |
| Name | Version |
|---|---|
| aws | 6.11.0 |
| external | 2.3.5 |
No modules.
| Name | Type |
|---|---|
| aws_cloudwatch_event_rule.cloudwatch_event | resource |
| aws_cloudwatch_event_rule.periodic | resource |
| aws_cloudwatch_event_target.cloudwatch_event | resource |
| aws_cloudwatch_event_target.periodic | resource |
| aws_config_config_rule.config_rule | resource |
| aws_lambda_function.custodian | resource |
| aws_lambda_permission.cloudwatch_event | resource |
| aws_lambda_permission.config_rule | resource |
| aws_lambda_permission.periodic | resource |
| aws_iam_role.custodian_role | data source |
| external_external.cloudwatch_event | data source |
| external_external.config_rule | data source |
| external_external.package_lambda | data source |
| external_external.validate_policy | data source |
| Name | Description | Type | Default | Required |
|---|---|---|---|---|
| policies | Policies in JSON or YAML format, this should either contain one policy or if it contains multiple policy_name should be provided.Note: The 'vars' section with YAML anchors/aliases is only supported in YAML format. |
string |
n/a | yes |
| architecture | Architecture for the Lambda function. Allowed: arm64 or x86_64. | string |
"arm64" |
no |
| execution_options | Execution options for the AWS Lambda function. Note that these are execution-options that would be set via the CLI when running custodian run.You can also set a more wide range of execution-options within the policy. See: https://cloudcustodian.io/docs/aws/lambda.html#execution-options |
map(any) |
{} |
no |
| force_deploy | Force redeployment of Lambda functions by updating a deployment timestamp tag. Set to true to trigger redeployment when source_code_hash doesn't detect changes. |
bool |
false |
no |
| policy_name | Optional: Extract a specific policy by name from multi-policy YAML. If not provided, expects single policy YAML. | string |
"" |
no |
| regions | Regions to deploy the policy to | list(string) |
[ |
no |
| Name | Description |
|---|---|
| cloudwatch_event_pattern | The event pattern for event mode |
| cloudwatch_event_rule | Complete AWS Cloudwatch Event Rule for cloudwatch event resource with all attributes |
| cloudwatch_event_rule_arn | The ARN of the CloudWatch Event Rule for event mode |
| cloudwatch_event_rule_name | The name of the CloudWatch Event Rule for event mode |
| config_rule | Complete AWS Config Rule resource with all attributes |
| config_rule_arn | The ARN of the AWS Config Rule |
| config_rule_name | The name of the AWS Config Rule |
| config_rule_rule_id | The ID of the AWS Config Rule |
| lambda_function | Complete AWS Lambda function resource with all attributes |
| lambda_function_arn | Map of Lambda function ARNs by region |
| lambda_function_filename | Map of Lambda function filenames by region |
| lambda_function_name | Map of Lambda function names by region |
| lambda_function_role | Map of Lambda function IAM roles by region |
| lambda_function_source_code_hash | Map of Lambda function source code hashes by region |
| lambda_function_source_code_size | Map of Lambda function source code sizes by region |
| lambda_function_tags | Map of Lambda function tags by region |
| mode_type | The type of Cloud Custodian mode (periodic, cloudtrail, config-rule, etc.) |
| package_lambda_result | Full output from package lambda step |
| package_versions | JSON string containing versions of all packages included in the Lambda deployment |
| periodic_event_rule | Complete AWS Cloudwatch Event Rule for periodic resource with all attributes |
| periodic_event_rule_arn | The ARN of the CloudWatch Event Rule for periodic mode |
| periodic_event_rule_name | The name of the CloudWatch Event Rule for periodic mode |
| periodic_schedule_expression | The schedule expression for periodic mode |
| policies_json | The policies rendered as JSON (only the specific policy if policy_name is set) |
| policies_yaml | The policies rendered as YAML (only the specific policy if policy_name is set) |
| policy_name | The name of the policy being deployed (if policy_name was specified) |
| regions | Regions that the policy is deployed to |
| sha256_hex | SHA256 hash of the Lambda package in hexadecimal format |