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

[lambda] feat: allows to use YAML instead of JSON for IAM policy #692

Merged
merged 12 commits into from
Jun 21, 2023
Merged
16 changes: 13 additions & 3 deletions modules/lambda/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,14 @@ components:
# s3_bucket_name: lambda-source # lambda main.tf calculates the rest of the bucket_name
# s3_key: hello-world-go.zip

policy_statements:
- sid: AllowSQSWorkerWriteAccess
effect: Allow
actions:
- sqs:SendMessage
- sqs:SendMessageBatch
resources:
- arn:aws:sqs:*:111111111111:worker-queue
```


Expand All @@ -62,7 +70,7 @@ components:

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.0 |
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3.0 |
| <a name="requirement_archive"></a> [archive](#requirement\_archive) | >= 2.3.0 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 4.9.0 |

Expand All @@ -89,6 +97,7 @@ components:
| [aws_iam_policy.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
| [aws_iam_role_policy_attachment.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [archive_file.lambdazip](https://registry.terraform.io/providers/hashicorp/archive/latest/docs/data-sources/file) | data source |
| [aws_iam_policy_document.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |

## Inputs

Expand All @@ -112,7 +121,7 @@ components:
| <a name="input_environment"></a> [environment](#input\_environment) | ID element. Usually used for region e.g. 'uw2', 'us-west-2', OR role 'prod', 'staging', 'dev', 'UAT' | `string` | `null` | no |
| <a name="input_event_source_mappings"></a> [event\_source\_mappings](#input\_event\_source\_mappings) | Creates event source mappings to allow the Lambda function to get events from Kinesis, DynamoDB and SQS. The IAM role<br> of this Lambda function will be enhanced with necessary minimum permissions to get those events. | `any` | `{}` | no |
| <a name="input_filename"></a> [filename](#input\_filename) | The path to the function's deployment package within the local filesystem. If defined, The s3\_-prefixed options and image\_uri cannot be used. | `string` | `null` | no |
| <a name="input_function_name"></a> [function\_name](#input\_function\_name) | Unique name for the Lambda Function. | `string` | n/a | yes |
| <a name="input_function_name"></a> [function\_name](#input\_function\_name) | Unique name for the Lambda Function. | `string` | `null` | no |
| <a name="input_handler"></a> [handler](#input\_handler) | The function entrypoint in your code. | `string` | `null` | no |
| <a name="input_iam_policy_description"></a> [iam\_policy\_description](#input\_iam\_policy\_description) | Description of the IAM policy for the Lambda IAM role | `string` | `"Minimum SSM read permissions for Lambda IAM Role"` | no |
| <a name="input_id_length_limit"></a> [id\_length\_limit](#input\_id\_length\_limit) | Limit `id` to this many characters (minimum 6).<br>Set to `0` for unlimited length.<br>Set to `null` for keep the existing setting, which defaults to `0`.<br>Does not affect `id_full`. | `number` | `null` | no |
Expand All @@ -134,7 +143,8 @@ components:
| <a name="input_namespace"></a> [namespace](#input\_namespace) | ID element. Usually an abbreviation of your organization name, e.g. 'eg' or 'cp', to help ensure generated IDs are globally unique | `string` | `null` | no |
| <a name="input_package_type"></a> [package\_type](#input\_package\_type) | The Lambda deployment package type. Valid values are `Zip` and `Image`. | `string` | `"Zip"` | no |
| <a name="input_permissions_boundary"></a> [permissions\_boundary](#input\_permissions\_boundary) | ARN of the policy that is used to set the permissions boundary for the role | `string` | `""` | no |
| <a name="input_policy_json"></a> [policy\_json](#input\_policy\_json) | IAM policy to attach to the Lambda IAM role | `string` | `null` | no |
| <a name="input_policy_json"></a> [policy\_json](#input\_policy\_json) | IAM policy to attach to the Lambda IAM role.<br> Shouldn't be used together with `policy_statements`, and takes precedence over it. | `string` | `null` | no |
| <a name="input_policy_statements"></a> [policy\_statements](#input\_policy\_statements) | IAM policy to attach to the Lambda IAM role.<br> Shouldn't be used together with `policy_json` - the latter will take precedence over this variable. | <pre>list(object({<br> sid = optional(string, "")<br> effect = optional(string, "")<br> actions = optional(list(string), [])<br> resources = optional(list(string), [])<br> conditions = optional(list(object({<br> test = string<br> variable = string<br> values = list(string)<br> })), [])<br> }))</pre> | `null` | no |
| <a name="input_publish"></a> [publish](#input\_publish) | Whether to publish creation/change as new Lambda Function Version. | `bool` | `false` | no |
| <a name="input_regex_replace_chars"></a> [regex\_replace\_chars](#input\_regex\_replace\_chars) | Terraform regular expression (regex) string.<br>Characters matching the regex will be removed from the ID elements.<br>If not set, `"/[^a-zA-Z0-9-]/"` is used to remove all characters other than hyphens, letters and digits. | `string` | `null` | no |
| <a name="input_region"></a> [region](#input\_region) | AWS Region | `string` | n/a | yes |
Expand Down
34 changes: 28 additions & 6 deletions modules/lambda/main.tf
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
locals {
enabled = module.this.enabled
iam_policy_enabled = local.enabled && var.policy_json != null
iam_policy_enabled = local.enabled && (var.policy_statements != null || var.policy_json != null)
policy = local.iam_policy_enabled ? coalesce(var.policy_json, data.aws_iam_policy_document.default[0].json) : ""
Nuru marked this conversation as resolved.
Show resolved Hide resolved
s3_bucket_full_name = var.s3_bucket_name != null ? format("%s-%s-%s-%s-%s", module.this.namespace, module.this.tenant, module.this.environment, module.this.stage, var.s3_bucket_name) : null
}



module "label" {
source = "cloudposse/label/null"
version = "0.25.0"
Expand All @@ -15,13 +14,37 @@ module "label" {
context = module.this.context
}

data "aws_iam_policy_document" "default" {
gberenice marked this conversation as resolved.
Show resolved Hide resolved
count = local.iam_policy_enabled && var.policy_statements != null ? 1 : 0
dynamic "statement" {
for_each = var.policy_statements

content {
sid = statement.value.sid
effect = statement.value.effect
actions = statement.value.actions
resources = statement.value.resources

dynamic "condition" {
for_each = statement.value.conditions

content {
test = condition.value.test
variable = condition.value.variable
values = condition.value.values
}
}
}
}
}

resource "aws_iam_policy" "default" {
count = local.iam_policy_enabled ? 1 : 0

name = module.label.id
path = "/"
description = format("%s Lambda policy", module.label.id)
policy = var.policy_json
policy = local.policy
Nuru marked this conversation as resolved.
Show resolved Hide resolved

tags = module.this.tags
}
Expand All @@ -45,7 +68,7 @@ module "lambda" {
source = "cloudposse/lambda-function/aws"
version = "0.4.1"

function_name = module.label.id
function_name = coalesce(var.function_name, module.label.id)
gberenice marked this conversation as resolved.
Show resolved Hide resolved
description = var.description
handler = var.handler
lambda_environment = var.lambda_environment
Expand Down Expand Up @@ -86,4 +109,3 @@ module "lambda" {

context = module.this.context
}

25 changes: 24 additions & 1 deletion modules/lambda/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ variable "region" {
variable "function_name" {
type = string
description = "Unique name for the Lambda Function."
default = null
}

variable "architectures" {
Expand Down Expand Up @@ -268,10 +269,32 @@ variable "iam_policy_description" {

variable "policy_json" {
type = string
description = "IAM policy to attach to the Lambda IAM role"
description = <<EOF
IAM policy to attach to the Lambda IAM role.
Shouldn't be used together with `policy_statements`, and takes precedence over it.
Nuru marked this conversation as resolved.
Show resolved Hide resolved
EOF
default = null
}

variable "policy_statements" {
description = <<EOF
IAM policy to attach to the Lambda IAM role.
Shouldn't be used together with `policy_json` - the latter will take precedence over this variable.
Nuru marked this conversation as resolved.
Show resolved Hide resolved
EOF
type = list(object({
sid = optional(string, "")
gberenice marked this conversation as resolved.
Show resolved Hide resolved
effect = optional(string, "")
actions = optional(list(string), [])
resources = optional(list(string), [])
conditions = optional(list(object({
test = string
variable = string
values = list(string)
})), [])
}))
default = null
}

variable "zip" {
type = object({
enabled = optional(bool, false)
Expand Down
2 changes: 1 addition & 1 deletion modules/lambda/versions.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
terraform {
required_version = ">= 1.0"
required_version = ">= 1.3.0"

required_providers {
aws = {
Expand Down