{"id":46530357,"url":"https://github.com/elsevierlabs-os/terraform-cloud-custodian-lambda","last_synced_at":"2026-03-06T22:03:06.676Z","repository":{"id":324731120,"uuid":"1059380488","full_name":"elsevierlabs-os/terraform-cloud-custodian-lambda","owner":"elsevierlabs-os","description":"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","archived":false,"fork":false,"pushed_at":"2026-02-12T10:36:35.000Z","size":339,"stargazers_count":12,"open_issues_count":0,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-12T18:59:50.622Z","etag":null,"topics":["aws","aws-lambda","c7n","c7n-mailer","cloud","cloud-custodian","compliance","cost-optimization","lambda","rules-engine","security","serverless"],"latest_commit_sha":null,"homepage":"","language":"HCL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/elsevierlabs-os.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-18T11:17:45.000Z","updated_at":"2026-02-12T10:26:56.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/elsevierlabs-os/terraform-cloud-custodian-lambda","commit_stats":null,"previous_names":["elsevierlabs-os/terraform-cloud-custodian-lambda"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/elsevierlabs-os/terraform-cloud-custodian-lambda","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elsevierlabs-os%2Fterraform-cloud-custodian-lambda","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elsevierlabs-os%2Fterraform-cloud-custodian-lambda/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elsevierlabs-os%2Fterraform-cloud-custodian-lambda/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elsevierlabs-os%2Fterraform-cloud-custodian-lambda/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/elsevierlabs-os","download_url":"https://codeload.github.com/elsevierlabs-os/terraform-cloud-custodian-lambda/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elsevierlabs-os%2Fterraform-cloud-custodian-lambda/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30200756,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-06T19:07:06.838Z","status":"ssl_error","status_checked_at":"2026-03-06T18:57:34.882Z","response_time":250,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aws","aws-lambda","c7n","c7n-mailer","cloud","cloud-custodian","compliance","cost-optimization","lambda","rules-engine","security","serverless"],"created_at":"2026-03-06T22:03:06.052Z","updated_at":"2026-03-06T22:03:06.666Z","avatar_url":"https://github.com/elsevierlabs-os.png","language":"HCL","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Cloud custodian lambda\n\nA 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. \n\nThis project contains:\n* A terraform module to create a [cloud custodian lambda policy](https://cloudcustodian.io/docs/aws/lambda.html) 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 `vars` section with YAML anchors/aliases is only supported in YAML format. Located in the root of this github repository\n* A terraform module to create multiple [cloud custodian lambda policies](https://cloudcustodian.io/docs/aws/lambda.html) 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 `vars` section with YAML anchors/aliases is only supported in YAML format. Using this module allows you to use the same `vars` across multiple policies. Located in [modules/cloud-custodian-lambda-mailer](./modules/cloud-custodian-lambda-policies/README.md)\n* A terraform module to create [cloud custodian lambda mailer](https://cloudcustodian.io/docs/tools/c7n-mailer.html). 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](./modules/cloud-custodian-lambda-mailer/README.md)\n\n## Python Setup\n\nThe 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](https://github.com/cloud-custodian/cloud-custodian) python modules and any dependencies installed. The following example uses [uv](https://docs.astral.sh/uv/) and a virtualenv, but this can be done other ways:\n\n```sh\n# From the module root which contains uv.lock, pyproject.toml etc\n# Install only production dependencies (just c7n)\nuv sync --frozen --no-dev\n\n# Activate the virtual environment\nsource .venv/bin/activate\n```\n\n## Managing Cloud Custodian Policies\n\n### Prerequisites\n\n* You will need an S3 bucket to store results\n* 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.\n\n### Terraform\n\nThe 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:\n\n```sh\nmodule \"cloud_custodian_lambda\" {\n  source = \"./\"\n\n  regions = [\n    \"eu-west-1\",\n    \"us-east-1\",\n    \"us-east-2\"\n  ]\n\n  execution_options = {\n    # Not really required but if you run custodian run you need to specify -s/--output-dir you'd then have execution-options\n    # as part of the config.json with the output_dir that was specified\n    \"output_dir\" = \"s3://\u003cyour-custodian-bucket\u003e/output?region=\u003cregion\u003e\"\n  }\n  policies = \u003c\u003cEOF\n---\npolicies:\n- name: cloudtrail\n  mode:\n    type: cloudtrail\n    function-prefix: custodian-\n    execution-options:\n      metrics_enabled: true\n      dryrun: false\n      log_group: /cloud-custodian/policies\n      output_dir: s3://\u003cyour-custodian-bucket\u003e/output\n    role: arn:aws:iam:::role/\u003cyour-iam-role\u003e\n    events:\n    - source: ec2.amazonaws.com\n      event: AuthorizeSecurityGroupIngress\n      ids: responseElements.securityGroupRuleSet.items[].groupId\n    - source: ec2.amazonaws.com\n      event: RevokeSecurityGroupIngress\n      ids: requestParameters.groupId\n  resource: security-group\n  filters:\n  - and:\n    - type: ingress\n      Ports:\n      - 22\n      Cidr:\n        value_type: cidr\n        op: in\n        value:\n        - 0.0.0.0/0\nEOF\n}\n```\n\nThere are [examples](./examples) for different policies as well as for using [custodian mailer](https://cloudcustodian.io/docs/tools/c7n-mailer.html). If your input was JSON then you can get a pretty printed YAML of the policies and output to a file with the following:\n\n```sh\nterraform 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))' \u003e policies.yaml\n```\n\nAfter this is done you can use the usual cloud custodian commands such as `custodian report -s s3://\u003cbucket\u003e policies.yaml` to get the results of the policies after they have been run.\n\n### Advanced Usage\n\n* [Multiple regions](./docs/MULTIPLE_REGIONS.md)\n* [Multiple policies](./modules/cloud-custodian-lambda-policies/README.md)\n\n### Troubleshooting\n\nSee [Troubleshooting](./docs/TROUBLESHOOTING.md)\n\n\u003c!-- BEGIN_TF_DOCS --\u003e\n## Requirements\n\n| Name | Version |\n|------|---------|\n| \u003ca name=\"requirement_terraform\"\u003e\u003c/a\u003e [terraform](#requirement\\_terraform) | \u003e= 1.5.7 |\n| \u003ca name=\"requirement_aws\"\u003e\u003c/a\u003e [aws](#requirement\\_aws) | \u003e= 6.0 |\n| \u003ca name=\"requirement_external\"\u003e\u003c/a\u003e [external](#requirement\\_external) | \u003e= 2.0 |\n\n## Providers\n\n| Name | Version |\n|------|---------|\n| \u003ca name=\"provider_aws\"\u003e\u003c/a\u003e [aws](#provider\\_aws) | 6.11.0 |\n| \u003ca name=\"provider_external\"\u003e\u003c/a\u003e [external](#provider\\_external) | 2.3.5 |\n\n## Modules\n\nNo modules.\n\n## Resources\n\n| Name | Type |\n|------|------|\n| [aws_cloudwatch_event_rule.cloudwatch_event](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_rule) | resource |\n| [aws_cloudwatch_event_rule.periodic](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_rule) | resource |\n| [aws_cloudwatch_event_target.cloudwatch_event](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_target) | resource |\n| [aws_cloudwatch_event_target.periodic](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_target) | resource |\n| [aws_config_config_rule.config_rule](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/config_config_rule) | resource |\n| [aws_lambda_function.custodian](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_function) | resource |\n| [aws_lambda_permission.cloudwatch_event](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_permission) | resource |\n| [aws_lambda_permission.config_rule](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_permission) | resource |\n| [aws_lambda_permission.periodic](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_permission) | resource |\n| [aws_iam_role.custodian_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_role) | data source |\n| [external_external.cloudwatch_event](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/external) | data source |\n| [external_external.config_rule](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/external) | data source |\n| [external_external.package_lambda](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/external) | data source |\n| [external_external.validate_policy](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/external) | data source |\n\n## Inputs\n\n| Name | Description | Type | Default | Required |\n|------|-------------|------|---------|:--------:|\n| \u003ca name=\"input_policies\"\u003e\u003c/a\u003e [policies](#input\\_policies) | Policies in JSON or YAML format, this should either contain one policy or if it contains multiple `policy_name` should be provided.\u003cbr/\u003e    Note: The 'vars' section with YAML anchors/aliases is only supported in YAML format. | `string` | n/a | yes |\n| \u003ca name=\"input_architecture\"\u003e\u003c/a\u003e [architecture](#input\\_architecture) | Architecture for the Lambda function. Allowed: arm64 or x86\\_64. | `string` | `\"arm64\"` | no |\n| \u003ca name=\"input_execution_options\"\u003e\u003c/a\u003e [execution\\_options](#input\\_execution\\_options) | Execution options for the AWS Lambda function.\u003cbr/\u003e    Note that these are execution-options that would be set via the CLI when running `custodian run`.\u003cbr/\u003e    You can also set a more wide range of execution-options within the policy.\u003cbr/\u003e    See: https://cloudcustodian.io/docs/aws/lambda.html#execution-options | `map(any)` | `{}` | no |\n| \u003ca name=\"input_force_deploy\"\u003e\u003c/a\u003e [force\\_deploy](#input\\_force\\_deploy) | Force redeployment of Lambda functions by updating a deployment timestamp tag.\u003cbr/\u003e    Set to true to trigger redeployment when source\\_code\\_hash doesn't detect changes. | `bool` | `false` | no |\n| \u003ca name=\"input_policy_name\"\u003e\u003c/a\u003e [policy\\_name](#input\\_policy\\_name) | Optional: Extract a specific policy by name from multi-policy YAML. If not provided, expects single policy YAML. | `string` | `\"\"` | no |\n| \u003ca name=\"input_regions\"\u003e\u003c/a\u003e [regions](#input\\_regions) | Regions to deploy the policy to | `list(string)` | \u003cpre\u003e[\u003cbr/\u003e  \"us-east-1\"\u003cbr/\u003e]\u003c/pre\u003e | no |\n\n## Outputs\n\n| Name | Description |\n|------|-------------|\n| \u003ca name=\"output_cloudwatch_event_pattern\"\u003e\u003c/a\u003e [cloudwatch\\_event\\_pattern](#output\\_cloudwatch\\_event\\_pattern) | The event pattern for event mode |\n| \u003ca name=\"output_cloudwatch_event_rule\"\u003e\u003c/a\u003e [cloudwatch\\_event\\_rule](#output\\_cloudwatch\\_event\\_rule) | Complete AWS Cloudwatch Event Rule for cloudwatch event resource with all attributes |\n| \u003ca name=\"output_cloudwatch_event_rule_arn\"\u003e\u003c/a\u003e [cloudwatch\\_event\\_rule\\_arn](#output\\_cloudwatch\\_event\\_rule\\_arn) | The ARN of the CloudWatch Event Rule for event mode |\n| \u003ca name=\"output_cloudwatch_event_rule_name\"\u003e\u003c/a\u003e [cloudwatch\\_event\\_rule\\_name](#output\\_cloudwatch\\_event\\_rule\\_name) | The name of the CloudWatch Event Rule for event mode |\n| \u003ca name=\"output_config_rule\"\u003e\u003c/a\u003e [config\\_rule](#output\\_config\\_rule) | Complete AWS Config Rule resource with all attributes |\n| \u003ca name=\"output_config_rule_arn\"\u003e\u003c/a\u003e [config\\_rule\\_arn](#output\\_config\\_rule\\_arn) | The ARN of the AWS Config Rule |\n| \u003ca name=\"output_config_rule_name\"\u003e\u003c/a\u003e [config\\_rule\\_name](#output\\_config\\_rule\\_name) | The name of the AWS Config Rule |\n| \u003ca name=\"output_config_rule_rule_id\"\u003e\u003c/a\u003e [config\\_rule\\_rule\\_id](#output\\_config\\_rule\\_rule\\_id) | The ID of the AWS Config Rule |\n| \u003ca name=\"output_lambda_function\"\u003e\u003c/a\u003e [lambda\\_function](#output\\_lambda\\_function) | Complete AWS Lambda function resource with all attributes |\n| \u003ca name=\"output_lambda_function_arn\"\u003e\u003c/a\u003e [lambda\\_function\\_arn](#output\\_lambda\\_function\\_arn) | Map of Lambda function ARNs by region |\n| \u003ca name=\"output_lambda_function_filename\"\u003e\u003c/a\u003e [lambda\\_function\\_filename](#output\\_lambda\\_function\\_filename) | Map of Lambda function filenames by region |\n| \u003ca name=\"output_lambda_function_name\"\u003e\u003c/a\u003e [lambda\\_function\\_name](#output\\_lambda\\_function\\_name) | Map of Lambda function names by region |\n| \u003ca name=\"output_lambda_function_role\"\u003e\u003c/a\u003e [lambda\\_function\\_role](#output\\_lambda\\_function\\_role) | Map of Lambda function IAM roles by region |\n| \u003ca name=\"output_lambda_function_source_code_hash\"\u003e\u003c/a\u003e [lambda\\_function\\_source\\_code\\_hash](#output\\_lambda\\_function\\_source\\_code\\_hash) | Map of Lambda function source code hashes by region |\n| \u003ca name=\"output_lambda_function_source_code_size\"\u003e\u003c/a\u003e [lambda\\_function\\_source\\_code\\_size](#output\\_lambda\\_function\\_source\\_code\\_size) | Map of Lambda function source code sizes by region |\n| \u003ca name=\"output_lambda_function_tags\"\u003e\u003c/a\u003e [lambda\\_function\\_tags](#output\\_lambda\\_function\\_tags) | Map of Lambda function tags by region |\n| \u003ca name=\"output_mode_type\"\u003e\u003c/a\u003e [mode\\_type](#output\\_mode\\_type) | The type of Cloud Custodian mode (periodic, cloudtrail, config-rule, etc.) |\n| \u003ca name=\"output_package_lambda_result\"\u003e\u003c/a\u003e [package\\_lambda\\_result](#output\\_package\\_lambda\\_result) | Full output from package lambda step |\n| \u003ca name=\"output_package_versions\"\u003e\u003c/a\u003e [package\\_versions](#output\\_package\\_versions) | JSON string containing versions of all packages included in the Lambda deployment |\n| \u003ca name=\"output_periodic_event_rule\"\u003e\u003c/a\u003e [periodic\\_event\\_rule](#output\\_periodic\\_event\\_rule) | Complete AWS Cloudwatch Event Rule for periodic resource with all attributes |\n| \u003ca name=\"output_periodic_event_rule_arn\"\u003e\u003c/a\u003e [periodic\\_event\\_rule\\_arn](#output\\_periodic\\_event\\_rule\\_arn) | The ARN of the CloudWatch Event Rule for periodic mode |\n| \u003ca name=\"output_periodic_event_rule_name\"\u003e\u003c/a\u003e [periodic\\_event\\_rule\\_name](#output\\_periodic\\_event\\_rule\\_name) | The name of the CloudWatch Event Rule for periodic mode |\n| \u003ca name=\"output_periodic_schedule_expression\"\u003e\u003c/a\u003e [periodic\\_schedule\\_expression](#output\\_periodic\\_schedule\\_expression) | The schedule expression for periodic mode |\n| \u003ca name=\"output_policies_json\"\u003e\u003c/a\u003e [policies\\_json](#output\\_policies\\_json) | The policies rendered as JSON (only the specific policy if policy\\_name is set) |\n| \u003ca name=\"output_policies_yaml\"\u003e\u003c/a\u003e [policies\\_yaml](#output\\_policies\\_yaml) | The policies rendered as YAML (only the specific policy if policy\\_name is set) |\n| \u003ca name=\"output_policy_name\"\u003e\u003c/a\u003e [policy\\_name](#output\\_policy\\_name) | The name of the policy being deployed (if policy\\_name was specified) |\n| \u003ca name=\"output_regions\"\u003e\u003c/a\u003e [regions](#output\\_regions) | Regions that the policy is deployed to |\n| \u003ca name=\"output_sha256_hex\"\u003e\u003c/a\u003e [sha256\\_hex](#output\\_sha256\\_hex) | SHA256 hash of the Lambda package in hexadecimal format |\n\u003c!-- END_TF_DOCS --\u003e","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felsevierlabs-os%2Fterraform-cloud-custodian-lambda","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Felsevierlabs-os%2Fterraform-cloud-custodian-lambda","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felsevierlabs-os%2Fterraform-cloud-custodian-lambda/lists"}