diff --git a/README.md b/README.md
index 4b9a6cb..72d8d1b 100644
--- a/README.md
+++ b/README.md
@@ -6,9 +6,11 @@
module "lambda" {
source = "../"
- prefix = "sbth"
- environment = "dev"
- name = "sigv4-request-to-s3"
+ prefix = "oozou"
+ environment = "test"
+ name = "resource"
+
+ is_edge = false # Default is "false." If you want to publish to the edge, don't forget to change AWS's provider to Virginia.
# File to read from
source_code_dir = "./src"
@@ -18,17 +20,45 @@ module "lambda" {
local_file_dir = "./outputs"
# S3 to upload source code to
- is_create_lambda_bucket = true # Default is `false`; plz use false, if not 1 lambda: 1 bucket
- bucket_name = "arn:aws:s3:::nanan" # If `is_create_lambda_bucket` is `false`; specified this, default is `""`
+ is_create_lambda_bucket = true # Default is `false`; plz use false, if not 1 lambda: 1 bucket
+ bucket_name = "" # If `is_create_lambda_bucket` is `false`; specified this, default is `""`
- # Lambda Config
+ # Lambda Env
runtime = "nodejs12.x"
handler = "index.handler" # Default `"index.handler"`
+ # Lambda Specification
+ timeout = 3 # Default is `3` seconds
+ memory_size = 128 # Default is `128` MB. as memory size increases, performance improves.
+ reserved_concurrent_executions = -1
+ ## Optional to connect Lambda to VPC
+ vpc_config = {
+ security_group_ids = ["sg-028f637312eea735e"]
+ subnet_ids_to_associate = ["subnet-0b853f8c85796d72d", "subnet-07c068b4b51262793", "subnet-0362f68c559ef7716"]
+ }
+ dead_letter_target_arn = "arn:aws:sns:ap-southeast-1:557291035693:demo" # Default is `null`; to send failed processing to target
+
# IAM
- is_create_lambda_role = true # Default is `true`
- lambda_role_arn = "" # If `is_create_lambda_role` is `false`
- additional_lambda_role_policy_arns = ["arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess"] # The policies that you want to attach to IAM Role created by only this module
+ is_create_lambda_role = true # Default is `true`
+ lambda_role_arn = "" # If `is_create_lambda_role` is `false`
+ additional_lambda_role_policy_arns = ["arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess", ] # The policies that you want to attach to IAM Role created by only this module
+
+ # Resource policy
+ lambda_permission_configuration = {
+ lambda_on_my_account = {
+ pricipal = "apigateway.amazonaws.com"
+ source_arn = "arn:aws:execute-api:ap-southeast-1:557291035693:lk36vflbha/*/*/"
+ }
+ lambda_on_my_another_account_wrong = {
+ pricipal = "apigateway.amazonaws.com"
+ source_arn = "arn:aws:execute-api:ap-southeast-1:562563527952:q6pwa6wgr6/*/*/"
+ source_account = "557291035693" # Optional just to restrict the permission
+ }
+ lambda_on_my_another_account_correct = {
+ pricipal = "apigateway.amazonaws.com"
+ source_arn = "arn:aws:execute-api:ap-southeast-1:562563527952:q6pwa6wgr6/*/*/"
+ }
+ }
# Logging
is_create_cloudwatch_log_group = true # Default is `true`
@@ -40,7 +70,7 @@ module "lambda" {
"DATABASE_HOST" = "www.google.com"
}
- tags = { "Workspace" = "pc" }
+ tags = { "Workspace" = "xxx-yyy-zzz" }
}
```
@@ -78,42 +108,53 @@ module "lambda" {
| [aws_iam_role_policy_attachment.ssm_policy_attachment](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_iam_role_policy_attachment.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_lambda_function.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_function) | resource |
+| [aws_lambda_permission.allow_serivce](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_permission) | resource |
| [aws_s3_object.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_object) | resource |
| [aws_ssm_parameter.params](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssm_parameter) | resource |
| [archive_file.zip_file](https://registry.terraform.io/providers/hashicorp/archive/2.2.0/docs/data-sources/file) | data source |
| [aws_iam_policy_document.assume_role_policy_doc](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
+| [aws_iam_policy_document.lambda_access_vpc](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.lambda_logs_policy_doc](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
+| [aws_iam_policy_document.lambda_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.secret_access_policy_doc](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
## Inputs
-| Name | Description | Type | Default | Required |
-|--------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------|-------------------|:--------:|
-| [additional\_lambda\_role\_policy\_arns](#input\_additional\_lambda\_role\_policy\_arns) | List of policies ARNs to attach to the lambda | `list(string)` | `[]` | no |
-| [bucket\_name](#input\_bucket\_name) | Name of the bucket to put the file in. Alternatively, an S3 access point ARN can be specified. | `string` | `""` | no |
-| [config\_file\_name](#input\_config\_file\_name) | The name of the file var.plaintext\_params will be written to as json | `string` | `"config.json"` | no |
-| [environment](#input\_environment) | Environment Variable used as a prefix | `string` | n/a | yes |
-| [file\_globs](#input\_file\_globs) | list of files or globs that you want included from the source\_code\_dir | `list(string)` | n/a | yes |
-| [handler](#input\_handler) | Function entrypoint in your code. | `string` | `"index.handler"` | no |
-| [is\_create\_cloudwatch\_log\_group](#input\_is\_create\_cloudwatch\_log\_group) | Whether to create cloudwatch log group or not | `bool` | `true` | no |
-| [is\_create\_lambda\_bucket](#input\_is\_create\_lambda\_bucket) | Whether to create lambda bucket or not | `bool` | `false` | no |
-| [local\_file\_dir](#input\_local\_file\_dir) | A path to the directory to store plan time generated local files | `string` | n/a | yes |
-| [name](#input\_name) | Name of the ECS cluster to create | `string` | n/a | yes |
-| [plaintext\_params](#input\_plaintext\_params) | Lambda@Edge does not support env vars, so it is a common pattern to exchange Env vars for values read from a config file.
So instead of using env vars like:
`const someEnvValue = process.env.SOME_ENV`
you would have lookups from a config file:
const config = JSON.parse(readFileSync('./config.json'))
const someConfigValue = config.SomeKeyCompared to var.ssm\_params, you should use this variable when you have non-secret things that you want very quick accessparams = {
COMMON_PREFIX_REGION = "eu-west-1"
COMMON_PREFIX_NAME = "Joeseph Schreibvogel"
}Compared to var.plaintext\_params, you should use this variable when you have secret data that you don't want written in plaintext in a fileconst config = JSON.parse(readFileSync('./config.json'))
const someConfigValue = config.SomeKey | `map(string)` | `{}` | no |
+| [prefix](#input\_prefix) | The prefix name of customer to be displayed in AWS console and resource | `string` | n/a | yes |
+| [reserved\_concurrent\_executions](#input\_reserved\_concurrent\_executions) | (Optional) Amount of reserved concurrent executions for this lambda function. A value of 0 disables lambda from being triggered and -1 removes any concurrency limitations. Defaults to Unreserved Concurrency Limits -1. See Managing Concurrency | `number` | `-1` | no |
+| [retention\_in\_days](#input\_retention\_in\_days) | Retention day for cloudwatch log group | `number` | `30` | no |
+| [runtime](#input\_runtime) | The runtime of the lambda function | `string` | n/a | yes |
+| [source\_code\_dir](#input\_source\_code\_dir) | An absolute path to the directory containing the code to upload to lambda | `string` | n/a | yes |
+| [ssm\_params](#input\_ssm\_params) | Lambda@Edge does not support env vars, so it is a common pattern to exchange Env vars for SSM params.object({
security_group_ids = list(string)
subnet_ids_to_associate = list(string)
}) | {
"security_group_ids": [],
"subnet_ids_to_associate": []
} | no |
## Outputs
-| Name | Description |
-|---------------------------------------------------------------------------------------------------|--------------------------------------------------------------|
-| [arn](#output\_arn) | Amazon Resource Name (ARN) identifying your Lambda Function. |
-| [execution\_role\_arn](#output\_execution\_role\_arn) | n/a |
-| [execution\_role\_name](#output\_execution\_role\_name) | n/a |
-| [function\_arn](#output\_function\_arn) | n/a |
-| [function\_name](#output\_function\_name) | Name of AWS Lambda function |
+| Name | Description |
+|------------------------------------------------------------------------------------------------|--------------------------------------------------------------|
+| [arn](#output\_arn) | Amazon Resource Name (ARN) identifying your Lambda Function. |
+| [execution\_role\_arn](#output\_execution\_role\_arn) | Role arn of lambda |
+| [function\_arn](#output\_function\_arn) | function arn |
+| [function\_name](#output\_function\_name) | Name of AWS Lambda function |
diff --git a/main.tf b/main.tf
index 3f84240..763509a 100644
--- a/main.tf
+++ b/main.tf
@@ -59,7 +59,7 @@ module "s3" {
prefix = var.prefix
environment = var.environment
- bucket_name = format("%s-lambda-bucket", var.name)
+ bucket_name = var.is_edge ? format("%s-lambda-edge-bucket", var.name) : format("%s-lambda-bucket", var.name)
force_s3_destroy = true
@@ -78,6 +78,23 @@ resource "aws_s3_object" "this" {
tags = merge(local.tags, { "Name" = format("%s.zip", local.name) })
}
+/* -------------------------------------------------------------------------- */
+/* Resource Based Policy */
+/* -------------------------------------------------------------------------- */
+resource "aws_lambda_permission" "allow_serivce" {
+ for_each = var.lambda_permission_configuration
+
+ statement_id = format("AllowExecutionFrom-%s", each.key)
+ action = "lambda:InvokeFunction"
+ function_name = aws_lambda_function.this.function_name
+ principal = lookup(each.value, "pricipal", null)
+ source_arn = lookup(each.value, "source_arn", null)
+ source_account = lookup(each.value, "source_account", null)
+ # TODO Terraform aws says not support but doc support
+ # https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_permission#principal_org_id
+ # principal_org_id = lookup(each.value, "principal_org_id", "")
+}
+
/* -------------------------------------------------------------------------- */
/* IAM Role */
/* -------------------------------------------------------------------------- */
@@ -93,9 +110,11 @@ data "aws_iam_policy_document" "assume_role_policy_doc" {
principals {
type = "Service"
- identifiers = [
+ identifiers = var.is_edge ? [
"edgelambda.amazonaws.com",
"lambda.amazonaws.com",
+ ] : [
+ "lambda.amazonaws.com",
]
}
}
@@ -115,6 +134,33 @@ data "aws_iam_policy_document" "lambda_logs_policy_doc" {
}
}
+data "aws_iam_policy_document" "lambda_access_vpc" {
+ count = var.is_create_lambda_role ? 1 : 0
+
+ # Allow to connect to VPC
+ statement {
+ effect = "Allow"
+ actions = [
+ "ec2:CreateNetworkInterface",
+ "ec2:DescribeNetworkInterfaces",
+ "ec2:DeleteNetworkInterface",
+ "ec2:DescribeSecurityGroups",
+ "ec2:DescribeSubnets",
+ "ec2:DescribeVpcs"
+ ]
+ resources = ["*"]
+ }
+}
+
+data "aws_iam_policy_document" "lambda_policy" {
+ count = var.is_create_lambda_role ? 1 : 0
+
+ source_policy_documents = [
+ data.aws_iam_policy_document.lambda_logs_policy_doc[0].json,
+ data.aws_iam_policy_document.lambda_access_vpc[0].json
+ ]
+}
+
resource "aws_iam_role" "this" {
count = var.is_create_lambda_role ? 1 : 0
@@ -127,9 +173,9 @@ resource "aws_iam_role" "this" {
resource "aws_iam_role_policy" "logs_role_policy" {
count = var.is_create_lambda_role ? 1 : 0
- name = format("%s-lambda-at-edge-log-access-policy", local.name)
+ name = var.is_edge ? format("%s-lambda-at-edge-log-access-policy", local.name) : format("%s-lambda-log-access-policy", local.name)
role = aws_iam_role.this[0].id
- policy = data.aws_iam_policy_document.lambda_logs_policy_doc[0].json
+ policy = data.aws_iam_policy_document.lambda_policy[0].json
}
resource "aws_iam_role_policy_attachment" "this" {
@@ -201,10 +247,29 @@ resource "aws_lambda_function" "this" {
s3_object_version = aws_s3_object.this.version_id
source_code_hash = filebase64sha256(data.archive_file.zip_file.output_path)
- publish = true
+ # Specification
+ timeout = var.timeout
+ memory_size = var.memory_size
+ reserved_concurrent_executions = var.reserved_concurrent_executions
+
+ vpc_config {
+ security_group_ids = var.vpc_config.security_group_ids
+ subnet_ids = var.vpc_config.subnet_ids_to_associate
+ }
+
+ dynamic "dead_letter_config" {
+ for_each = var.dead_letter_target_arn == null ? [] : [true]
+ content {
+ target_arn = var.dead_letter_target_arn
+ }
+ }
+
+ # Code Env
+ publish = true # Force public new version
runtime = var.runtime
handler = var.handler
- role = local.lambda_role_arn
+
+ role = local.lambda_role_arn
lifecycle {
ignore_changes = [
@@ -221,8 +286,8 @@ resource "aws_lambda_function" "this" {
resource "aws_cloudwatch_log_group" "this" {
count = var.is_create_cloudwatch_log_group ? 1 : 0
- name = format("%s-lambda-log-group", local.name)
+ name = format("/aws/lambda/%s-function", local.name)
retention_in_days = var.retention_in_days
- tags = merge(local.tags, { "Name" = format("%s-lambda-log-group", local.name) })
+ tags = merge(local.tags, { "Name" = format("/aws/lambda/%s-function", local.name) })
}
diff --git a/variables.tf b/variables.tf
index 780811a..d7de2d1 100644
--- a/variables.tf
+++ b/variables.tf
@@ -44,18 +44,12 @@ variable "file_globs" {
variable "plaintext_params" {
description = <