diff --git a/README.md b/README.md index 12fdc69..fa41d3f 100644 --- a/README.md +++ b/README.md @@ -216,7 +216,7 @@ This guide provides a quick way to get started with our project. Please see our ### Setting Up the End-to-End Demo -#### Deploying the Initiator +#### Create the centralized log group 1. Clone repo: @@ -224,10 +224,48 @@ This guide provides a quick way to get started with our project. Please see our git clone https://github.com/unity-sds/unity-initiator.git ``` +1. Change directory to the location of the centralized log group terraform: + + ``` + cd unity-initiator/terraform-unity/centralized_log_group/ + ``` + +1. Set up environment variables for `project` (by default `uod`) and venue (by default `dev`): + + ``` + export PROJECT= + export VENUE= + ``` + +1. Initialize terraform: + + ``` + terraform init + ``` + +1. Run terraform apply: + + ``` + terraform apply \ + --var project=${PROJECT} \ + --var venue=${VENUE} \ + -auto-approve + ``` + + **Take note of the `centralized_log_group_name` that is output by terraform. It will be used when setting up other resources (e.g. initiator, trigger and evaluator lambdas).** + +1. Export the `centralized_log_group_name` that was output from the centralized log group terraform deployment: + + ``` + export CENTRALIZED_LOG_GROUP= + ``` + +#### Deploying the Initiator + 1. Change directory to the location of the inititator terraform: ``` - cd unity-initiator/terraform-unity/initiator/ + cd ../initiator/ ``` 1. You will need an S3 bucket for terraform to stage the router Lambda zip file and router configuration YAML file during deployment. Create one or reuse an existing one and set an environment variable for it: @@ -248,12 +286,6 @@ This guide provides a quick way to get started with our project. Please see our aws s3 cp test_router.yaml s3://${CODE_BUCKET}/test_router.yaml ``` -1. Set a project name: - - ``` - export PROJECT=gmanipon-test - ``` - 1. Initialize terraform: ``` @@ -265,6 +297,7 @@ This guide provides a quick way to get started with our project. Please see our ``` terraform apply \ --var project=${PROJECT} \ + --var venue=${VENUE} \ --var code_bucket=${CODE_BUCKET} \ --var router_config=s3://${CODE_BUCKET}/test_router.yaml \ -auto-approve @@ -272,6 +305,12 @@ This guide provides a quick way to get started with our project. Please see our **Take note of the `initiator_topic_arn` that is output by terraform. It will be used when setting up any triggers.** +1. Export the `initiator_topic_arn` that was output from the initiator terraform deployment: + + ``` + export INITIATOR_TOPIC_ARN= + ``` + #### Deploying Example Evaluators (SNS topic->SQS queue->Lambda) In this demo we will deploy 2 evaluators: @@ -320,6 +359,8 @@ In this demo we will deploy 2 evaluators: ``` terraform apply \ + --var project=${PROJECT} \ + --var venue=${VENUE} \ --var evaluator_name=${EVALUATOR_NAME} \ --var code_bucket=${CODE_BUCKET} \ -auto-approve @@ -361,6 +402,8 @@ In this demo we will deploy 2 evaluators: 1. Run terraform apply: ``` terraform apply \ + --var project=${PROJECT} \ + --var venue=${VENUE} \ --var evaluator_name=${EVALUATOR_NAME} \ --var code_bucket=${CODE_BUCKET} \ -auto-approve @@ -448,11 +491,12 @@ In this demo we will deploy 2 evaluators: terraform init ``` -1. Run terraform apply. Note the PROJECT and INITIATOR_TOPIC_ARN environment variables should have been set in the previous steps. If not set them again: +1. Run terraform apply. Note the PROJECT, VENUE and INITIATOR_TOPIC_ARN environment variables should have been set in the previous steps. If not set them again: ``` terraform apply \ --var project=${PROJECT} \ + --var venue=${VENUE} \ --var initiator_topic_arn=${INITIATOR_TOPIC_ARN} \ -auto-approve ``` @@ -505,6 +549,7 @@ In this demo we will deploy 2 evaluators: ``` terraform apply \ --var project=${PROJECT} \ + --var venue=${VENUE} \ --var code_bucket=${CODE_BUCKET} \ --var initiator_topic_arn=${INITIATOR_TOPIC_ARN} \ --var provider_id=${PROVIDER_ID} \ diff --git a/src/unity_initiator/cloud/lambda_handler.py b/src/unity_initiator/cloud/lambda_handler.py index e3c8b10..6f75484 100644 --- a/src/unity_initiator/cloud/lambda_handler.py +++ b/src/unity_initiator/cloud/lambda_handler.py @@ -7,7 +7,7 @@ from aws_xray_sdk.core import patch_all, xray_recorder from ..router import Router -from ..utils.logger import logger +from ..utils.logger import log_exceptions, logger # initialize the AWS X-Ray SDK patch_all() @@ -16,33 +16,34 @@ ROUTER = None -@xray_recorder.capture("lambda_handler_base") +@log_exceptions def lambda_handler_base(event, context): """Base lambda handler that instantiates a router, globally, and executes actions for a single payload.""" logger.info("context: %s", context) - # TODO: Should use AppConfig. For now, either reading router config body in ROUTER_CFG env variable - # or from a url in ROUTER_CFG_URL env variable. - global ROUTER - if ROUTER is None: - router_cfg = os.environ.get("ROUTER_CFG", "").strip() - router_cfg_url = os.environ.get("ROUTER_CFG_URL", "").strip() - if router_cfg == "": - if router_cfg_url != "": - with smart_open.open(router_cfg_url, "r") as f: - router_cfg = f.read() - else: - raise RuntimeError( - "No router configuration specified via ROUTER_CFG or ROUTER_CFG_URL env variables." - ) - fd, router_file = mkstemp(prefix="router_", suffix=".yaml", text=True) - with os.fdopen(fd, "w") as f: - f.write(router_cfg) - ROUTER = Router(router_file) - os.unlink(router_file) - xray_recorder.put_annotation("payload", event["payload"]) - return ROUTER.execute_actions(event["payload"]) + with xray_recorder.capture("lambda_handler_base"): + # TODO: Should use AppConfig. For now, either reading router config body in ROUTER_CFG env variable + # or from a url in ROUTER_CFG_URL env variable. + global ROUTER + if ROUTER is None: + router_cfg = os.environ.get("ROUTER_CFG", "").strip() + router_cfg_url = os.environ.get("ROUTER_CFG_URL", "").strip() + if router_cfg == "": + if router_cfg_url != "": + with smart_open.open(router_cfg_url, "r") as f: + router_cfg = f.read() + else: + raise RuntimeError( + "No router configuration specified via ROUTER_CFG or ROUTER_CFG_URL env variables." + ) + fd, router_file = mkstemp(prefix="router_", suffix=".yaml", text=True) + with os.fdopen(fd, "w") as f: + f.write(router_cfg) + ROUTER = Router(router_file) + os.unlink(router_file) + xray_recorder.put_annotation("payload", event["payload"]) + return ROUTER.execute_actions(event["payload"]) def lambda_handler_multiple_payloads(event, context): diff --git a/src/unity_initiator/utils/logger.py b/src/unity_initiator/utils/logger.py index 48a7c5a..c0fd8af 100644 --- a/src/unity_initiator/utils/logger.py +++ b/src/unity_initiator/utils/logger.py @@ -1,4 +1,6 @@ import logging +import traceback +from functools import wraps # set logger and custom filter log_format = "[%(asctime)s: %(levelname)s/%(funcName)s] %(message)s" @@ -16,3 +18,16 @@ def filter(self, record): logger = logging.getLogger("unity_initiator") logger.setLevel(logging.INFO) logger.addFilter(LogFilter()) + + +def log_exceptions(lambda_handler): + @wraps(lambda_handler) + def wrapper(event, context): + try: + return lambda_handler(event, context) + except Exception as err: + tb = traceback.format_exc() + logger.exception("Got exception: %s\n%s", str(err), tb) + raise + + return wrapper diff --git a/terraform-unity/centralized_log_group/.terraform.lock.hcl b/terraform-unity/centralized_log_group/.terraform.lock.hcl new file mode 100644 index 0000000..9639503 --- /dev/null +++ b/terraform-unity/centralized_log_group/.terraform.lock.hcl @@ -0,0 +1,45 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/aws" { + version = "5.65.0" + constraints = ">= 5.50.0" + hashes = [ + "h1:OG8xMZjGZL/OtEV9OwX0CTPcUzvSfcfiB0X9lcs2joY=", + "zh:036f8557c8c9b58656e1ec08ed5702e44bd338fda17dc4b2add40b234102e29a", + "zh:0ba0708ece98735540070899a916b7a90c5c887be31ffd693ee1359e40245978", + "zh:12d82a82ae0e3bc580f2be961078e89d129e12df7dd82a6ec610a2b945bba1a4", + "zh:1ed0ee17df8807aef64976e2a4276d2a3e1d54efeae2a86f596d12eccb94dc83", + "zh:36b7c61a83d24f612156b4648027ba8bd5727f0ed57183cbad0e6c93b7503aa2", + "zh:496d06a089b1bc8d60995e8dddfe1d87c605a208f377a60b17987e89381dafda", + "zh:4e9aba435994589befe4279927c71a461a52e6cd96b8f0437295c18c50f6baff", + "zh:71134031288a312db1804d4798b10f106a843c36aafd7b8fe8f4859156d7df93", + "zh:748d0dbdfbe8df4b516a09b23b3981c19cef9a255c1ca0187e84ab424e6bd845", + "zh:783541ff77f4e7c74c817e0e2989ebdb45dd6e2c9853a8cccbcf5f1976736a76", + "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", + "zh:af3f080975d5ed79917b8238cc0ae3150da688bc89e12dcc3ee85134b29857d0", + "zh:ec542372c3ffbfc3df6966f77357f8af7319d4bd956ff8e9fde0bbd124352e34", + "zh:f3dc7b2b5b55173207c2fd35ed6bb8cc66b06af777e221060ca2f0c0afdecbb5", + "zh:f9631ecc21d6e5cf82ef6ef8d14c39e1dfb2a52cc8f0abb684311885ffdb79a1", + ] +} + +provider "registry.terraform.io/hashicorp/local" { + version = "2.5.1" + constraints = ">= 2.5.1" + hashes = [ + "h1:/GAVA/xheGQcbOZEq0qxANOg+KVLCA7Wv8qluxhTjhU=", + "zh:0af29ce2b7b5712319bf6424cb58d13b852bf9a777011a545fac99c7fdcdf561", + "zh:126063ea0d79dad1f68fa4e4d556793c0108ce278034f101d1dbbb2463924561", + "zh:196bfb49086f22fd4db46033e01655b0e5e036a5582d250412cc690fa7995de5", + "zh:37c92ec084d059d37d6cffdb683ccf68e3a5f8d2eb69dd73c8e43ad003ef8d24", + "zh:4269f01a98513651ad66763c16b268f4c2da76cc892ccfd54b401fff6cc11667", + "zh:51904350b9c728f963eef0c28f1d43e73d010333133eb7f30999a8fb6a0cc3d8", + "zh:73a66611359b83d0c3fcba2984610273f7954002febb8a57242bbb86d967b635", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:7ae387993a92bcc379063229b3cce8af7eaf082dd9306598fcd42352994d2de0", + "zh:9e0f365f807b088646db6e4a8d4b188129d9ebdbcf2568c8ab33bddd1b82c867", + "zh:b5263acbd8ae51c9cbffa79743fbcadcb7908057c87eb22fd9048268056efbc4", + "zh:dfcd88ac5f13c0d04e24be00b686d069b4879cc4add1b7b1a8ae545783d97520", + ] +} diff --git a/terraform-unity/centralized_log_group/README.md b/terraform-unity/centralized_log_group/README.md new file mode 100644 index 0000000..7fabfd6 --- /dev/null +++ b/terraform-unity/centralized_log_group/README.md @@ -0,0 +1,40 @@ +# terraform-unity + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | ~> 1.8.2 | +| [aws](#requirement\_aws) | >=5.50.0 | +| [local](#requirement\_local) | >=2.5.1 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | 5.65.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_cloudwatch_log_group.centralized_log_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [project](#input\_project) | The unity project its installed into | `string` | `"uod"` | no | +| [venue](#input\_venue) | The unity venue its installed into | `string` | `"dev"` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [centralized\_log\_group\_name](#output\_centralized\_log\_group\_name) | The name of the centralized log group | + diff --git a/terraform-unity/centralized_log_group/locals.tf b/terraform-unity/centralized_log_group/locals.tf new file mode 100644 index 0000000..549d0d2 --- /dev/null +++ b/terraform-unity/centralized_log_group/locals.tf @@ -0,0 +1,15 @@ +locals { + log_group_name = "${var.project}-${var.venue}-initiator-centralized-log-group" + tags = { + Venue = "dev" + ServiceArea = "cs" + Capability = "initiator" + CapVersion = "0.0.1" + Component = "U-OD" + Name = "${var.project}-${var.venue}-cs-initiator-od" + Proj = var.project + CreatedBy = "cs" + Env = "dev" + Stack = "U-OD" + } +} diff --git a/terraform-unity/centralized_log_group/main.tf b/terraform-unity/centralized_log_group/main.tf new file mode 100644 index 0000000..dd1415b --- /dev/null +++ b/terraform-unity/centralized_log_group/main.tf @@ -0,0 +1,5 @@ +resource "aws_cloudwatch_log_group" "centralized_log_group" { + name = "/unity/log/${local.log_group_name}" + retention_in_days = 14 + tags = local.tags +} diff --git a/terraform-unity/centralized_log_group/output.tf b/terraform-unity/centralized_log_group/output.tf new file mode 100644 index 0000000..45e651e --- /dev/null +++ b/terraform-unity/centralized_log_group/output.tf @@ -0,0 +1,4 @@ +output "centralized_log_group_name" { + description = "The name of the centralized log group" + value = aws_cloudwatch_log_group.centralized_log_group.name +} diff --git a/terraform-unity/centralized_log_group/variables.tf b/terraform-unity/centralized_log_group/variables.tf new file mode 100644 index 0000000..cceab64 --- /dev/null +++ b/terraform-unity/centralized_log_group/variables.tf @@ -0,0 +1,11 @@ +variable "project" { + description = "The unity project its installed into" + type = string + default = "uod" +} + +variable "venue" { + description = "The unity venue its installed into" + type = string + default = "dev" +} diff --git a/terraform-unity/centralized_log_group/versions.tf b/terraform-unity/centralized_log_group/versions.tf new file mode 100644 index 0000000..6f93e3b --- /dev/null +++ b/terraform-unity/centralized_log_group/versions.tf @@ -0,0 +1,14 @@ +terraform { + required_version = "~> 1.8.2" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">=5.50.0" + } + local = { + source = "hashicorp/local" + version = ">=2.5.1" + } + } +} diff --git a/terraform-unity/evaluators/sns-sqs-lambda/README.md b/terraform-unity/evaluators/sns-sqs-lambda/README.md index 4626485..9d1aad5 100644 --- a/terraform-unity/evaluators/sns-sqs-lambda/README.md +++ b/terraform-unity/evaluators/sns-sqs-lambda/README.md @@ -27,7 +27,6 @@ No modules. | Name | Type | |------|------| -| [aws_cloudwatch_log_group.evaluator_lambda_log_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource | | [aws_iam_policy.evaluator_lambda_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | | [aws_iam_role.evaluator_lambda_iam_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | | [aws_iam_role_policy_attachment.aws_xray_write_only_access](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | @@ -35,6 +34,7 @@ No modules. | [aws_iam_role_policy_attachment.lambda_policy_attachment](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | | [aws_lambda_event_source_mapping.evaluator_queue_event_source_mapping](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_event_source_mapping) | resource | | [aws_lambda_function.evaluator_lambda](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_function) | resource | +| [aws_lambda_function_event_invoke_config.invoke_config](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_function_event_invoke_config) | resource | | [aws_s3_object.lambda_package](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_object) | resource | | [aws_sns_topic.evaluator_topic](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic) | resource | | [aws_sns_topic_policy.evaluator_topic_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic_policy) | resource | diff --git a/terraform-unity/evaluators/sns-sqs-lambda/lambda_handler.py b/terraform-unity/evaluators/sns-sqs-lambda/lambda_handler.py index d6494bc..efc63b9 100644 --- a/terraform-unity/evaluators/sns-sqs-lambda/lambda_handler.py +++ b/terraform-unity/evaluators/sns-sqs-lambda/lambda_handler.py @@ -2,7 +2,7 @@ from aws_xray_sdk.core import patch_all, xray_recorder -from unity_initiator.utils.logger import logger +from unity_initiator.utils.logger import log_exceptions, logger patch_all() @@ -17,6 +17,7 @@ def perform_evaluation(event, context): return True +@log_exceptions def lambda_handler(event, context): with xray_recorder.capture(context.function_name): return {"success": perform_evaluation(event, context)} diff --git a/terraform-unity/evaluators/sns-sqs-lambda/main.tf b/terraform-unity/evaluators/sns-sqs-lambda/main.tf index 15d6cb7..136c3d7 100644 --- a/terraform-unity/evaluators/sns-sqs-lambda/main.tf +++ b/terraform-unity/evaluators/sns-sqs-lambda/main.tf @@ -18,7 +18,7 @@ resource "aws_s3_object" "lambda_package" { } resource "aws_lambda_function" "evaluator_lambda" { - depends_on = [aws_s3_object.lambda_package, aws_cloudwatch_log_group.evaluator_lambda_log_group] + depends_on = [aws_s3_object.lambda_package] function_name = local.function_name s3_bucket = var.code_bucket s3_key = "${var.evaluator_name}-${jsondecode(data.local_file.version.content).version}-lambda.zip" @@ -31,11 +31,17 @@ resource "aws_lambda_function" "evaluator_lambda" { tracing_config { mode = "Active" } + + logging_config { + log_format = "Text" + log_group = "/unity/log/${var.project}-${var.venue}-initiator-centralized-log-group" + } } -resource "aws_cloudwatch_log_group" "evaluator_lambda_log_group" { - name = "/aws/lambda/${local.function_name}" - retention_in_days = 14 +resource "aws_lambda_function_event_invoke_config" "invoke_config" { + function_name = aws_lambda_function.evaluator_lambda.function_name + maximum_event_age_in_seconds = 21600 + maximum_retry_attempts = 0 } resource "aws_iam_role" "evaluator_lambda_iam_role" { diff --git a/terraform-unity/initiator/README.md b/terraform-unity/initiator/README.md index 8ca5aaf..64d43b7 100644 --- a/terraform-unity/initiator/README.md +++ b/terraform-unity/initiator/README.md @@ -26,7 +26,6 @@ No modules. | Name | Type | |------|------| -| [aws_cloudwatch_log_group.initiator_lambda](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource | | [aws_iam_policy.initiator_lambda_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | | [aws_iam_role.initiator_lambda_iam_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | | [aws_iam_role_policy_attachment.aws_xray_write_only_access](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | @@ -35,6 +34,7 @@ No modules. | [aws_iam_role_policy_attachment.lambda_sns_policy_attachment](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | | [aws_lambda_event_source_mapping.initiator_queue_event_source_mapping](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_event_source_mapping) | resource | | [aws_lambda_function.initiator_lambda](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_function) | resource | +| [aws_lambda_function_event_invoke_config.invoke_config](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_function_event_invoke_config) | resource | | [aws_s3_object.lambda_package](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_object) | resource | | [aws_sns_topic.initiator_topic](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic) | resource | | [aws_sns_topic_subscription.initiator_subscription](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic_subscription) | resource | diff --git a/terraform-unity/initiator/locals.tf b/terraform-unity/initiator/locals.tf index 1ee28d9..5c396bf 100644 --- a/terraform-unity/initiator/locals.tf +++ b/terraform-unity/initiator/locals.tf @@ -1,5 +1,5 @@ locals { - function_name = "${var.project}-${var.venue}-inititator" + function_name = "${var.project}-${var.venue}-initiator" tags = { Venue = "dev" ServiceArea = "cs" diff --git a/terraform-unity/initiator/main.tf b/terraform-unity/initiator/main.tf index 492c16c..bbbef22 100644 --- a/terraform-unity/initiator/main.tf +++ b/terraform-unity/initiator/main.tf @@ -18,8 +18,8 @@ resource "aws_s3_object" "lambda_package" { } resource "aws_lambda_function" "initiator_lambda" { - depends_on = [aws_s3_object.lambda_package, aws_cloudwatch_log_group.initiator_lambda] - function_name = "${var.project}-${var.venue}-inititator" + depends_on = [aws_s3_object.lambda_package] + function_name = "${var.project}-${var.venue}-initiator" s3_bucket = var.code_bucket s3_key = "unity_initiator-${jsondecode(data.local_file.version.content).version}-lambda.zip" handler = "unity_initiator.cloud.lambda_handler.lambda_handler_initiator" @@ -37,13 +37,18 @@ resource "aws_lambda_function" "initiator_lambda" { mode = "Active" } + logging_config { + log_format = "Text" + log_group = "/unity/log/${var.project}-${var.venue}-initiator-centralized-log-group" + } + tags = local.tags } -resource "aws_cloudwatch_log_group" "initiator_lambda" { - name = "/aws/lambda/${var.project}-${var.venue}-inititator" - retention_in_days = 14 - tags = local.tags +resource "aws_lambda_function_event_invoke_config" "invoke_config" { + function_name = aws_lambda_function.initiator_lambda.function_name + maximum_event_age_in_seconds = 21600 + maximum_retry_attempts = 0 } resource "aws_iam_role" "initiator_lambda_iam_role" { diff --git a/terraform-unity/triggers/cmr-query/README.md b/terraform-unity/triggers/cmr-query/README.md index 43c20ca..64511ff 100644 --- a/terraform-unity/triggers/cmr-query/README.md +++ b/terraform-unity/triggers/cmr-query/README.md @@ -27,7 +27,6 @@ No modules. | Name | Type | |------|------| -| [aws_cloudwatch_log_group.cmr_query_lambda_log_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource | | [aws_dynamodb_table.cmr_table](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/dynamodb_table) | resource | | [aws_iam_policy.dynamodb_crud_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | | [aws_iam_policy.scheduler](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | @@ -39,6 +38,7 @@ No modules. | [aws_iam_role_policy_attachment.lambda_sns_policy_attachment](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | | [aws_iam_role_policy_attachment.scheduler](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | | [aws_lambda_function.cmr_query_lambda](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_function) | resource | +| [aws_lambda_function_event_invoke_config.invoke_config](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_function_event_invoke_config) | resource | | [aws_s3_object.lambda_package](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_object) | resource | | [aws_scheduler_schedule.run_cmr_query](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/scheduler_schedule) | resource | | [null_resource.build_lambda_package](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource | diff --git a/terraform-unity/triggers/cmr-query/lambda_handler.py b/terraform-unity/triggers/cmr-query/lambda_handler.py index a378eb2..fe7dce9 100644 --- a/terraform-unity/triggers/cmr-query/lambda_handler.py +++ b/terraform-unity/triggers/cmr-query/lambda_handler.py @@ -6,7 +6,7 @@ from aws_xray_sdk.core import patch_all, xray_recorder from cmr import GranuleQuery -from unity_initiator.utils.logger import logger +from unity_initiator.utils.logger import log_exceptions, logger patch_all() @@ -32,6 +32,7 @@ def submit_urls_and_bookkeep(sns_client, urls_to_send, table, granules_to_save): return res +@log_exceptions def lambda_handler(event, context): logger.info("event: %s", json.dumps(event, indent=2)) logger.info("context: %s", context) diff --git a/terraform-unity/triggers/cmr-query/main.tf b/terraform-unity/triggers/cmr-query/main.tf index 95019b8..1e67814 100644 --- a/terraform-unity/triggers/cmr-query/main.tf +++ b/terraform-unity/triggers/cmr-query/main.tf @@ -113,7 +113,7 @@ resource "aws_iam_role_policy_attachment" "aws_xray_write_only_access" { } resource "aws_lambda_function" "cmr_query_lambda" { - depends_on = [aws_s3_object.lambda_package, aws_cloudwatch_log_group.cmr_query_lambda_log_group] + depends_on = [aws_s3_object.lambda_package] function_name = local.function_name s3_bucket = var.code_bucket s3_key = "cmr_query-${jsondecode(data.local_file.version.content).version}-lambda.zip" @@ -133,12 +133,18 @@ resource "aws_lambda_function" "cmr_query_lambda" { mode = "Active" } + logging_config { + log_format = "Text" + log_group = "/unity/log/${var.project}-${var.venue}-initiator-centralized-log-group" + } + tags = local.tags } -resource "aws_cloudwatch_log_group" "cmr_query_lambda_log_group" { - name = "/aws/lambda/${local.function_name}" - retention_in_days = 14 +resource "aws_lambda_function_event_invoke_config" "invoke_config" { + function_name = aws_lambda_function.cmr_query_lambda.function_name + maximum_event_age_in_seconds = 21600 + maximum_retry_attempts = 0 } resource "aws_iam_role" "scheduler" { diff --git a/terraform-unity/triggers/scheduled-task-instrumented/README.md b/terraform-unity/triggers/scheduled-task-instrumented/README.md index a1a2d80..ecdd896 100644 --- a/terraform-unity/triggers/scheduled-task-instrumented/README.md +++ b/terraform-unity/triggers/scheduled-task-instrumented/README.md @@ -27,7 +27,6 @@ No modules. | Name | Type | |------|------| -| [aws_cloudwatch_log_group.scheduled_task_lambda_log_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource | | [aws_iam_policy.scheduler](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | | [aws_iam_role.scheduled_task_lambda_iam_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | | [aws_iam_role.scheduler](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | @@ -36,6 +35,7 @@ No modules. | [aws_iam_role_policy_attachment.lambda_sns_policy_attachment](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | | [aws_iam_role_policy_attachment.scheduler](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | | [aws_lambda_function.scheduled_task_lambda](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_function) | resource | +| [aws_lambda_function_event_invoke_config.invoke_config](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_function_event_invoke_config) | resource | | [aws_s3_object.lambda_package](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_object) | resource | | [aws_scheduler_schedule.run_scheduled_task](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/scheduler_schedule) | resource | | [null_resource.build_lambda_package](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource | @@ -47,7 +47,6 @@ No modules. | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | [code\_bucket](#input\_code\_bucket) | The S3 bucket where lambda zip files will be stored and accessed | `string` | n/a | yes | -| [deployment\_name](#input\_deployment\_name) | The deployment name | `string` | n/a | yes | | [initiator\_topic\_arn](#input\_initiator\_topic\_arn) | The ARN of the initiator SNS topic to publish S3 events to | `string` | n/a | yes | | [project](#input\_project) | The unity project its installed into | `string` | `"uod"` | no | | [venue](#input\_venue) | The unity venue its installed into | `string` | `"dev"` | no | diff --git a/terraform-unity/triggers/scheduled-task-instrumented/lambda_handler.py b/terraform-unity/triggers/scheduled-task-instrumented/lambda_handler.py index 383c328..a14c09a 100644 --- a/terraform-unity/triggers/scheduled-task-instrumented/lambda_handler.py +++ b/terraform-unity/triggers/scheduled-task-instrumented/lambda_handler.py @@ -4,22 +4,24 @@ import boto3 from aws_xray_sdk.core import patch_all, xray_recorder -patch_all() +from unity_initiator.utils.logger import log_exceptions, logger +patch_all() INITIATOR_TOPIC_ARN = os.environ["INITIATOR_TOPIC_ARN"] +@log_exceptions def lambda_handler(event, context): - print(f"event: {json.dumps(event, indent=2)}") - print(f"context: {context}") + logger.info("event: %s", json.dumps(event, indent=2)) + logger.info("context: %s", context) # implement your adaptation-specific trigger code here and submit payloads # to the SNS topic as either a list of payloads or a single payload. Below # is an example of a single payload. # Finally return True if it successful. False otherwise. - with xray_recorder.capture("publish_url_to_inititator_topic"): + with xray_recorder.capture("publish_url_to_initiator_topic"): client = boto3.client("sns") res = client.publish( TopicArn=INITIATOR_TOPIC_ARN, diff --git a/terraform-unity/triggers/scheduled-task-instrumented/locals.tf b/terraform-unity/triggers/scheduled-task-instrumented/locals.tf index 68396e8..d7997ca 100644 --- a/terraform-unity/triggers/scheduled-task-instrumented/locals.tf +++ b/terraform-unity/triggers/scheduled-task-instrumented/locals.tf @@ -1,5 +1,5 @@ locals { - function_name = "${var.project}-${var.venue}-${var.deployment_name}-scheduled_task" + function_name = "${var.project}-${var.venue}-scheduled_task" tags = { Venue = "dev" ServiceArea = "cs" diff --git a/terraform-unity/triggers/scheduled-task-instrumented/main.tf b/terraform-unity/triggers/scheduled-task-instrumented/main.tf index aa6aad2..69313eb 100644 --- a/terraform-unity/triggers/scheduled-task-instrumented/main.tf +++ b/terraform-unity/triggers/scheduled-task-instrumented/main.tf @@ -52,7 +52,7 @@ resource "aws_iam_role_policy_attachment" "aws_xray_write_only_access" { } resource "aws_lambda_function" "scheduled_task_lambda" { - depends_on = [aws_s3_object.lambda_package, aws_cloudwatch_log_group.scheduled_task_lambda_log_group] + depends_on = [aws_s3_object.lambda_package] function_name = local.function_name s3_bucket = var.code_bucket s3_key = "scheduled_task-${jsondecode(data.local_file.version.content).version}-lambda.zip" @@ -71,16 +71,22 @@ resource "aws_lambda_function" "scheduled_task_lambda" { mode = "Active" } + logging_config { + log_format = "Text" + log_group = "/unity/log/${var.project}-${var.venue}-initiator-centralized-log-group" + } + tags = local.tags } -resource "aws_cloudwatch_log_group" "scheduled_task_lambda_log_group" { - name = "/aws/lambda/${local.function_name}" - retention_in_days = 14 +resource "aws_lambda_function_event_invoke_config" "invoke_config" { + function_name = aws_lambda_function.scheduled_task_lambda.function_name + maximum_event_age_in_seconds = 21600 + maximum_retry_attempts = 0 } resource "aws_iam_role" "scheduler" { - name = "${var.project}-${var.venue}-${var.deployment_name}-cron-scheduler-role" + name = "${var.project}-${var.venue}-cron-scheduler-role" assume_role_policy = jsonencode({ Version = "2012-10-17" Statement = [ @@ -98,7 +104,7 @@ resource "aws_iam_role" "scheduler" { } resource "aws_iam_policy" "scheduler" { - name = "${var.project}-${var.venue}-${var.deployment_name}-cron-scheduler-policy" + name = "${var.project}-${var.venue}-cron-scheduler-policy" policy = jsonencode({ Version = "2012-10-17" Statement = [ @@ -120,7 +126,7 @@ resource "aws_iam_role_policy_attachment" "scheduler" { } resource "aws_scheduler_schedule" "run_scheduled_task" { - name = "${var.project}-${var.venue}-${var.deployment_name}-run_scheduled_task" + name = "${var.project}-${var.venue}-run_scheduled_task" schedule_expression = "rate(1 minute)" flexible_time_window { mode = "OFF" diff --git a/terraform-unity/triggers/scheduled-task-instrumented/variables.tf b/terraform-unity/triggers/scheduled-task-instrumented/variables.tf index 56b95f9..237ffbb 100644 --- a/terraform-unity/triggers/scheduled-task-instrumented/variables.tf +++ b/terraform-unity/triggers/scheduled-task-instrumented/variables.tf @@ -1,8 +1,3 @@ -variable "deployment_name" { - description = "The deployment name" - type = string -} - variable "project" { description = "The unity project its installed into" type = string diff --git a/terraform-unity/triggers/scheduled-task/README.md b/terraform-unity/triggers/scheduled-task/README.md index 97d3743..163c4bd 100644 --- a/terraform-unity/triggers/scheduled-task/README.md +++ b/terraform-unity/triggers/scheduled-task/README.md @@ -26,7 +26,6 @@ No modules. | Name | Type | |------|------| -| [aws_cloudwatch_log_group.scheduled_task_lambda_log_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_group) | resource | | [aws_iam_policy.scheduler](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource | | [aws_iam_role.scheduled_task_lambda_iam_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | | [aws_iam_role.scheduler](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | @@ -34,6 +33,7 @@ No modules. | [aws_iam_role_policy_attachment.lambda_sns_policy_attachment](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | | [aws_iam_role_policy_attachment.scheduler](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | | [aws_lambda_function.scheduled_task_lambda](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_function) | resource | +| [aws_lambda_function_event_invoke_config.invoke_config](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_function_event_invoke_config) | resource | | [aws_scheduler_schedule.run_scheduled_task](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/scheduler_schedule) | resource | | [archive_file.lambda_zip_inline](https://registry.terraform.io/providers/hashicorp/archive/latest/docs/data-sources/file) | data source | | [aws_iam_policy.mcp_operator_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy) | data source | diff --git a/terraform-unity/triggers/scheduled-task/main.tf b/terraform-unity/triggers/scheduled-task/main.tf index 16eea3b..b944a7a 100644 --- a/terraform-unity/triggers/scheduled-task/main.tf +++ b/terraform-unity/triggers/scheduled-task/main.tf @@ -41,12 +41,19 @@ resource "aws_lambda_function" "scheduled_task_lambda" { INITIATOR_TOPIC_ARN = var.initiator_topic_arn } } + + logging_config { + log_format = "Text" + log_group = "/unity/log/${var.project}-${var.venue}-initiator-centralized-log-group" + } + tags = local.tags } -resource "aws_cloudwatch_log_group" "scheduled_task_lambda_log_group" { - name = "/aws/lambda/${local.function_name}" - retention_in_days = 14 +resource "aws_lambda_function_event_invoke_config" "invoke_config" { + function_name = aws_lambda_function.scheduled_task_lambda.function_name + maximum_event_age_in_seconds = 21600 + maximum_retry_attempts = 0 } resource "aws_iam_role" "scheduler" { diff --git a/tests/test_lambda.py b/tests/test_lambda.py index 1a2dfd8..c3168e5 100644 --- a/tests/test_lambda.py +++ b/tests/test_lambda.py @@ -50,9 +50,15 @@ def setup_mock_resources(): # create mock SNS topics sns_client = boto3.client("sns") - sns_client.create_topic(Name="eval_sbg_l2_readiness") - sns_client.create_topic(Name="eval_m2020_xyz_left_finder") - sns_client.create_topic(Name="eval_nisar_ingest") + sns_client.create_topic( + Name="eval_sbg_l2_readiness", Attributes={"TracingConfig": "Active"} + ) + sns_client.create_topic( + Name="eval_m2020_xyz_left_finder", Attributes={"TracingConfig": "Active"} + ) + sns_client.create_topic( + Name="eval_nisar_ingest", Attributes={"TracingConfig": "Active"} + ) # mock airflow REST API respx.post("https://example.com/api/v1/dags/eval_nisar_l0a_readiness/dagRuns").mock( @@ -174,6 +180,7 @@ def setup_class(cls): MemorySize=128, Publish=True, Environment={"Variables": {"ROUTER_CFG": cls.router_cfg}}, + TracingConfig={"Mode": "Active"}, ) @classmethod @@ -288,7 +295,9 @@ def setup_class(cls): # create mock SNS topic for initiator cls.sns_client = boto3.client("sns") - cls.sns_topic_initiator = cls.sns_client.create_topic(Name="initiator_topic") + cls.sns_topic_initiator = cls.sns_client.create_topic( + Name="initiator_topic", Attributes={"TracingConfig": "Active"} + ) # create mock SQS queues cls.sqs_client = boto3.client("sqs") @@ -356,6 +365,7 @@ def setup_class(cls): "ROUTER_CFG_URL": f"s3://{cls.bucket_name}/test_router.yaml" } }, + TracingConfig={"Mode": "Active"}, ) # create event source mapping diff --git a/tests/test_router.py b/tests/test_router.py index 12eeb93..bcd9728 100644 --- a/tests/test_router.py +++ b/tests/test_router.py @@ -64,7 +64,9 @@ def test_routing_sbg_url(): for evaluator in evaluators: assert isinstance(evaluator, Evaluator) assert evaluator.name == "eval_sbg_l2_readiness" - topic_arn = client.create_topic(Name=evaluator.name)["TopicArn"] + topic_arn = client.create_topic( + Name=evaluator.name, Attributes={"TracingConfig": "Active"} + )["TopicArn"] actions = list(evaluator.get_actions()) assert len(actions) == 1 for action in actions: @@ -83,7 +85,10 @@ def test_execute_actions_for_sbg_url(): client = boto3.client("sns") router_file = files("tests.resources").joinpath("test_router.yaml") router = Router(router_file) - client.create_topic(Name=list(router.get_evaluators_by_url(url))[0].name) + client.create_topic( + Name=list(router.get_evaluators_by_url(url))[0].name, + Attributes={"TracingConfig": "Active"}, + ) results = router.execute_actions(url) logger.info("results: %s", results) for res in results: @@ -103,7 +108,10 @@ def test_execute_actions_for_m2020_url(): "ML01234567891011121_000DSP_N01234567890101112131415161.VIC-link", ): url = f"s3://bucket/ids-pipeline/pipes/nonlin_xyz_left/inputque/{test_file}" - client.create_topic(Name=list(router.get_evaluators_by_url(url))[0].name) + client.create_topic( + Name=list(router.get_evaluators_by_url(url))[0].name, + Attributes={"TracingConfig": "Active"}, + ) results = router.execute_actions(url) logger.info("results: %s", results) for res in results: @@ -118,7 +126,10 @@ def test_execute_actions_for_nisar_telemetry_url(): client = boto3.client("sns") router_file = files("tests.resources").joinpath("test_router.yaml") router = Router(router_file) - client.create_topic(Name=list(router.get_evaluators_by_url(url))[0].name) + client.create_topic( + Name=list(router.get_evaluators_by_url(url))[0].name, + Attributes={"TracingConfig": "Active"}, + ) results = router.execute_actions(url) logger.info("results: %s", results) for res in results: @@ -157,7 +168,10 @@ def test_execute_actions_for_nisar_ldf_url(): client = boto3.client("sns") router_file = files("tests.resources").joinpath("test_router.yaml") router = Router(router_file) - client.create_topic(Name=list(router.get_evaluators_by_url(url))[0].name) + client.create_topic( + Name=list(router.get_evaluators_by_url(url))[0].name, + Attributes={"TracingConfig": "Active"}, + ) results = router.execute_actions(url) logger.info("results: %s", results) for res in results: