From 2f22759a3cf3774c7e29d4534de9da1012825989 Mon Sep 17 00:00:00 2001 From: Vaibhav Jain Date: Mon, 11 Sep 2023 12:19:08 -0400 Subject: [PATCH 1/3] msk-go-iam --- msk-lambda-iam-go-sam/HandlerKafka/go.mod | 7 + msk-lambda-iam-go-sam/HandlerKafka/go.sum | 13 ++ msk-lambda-iam-go-sam/HandlerKafka/main.go | 68 ++++++ .../HandlerKafka/main_test.go | 64 ++++++ msk-lambda-iam-go-sam/Makefile | 4 + msk-lambda-iam-go-sam/README.md | 208 ++++++++++++++++++ msk-lambda-iam-go-sam/events/event.json | 31 +++ msk-lambda-iam-go-sam/example-pattern.json | 90 ++++++++ msk-lambda-iam-go-sam/template.yaml | 82 +++++++ 9 files changed, 567 insertions(+) create mode 100644 msk-lambda-iam-go-sam/HandlerKafka/go.mod create mode 100644 msk-lambda-iam-go-sam/HandlerKafka/go.sum create mode 100644 msk-lambda-iam-go-sam/HandlerKafka/main.go create mode 100644 msk-lambda-iam-go-sam/HandlerKafka/main_test.go create mode 100644 msk-lambda-iam-go-sam/Makefile create mode 100644 msk-lambda-iam-go-sam/README.md create mode 100644 msk-lambda-iam-go-sam/events/event.json create mode 100644 msk-lambda-iam-go-sam/example-pattern.json create mode 100644 msk-lambda-iam-go-sam/template.yaml diff --git a/msk-lambda-iam-go-sam/HandlerKafka/go.mod b/msk-lambda-iam-go-sam/HandlerKafka/go.mod new file mode 100644 index 000000000..12240c967 --- /dev/null +++ b/msk-lambda-iam-go-sam/HandlerKafka/go.mod @@ -0,0 +1,7 @@ +require github.com/aws/aws-lambda-go v1.36.1 + +replace gopkg.in/yaml.v2 => gopkg.in/yaml.v2 v2.2.8 + +module HandlerKafka + +go 1.16 diff --git a/msk-lambda-iam-go-sam/HandlerKafka/go.sum b/msk-lambda-iam-go-sam/HandlerKafka/go.sum new file mode 100644 index 000000000..d1ee29f48 --- /dev/null +++ b/msk-lambda-iam-go-sam/HandlerKafka/go.sum @@ -0,0 +1,13 @@ +github.com/aws/aws-lambda-go v1.36.1 h1:CJxGkL9uKszIASRDxzcOcLX6juzTLoTKtCIgUGcTjTU= +github.com/aws/aws-lambda-go v1.36.1/go.mod h1:jwFe2KmMsHmffA1X2R09hH6lFzJQxzI8qK17ewzbQMM= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/msk-lambda-iam-go-sam/HandlerKafka/main.go b/msk-lambda-iam-go-sam/HandlerKafka/main.go new file mode 100644 index 000000000..56ad131a0 --- /dev/null +++ b/msk-lambda-iam-go-sam/HandlerKafka/main.go @@ -0,0 +1,68 @@ +package main + +import ( + "context" + b64 "encoding/base64" + "fmt" + "github.com/aws/aws-lambda-go/events" + "github.com/aws/aws-lambda-go/lambda" +) + +//Core lambda Kafka event handling logic + +func handler(ctx context.Context, kafkaEvent events.KafkaEvent) error { + + //Lambda Runtime delivers a batch of messages to the lambda function + //Each batch of messages has two fields EventSource and EventSourceARN + //Each batch of messages also has a field called Records + //The Records is a map with multiple keys and values + //Each key is a combination of the Topic Name and the Partition Number + //One batch of messages can contain messages from multiple partitions + eventSource := kafkaEvent.EventSource + eventSourceARN := kafkaEvent.EventSourceARN + records := kafkaEvent.Records + fmt.Println("EventSource = ", eventSource) + fmt.Println("EventSourceARN = ", eventSourceARN) + //Defining a variable to keep track of the message number in the batch + var i = 1 + //Now looping through the keys in the map + for key, arrayOfKafkaMessage := range records { + fmt.Println("This Key = ", key) + //Each key (topic-partition) can in turn have a number of messages + //Now looping through the messages in a particular key and getting fields in the message + for _, thisKafkaMessage := range arrayOfKafkaMessage { + fmt.Println("**********") + fmt.Println("Start of message ", i) + fmt.Println("Topic = ", thisKafkaMessage.Topic) + fmt.Println("Partition = ", thisKafkaMessage.Partition) + fmt.Println("Offset = ", thisKafkaMessage.Offset) + fmt.Println("Timestamp = ", thisKafkaMessage.Timestamp) + fmt.Println("TimestampType = ", thisKafkaMessage.TimestampType) + //Each message in turn has a key and a value which are base64 encoded and need to be decoded + var thisKafkaMessageKey = "null" + if thisKafkaMessage.Key != "" { + var thisKafkaMessageKeyBase64 = thisKafkaMessage.Key + var thisKafkaMessageKeyDecodedInByteArray, _ = b64.StdEncoding.DecodeString(thisKafkaMessageKeyBase64) + thisKafkaMessageKey = string(thisKafkaMessageKeyDecodedInByteArray) + } + fmt.Println("Key = ", thisKafkaMessageKey) + var thisKafkaMessageValue = "null" + if thisKafkaMessage.Value != "" { + var thisKafkaMessageValueBase64 = thisKafkaMessage.Value + var thisKafkaMessageValueDecodedInByteArray, _ = b64.StdEncoding.DecodeString(thisKafkaMessageValueBase64) + thisKafkaMessageValue = string(thisKafkaMessageValueDecodedInByteArray) + + } + fmt.Println("Value = ", thisKafkaMessageValue) + fmt.Println("End of message ", i) + fmt.Println("**********") + i = i + 1 + } + } + + return nil +} + +func main() { + lambda.Start(handler) +} diff --git a/msk-lambda-iam-go-sam/HandlerKafka/main_test.go b/msk-lambda-iam-go-sam/HandlerKafka/main_test.go new file mode 100644 index 000000000..bb1d2a2f1 --- /dev/null +++ b/msk-lambda-iam-go-sam/HandlerKafka/main_test.go @@ -0,0 +1,64 @@ +package main + +import ( + "fmt" + "net/http" + "net/http/httptest" + "testing" + + "github.com/aws/aws-lambda-go/events" +) + +func TestHandler(t *testing.T) { + t.Run("Unable to get IP", func(t *testing.T) { + DefaultHTTPGetAddress = "http://127.0.0.1:12345" + + _, err := handler(events.APIGatewayProxyRequest{}) + if err == nil { + t.Fatal("Error failed to trigger with an invalid request") + } + }) + + t.Run("Non 200 Response", func(t *testing.T) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(500) + })) + defer ts.Close() + + DefaultHTTPGetAddress = ts.URL + + _, err := handler(events.APIGatewayProxyRequest{}) + if err != nil && err.Error() != ErrNon200Response.Error() { + t.Fatalf("Error failed to trigger with an invalid HTTP response: %v", err) + } + }) + + t.Run("Unable decode IP", func(t *testing.T) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(500) + })) + defer ts.Close() + + DefaultHTTPGetAddress = ts.URL + + _, err := handler(events.APIGatewayProxyRequest{}) + if err == nil { + t.Fatal("Error failed to trigger with an invalid HTTP response") + } + }) + + t.Run("Successful Request", func(t *testing.T) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(200) + fmt.Fprintf(w, "127.0.0.1") + })) + defer ts.Close() + + DefaultHTTPGetAddress = ts.URL + + _, err := handler(events.APIGatewayProxyRequest{}) + if err != nil { + t.Fatal("Everything should be ok") + } + }) +} diff --git a/msk-lambda-iam-go-sam/Makefile b/msk-lambda-iam-go-sam/Makefile new file mode 100644 index 000000000..a6699b6e8 --- /dev/null +++ b/msk-lambda-iam-go-sam/Makefile @@ -0,0 +1,4 @@ +.PHONY: build + +build: + sam build diff --git a/msk-lambda-iam-go-sam/README.md b/msk-lambda-iam-go-sam/README.md new file mode 100644 index 000000000..10b77d615 --- /dev/null +++ b/msk-lambda-iam-go-sam/README.md @@ -0,0 +1,208 @@ +# Golang AWS Lambda Kafka consumer with IAM auth, using AWS SAM + +This pattern is an example of a Lambda function that consumes messages from an Amazon Managed Streaming for Kafka (Amazon MSK) topic, where the MSK Cluster has been configured to use IAM authentication. This pattern assumes you already have an MSK cluster with a topic configured, if you need a sample pattern to deploy an MSK cluster either in Provisioned or Serverless modes please see the [msk-cfn-sasl-lambda pattern](https://serverlessland.com/patterns/msk-cfn-sasl-lambda). + +This project contains source code and supporting files for a serverless application that you can deploy with the AWS Serverless Application Model (AWS SAM) CLI. It includes the following files and folders. + + +```bash +. +├── Makefile <-- Make to automate build +├── README.md <-- This instructions file +├── HandlerKafka <-- Source code for a lambda function +│ ├── main.go <-- Lambda function code +│ └── main_test.go <-- Unit tests +└── template.yaml +``` + +The application creates a Lambda function that listens to Kafka messages on a topic of an MSK Cluster. These resources are defined in the `template.yaml` file in this project. You can update the template to add AWS resources through the same deployment process that updates your application code. + +Important: this application uses various AWS services and there are costs associated with these services after the Free Tier usage - please see the [AWS Pricing page](https://aws.amazon.com/pricing/) for details. You are responsible for any AWS costs incurred. No warranty is implied in this example. + +## Requirements + +* [Create an AWS account](https://portal.aws.amazon.com/gp/aws/developer/registration/index.html) if you do not already have one and log in. The IAM user that you use must have sufficient permissions to make necessary AWS service calls and manage AWS resources. +* [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) installed and configured +* [Git installed](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) +* [AWS Serverless Application Model](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html) (AWS SAM) installed +* [Docker installed](https://www.docker.com/community-edition) +* [Golang](https://golang.org) +* Create MSK cluster and topic that will be used for testing. It is important to create the topic before deploying the Lambda function, otherwise the event source mapping will stay disabled. + +## Deploy the sample application + +The AWS SAM CLI is a serverless tool for building and testing Lambda applications. It uses Docker to locally test your functions in an Amazon Linux environment that resembles the Lambda execution environment. It can also emulate your application's build environment and API. + +To use the AWS SAM CLI, you need the following tools. + +* AWS SAM CLI - [Install the AWS SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html) +* Docker - [Install Docker community edition](https://hub.docker.com/search/?type=edition&offering=community) + +In this example we use the built-in `sam build` to automatically download all the dependencies and package our build target. +Read more about [SAM Build here](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-build.html) + + +1. Create a new directory, navigate to that directory in a terminal and clone the GitHub repository: + ``` + git clone https://github.com/aws-samples/serverless-patterns.git + ``` +1. Change directory to the pattern directory: + ``` + cd msk-lambda-iam-python-sam + ``` + +1. The `sam build` command is wrapped inside of the `Makefile`. + + ```shell + make + ``` + +AWS Lambda Golang runtime requires a flat folder with the executable generated on build step. SAM will use `CodeUri` property to know where to look up for the application: + +```yaml +... + FirstFunction: + Type: AWS::Serverless::Function + Properties: + CodeUri: hello_world/ + ... +``` + +1. To deploy your application for the first time, run the following in your shell: + +```bash +sam deploy --guided +``` + +1. During the prompts: +* **Stack Name**: The name of the stack to deploy to CloudFormation. This should be unique to your account and region, and a good starting point would be something matching your project name. +* **AWS Region**: The AWS region you want to deploy your app to. +* **Parameter MSKClusterName**: The name of the MSKCluster, eg. msk-test-cluster + +* **Parameter MSKClusterId**: The unique ID of the MSKCluster, eg. a4e132c8-6ad0-4334-a313-123456789012-s2 +* **Parameter MSKTopic**: The Kafka topic on which the lambda function will listen on +* **Confirm changes before deploy**: If set to yes, any change sets will be shown to you before execution for manual review. If set to no, the AWS SAM CLI will automatically deploy application changes. +* **Allow SAM CLI IAM role creation**: Many AWS SAM templates, including this example, create AWS IAM roles required for the AWS Lambda function(s) included to access AWS services. By default, these are scoped down to minimum required permissions. To deploy an AWS CloudFormation stack which creates or modifies IAM roles, the `CAPABILITY_IAM` value for `capabilities` must be provided. If permission isn't provided through this prompt, to deploy this example you must explicitly pass `--capabilities CAPABILITY_IAM` to the `sam deploy` command. +* **Disable rollback**: Defaults to No and it preserves the state of previously provisioned resources when an operation fails +* **Save arguments to configuration file**: If set to yes, your choices will be saved to a configuration file inside the project, so that in the future you can just re-run `sam deploy` without parameters to deploy changes to your application. +* **SAM configuration file [samconfig.toml]**: Name of the configuration file to store configuration information locally +* **SAM configuration environment [default]**: Environment for storing deployment information locally + +You should get a message "Successfully created/updated stack - in " if all goes well. + +Once you have run `sam deploy --guided` mode once and saved arguments to a configuration file (samconfig.toml), you can use `sam deploy` in future to use these defaults. + +## How it works + +This pattern creates a Lambda function along with a Lambda Event Source Mapping(ESM) resource. This maps a Kafka topic on an MSK Cluster as a trigger to a Lambda function. The ESM takes care of polling the Kafka topic and then invokes the Lambda function with a batch of messages. + +## Test the sample application + +Once the Lambda function is deployed, send some Kafka messages to the topic that you configured in the Lambda function trigger. + +Either send at least 10 messages or wait for 300 seconds (check the values of BatchSize: 10 and MaximumBatchingWindowInSeconds: 300 in the template.yaml file) + +Then check Amazon CloudWatch logs and you should see messages in the CloudWatch Log Group with the name of the deployed Lambda function. + +The Lambda code parses the Kafka messages and outputs the fields in the Kafka messages to CloudWatch logs. + +A single Lambda function receives a batch of messages. The messages are received as a map with each key being a combination of the topic and the partition, as a single batch can receive messages from multiple partitions. + +Each key has a list of messages. Each Kafka message has the following properties - `Topic`, `Partition`, `Offset`, `TimeStamp`, `TimeStampType`, `Key`, and `Value`. + +The `Key` and `Value` are base64 encoded and have to be decoded. A message can also have a list of headers, each header having a key and a value. + +The code in this example prints out the fields in the Kafka message and also decrypts the key and the value and logs them to CloudWatch logs. + + +### Local development + +**You can invoke the function locally using `sam local`** + +```bash +sam local invoke --event=events/event.json +``` + +You should see a response similar to the below + +`START RequestId: 5c10310a-abf9-416e-b017-697d2c3ba097 Version: $LATEST +Received an event: {'eventSource': 'aws:kafka', 'eventSourceArn': 'arn:aws:kafka:us-west-2:123456789012:cluster/MSKWorkshopCluster/a93759a9-c9d0-4952-984c-492c6bfa2be8-13', 'bootstrapServers': 'b-1.mskworkshopcluster.z9kc4f.c13.kafka.us-west-2.amazonaws.com:9098,b-3.mskworkshopcluster.z9kc4f.c13.kafka.us-west-2.amazonaws.com:9098,b-2.mskworkshopcluster.z9kc4f.c13.kafka.us-west-2.amazonaws.com:9098', 'records': {'myTopic-0': [{'topic': 'myTopic', 'partition': 0, 'offset': 383, 'timestamp': 1678484822068, 'timestampType': 'CREATE_TIME', 'value': 'bTE=', 'headers': []}, {'topic': 'myTopic', 'partition': 0, 'offset': 384, 'timestamp': 1678484823448, 'timestampType': 'CREATE_TIME', 'value': 'bTI=', 'headers': []}, {'topic': 'myTopic', 'partition': 0, 'offset': 385, 'timestamp': 1678484824763, 'timestampType': 'CREATE_TIME', 'value': 'bTM=', 'headers': []}, {'topic': 'myTopic', 'partition': 0, 'offset': 386, 'timestamp': 1678484825902, 'timestampType': 'CREATE_TIME', 'value': 'bTQ=', 'headers': []}, {'topic': 'myTopic', 'partition': 0, 'offset': 387, 'timestamp': 1678484827810, 'timestampType': 'CREATE_TIME', 'value': 'bTU=', 'headers': []}]}} +Event Source: aws:kafka +Event Source ARN: arn:aws:kafka:us-west-2:123456789012:cluster/MSKWorkshopCluster/a93759a9-c9d0-4952-984c-492c6bfa2be8-13 +Bootstrap Servers: b-1.mskworkshopcluster.z9kc4f.c13.kafka.us-west-2.amazonaws.com:9098,b-3.mskworkshopcluster.z9kc4f.c13.kafka.us-west-2.amazonaws.com:9098,b-2.mskworkshopcluster.z9kc4f.c13.kafka.us-west-2.amazonaws.com:9098 +Records: {'myTopic-0': [{'topic': 'myTopic', 'partition': 0, 'offset': 383, 'timestamp': 1678484822068, 'timestampType': 'CREATE_TIME', 'value': 'bTE=', 'headers': []}, {'topic': 'myTopic', 'partition': 0, 'offset': 384, 'timestamp': 1678484823448, 'timestampType': 'CREATE_TIME', 'value': 'bTI=', 'headers': []}, {'topic': 'myTopic', 'partition': 0, 'offset': 385, 'timestamp': 1678484824763, 'timestampType': 'CREATE_TIME', 'value': 'bTM=', 'headers': []}, {'topic': 'myTopic', 'partition': 0, 'offset': 386, 'timestamp': 1678484825902, 'timestampType': 'CREATE_TIME', 'value': 'bTQ=', 'headers': []}, {'topic': 'myTopic', 'partition': 0, 'offset': 387, 'timestamp': 1678484827810, 'timestampType': 'CREATE_TIME', 'value': 'bTU=', 'headers': []}]} +Current Record: [{'topic': 'myTopic', 'partition': 0, 'offset': 383, 'timestamp': 1678484822068, 'timestampType': 'CREATE_TIME', 'value': 'bTE=', 'headers': []}, {'topic': 'myTopic', 'partition': 0, 'offset': 384, 'timestamp': 1678484823448, 'timestampType': 'CREATE_TIME', 'value': 'bTI=', 'headers': []}, {'topic': 'myTopic', 'partition': 0, 'offset': 385, 'timestamp': 1678484824763, 'timestampType': 'CREATE_TIME', 'value': 'bTM=', 'headers': []}, {'topic': 'myTopic', 'partition': 0, 'offset': 386, 'timestamp': 1678484825902, 'timestampType': 'CREATE_TIME', 'value': 'bTQ=', 'headers': []}, {'topic': 'myTopic', 'partition': 0, 'offset': 387, 'timestamp': 1678484827810, 'timestampType': 'CREATE_TIME', 'value': 'bTU=', 'headers': []}]` +******************** +Now printing details of record number: 1 +Topic: myTopic +Partition: 0 +Offset: 383 +Topic: myTopic +Timestamp: 1678484822068 +TimestampType: CREATE_TIME +Key = null +Value = m1 +Now finished printing details of record number: 1 +******************** +******************** +Now printing details of record number: 2 +Topic: myTopic +Partition: 0 +Offset: 384 +Topic: myTopic +Timestamp: 1678484823448 +TimestampType: CREATE_TIME +Key = null +Value = m2 +Now finished printing details of record number: 2 +******************** +******************** +Now printing details of record number: 3 +Topic: myTopic +Partition: 0 +Offset: 385 +Topic: myTopic +Timestamp: 1678484824763 +TimestampType: CREATE_TIME +Key = null +Value = m3 +Now finished printing details of record number: 3 +******************** +******************** +Now printing details of record number: 4 +Topic: myTopic +Partition: 0 +Offset: 386 +Topic: myTopic +Timestamp: 1678484825902 +TimestampType: CREATE_TIME +Key = null +Value = m4 +Now finished printing details of record number: 4 +******************** +******************** +Now printing details of record number: 5 +Topic: myTopic +Partition: 0 +Offset: 387 +Topic: myTopic +Timestamp: 1678484827810 +TimestampType: CREATE_TIME +Key = null +Value = m5 +Now finished printing details of record number: 5 +******************** +END RequestId: 5c10310a-abf9-416e-b017-697d2c3ba097 +REPORT RequestId: 5c10310a-abf9-416e-b017-697d2c3ba097 Init Duration: 6.68 ms Duration: 1502.83 ms Billed Duration: 1503 ms Memory Size: 128 MB Max Memory Used: 128 MB + +## Cleanup + +1. Delete the stack + ```bash + sam delete + ``` + +---- +Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. + +SPDX-License-Identifier: MIT-0 diff --git a/msk-lambda-iam-go-sam/events/event.json b/msk-lambda-iam-go-sam/events/event.json new file mode 100644 index 000000000..b527986ab --- /dev/null +++ b/msk-lambda-iam-go-sam/events/event.json @@ -0,0 +1,31 @@ +{ + "records":{ + "myTopic-0":[ + { + "topic":"myTopic", + "partition":0, + "offset":250, + "timestamp":1678072110111, + "timestampType":"CREATE_TIME", + "value":"Zg==", + "headers":[ + + ] + }, + { + "topic":"myTopic", + "partition":0, + "offset":251, + "timestamp":1678072111086, + "timestampType":"CREATE_TIME", + "value":"Zw==", + "headers":[ + + ] + } + ] + }, + "eventSource":"aws:kafka", + "eventSourceArn":"arn:aws:kafka:us-west-2:123456789012:cluster/MSKWorkshopCluster/a93759a9-c9d0-4952-984c-492c6bfa2be8-13", + "bootstrapServers":"b-2.mskworkshopcluster.z9kc4f.c13.kafka.us-west-2.amazonaws.com:9098,b-3.mskworkshopcluster.z9kc4f.c13.kafka.us-west-2.amazonaws.com:9098,b-1.mskworkshopcluster.z9kc4f.c13.kafka.us-west-2.amazonaws.com:9098" +} \ No newline at end of file diff --git a/msk-lambda-iam-go-sam/example-pattern.json b/msk-lambda-iam-go-sam/example-pattern.json new file mode 100644 index 000000000..6d79b62c6 --- /dev/null +++ b/msk-lambda-iam-go-sam/example-pattern.json @@ -0,0 +1,90 @@ + { + "title": "AWS Lambda function subscribed to an Amazon MSK topic using IAM auth", + "description": "Creates a Lambda function that uses an Amazon MSK topic as an event source with IAM authentication.", + "language": "Go", + "level": "200", + "framework": "SAM", + "introBox": { + "headline": "How it works", + "text": [ + "This pattern provides a Lambda function along with an Event Source Mapping to a Kafka topic.", + "It requires that you already have an Amazon Managed Streaming for Kafka(Amazon MSK) cluster setup with a topic created. If you don't already have an MSK cluster ", + "you can use the example in this pattern https://serverlessland.com/patterns/msk-cfn-sasl-lambda (linked in the resources) to deploy a cluster.", + "This pattern works with either a Provisioned or Serverless MSK cluster as long as the cluster is configured to use IAM authentication. ", + "For detailed deployment instructions instructions see the README " + ] + }, + "gitHub": { + "template": { + "repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/msk-lambda-go-sam", + "templateURL": "serverless-patterns/msk-lambda-go-sam", + "projectFolder": "msk-lambda-go-sam", + "templateFile": "template.yml" + } + }, + "resources": { + "bullets": [ + { + "text": "Amazon MSK Cluster pattern", + "link": "https://serverlessland.com/patterns/msk-cfn-sasl-lambda" + }, + { + "text": "Using AWS Lambda with Amazon MSK", + "link": "https://docs.aws.amazon.com/lambda/latest/dg/with-msk.html" + }, + { + "text": "AWS CloudFormation Provisioned MSK cluster reference", + "link": "https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-msk-cluster.html" + }, + { + "text": "AWS CloudFormation Serverless MSK cluster reference", + "link": "https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-msk-serverlesscluster.html" + } + ] + }, + "deploy": { + "text": [ + "sam deploy --guided" + ] + }, + "testing": { + "text": [ + "See the GitHub repo for detailed testing instructions." + ] + }, + "cleanup": { + "text": [ + "Delete the template: sam delete." + ] + }, + "authors": [ + { + "name": "Vaibhav Jain", + "bio": "AWS - Sr. Application Architect", + "image": "https://media.licdn.com/dms/image/C4E03AQEqzZWHGT4dBQ/profile-displayphoto-shrink_800_800/0/1580165399872?e=1687392000&v=beta&t=zdxENLnqCpqCz9i1Uf5Yx4YXlR9EYvgxP8N5UTsy6J8", + "linkedin": "https://www.linkedin.com/in/vaibhavjainv/" + }, + { + "name": "Paveen Allam", + "bio": "Senior Solutions Architect", + "image": "https://www.fintail.me/images/pa.jpg", + "linkedin": "https://www.linkedin.com/in/pallam/" + }, + { + "name": "Suraj Tripathi", + "bio": "AWS - AppDev Cloud Consultant", + "linkedin": "https://www.linkedin.com/in/suraj-tripathi-01b49a140/" + }, + { + "name": "Adam Wagner", + "bio": "AWS - Principal Serverless Solutions Architect", + "linkedin": "https://www.linkedin.com/in/adam-wagner-4bb412/" + }, + { + "name": "Indranil Banerjee", + "bio": "AWS - Senior Solutions Architect", + "linkedin": "https://www.linkedin.com/in/indranil-banerjee-b00a261/" + } + ] + } + \ No newline at end of file diff --git a/msk-lambda-iam-go-sam/template.yaml b/msk-lambda-iam-go-sam/template.yaml new file mode 100644 index 000000000..20536026e --- /dev/null +++ b/msk-lambda-iam-go-sam/template.yaml @@ -0,0 +1,82 @@ +AWSTemplateFormatVersion: '2010-09-09' +Transform: AWS::Serverless-2016-10-31 +Description: > + lambda-msk-consumer-go + + Sample SAM Template for lambda-msk-consumer-go + +# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst +Globals: + Function: + Timeout: 15 + +Resources: + HelloWorldGoKafkaFunction: + Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction + Properties: + CodeUri: HandlerKafka/ + Handler: handler + Runtime: go1.x + Architectures: + - x86_64 + Events: + MSKEvent: + Type: MSK + Properties: + StartingPosition: LATEST + BatchSize: 10 + MaximumBatchingWindowInSeconds: 300 + Stream: !Join [ '', ["arn:", "aws:", "kafka:", !Ref "AWS::Region" , ":" ,!Ref "AWS::AccountId", ":", "cluster/", !Ref MSKClusterName, "/" , !Ref MSKClusterId] ] + Topics: + - !Ref MSKTopic + Policies: + - Statement: + - Sid: KafkaClusterPermissionsPolicy + Effect: Allow + Action: + - kafka-cluster:Connect + - kafka-cluster:DescribeGroup + - kafka-cluster:DescribeCluster + - kafka-cluster:AlterCluster + - kafka-cluster:AlterClusterDynamicConfiguration + - kafka-cluster:WriteDataIdempotently + - kafka-cluster:AlterGroup + - kafka-cluster:DescribeTopic + - kafka-cluster:ReadData + - kafka-cluster:DescribeClusterDynamicConfiguration + Resource: + - !Join ['', ["arn:", "aws:", "kafka:", !Ref "AWS::Region", ":", !Ref "AWS::AccountId", ":", "cluster/", !Ref MSKClusterName, "/" , !Ref MSKClusterId]] + - !Join ['', ["arn:", "aws:", "kafka:", !Ref "AWS::Region", ":", !Ref "AWS::AccountId", ":", "topic/", !Ref MSKClusterName, "/" , !Ref MSKClusterId, "/*"]] + - !Join ['', ["arn:", "aws:", "kafka:", !Ref "AWS::Region", ":", !Ref "AWS::AccountId", ":", "group/", !Ref MSKClusterName, "/" , !Ref MSKClusterId, "/*"]] + + - Sid: KafkaPermissionsPolicy + Effect: Allow + Action: + - kafka:DescribeClusterV2 + - kafka:GetBootstrapBrokers + Resource: '*' + + - Sid: EC2PermissionsPolicy + Effect: Allow + Action: + - ec2:DescribeSecurityGroups + - ec2:DescribeSubnets + - ec2:DescribeVpcs + - ec2:CreateNetworkInterface + - ec2:DescribeNetworkInterfaces + - ec2:DeleteNetworkInterface + Resource: '*' +Parameters: + MSKClusterName: + Type: String + Description: Enter the name of the MSK Cluster + MSKClusterId: + Type: String + Description: Enter the ID of the MSK Cluster + MSKTopic: + Type: String + Description: Enter the name of the MSK Topic +Outputs: + HelloWorldGoKafkaFunction: + Description: "Topic Consumer Lambda Function ARN" + Value: !GetAtt HelloWorldGoKafkaFunction.Arn From 474df3bfd30e4d4c9c2c399f80de14c25a4c43ec Mon Sep 17 00:00:00 2001 From: Vaibhav Jain Date: Mon, 11 Sep 2023 12:21:35 -0400 Subject: [PATCH 2/3] updated readme --- msk-lambda-iam-go-sam/README.md | 97 ++++++++++----------------------- 1 file changed, 28 insertions(+), 69 deletions(-) diff --git a/msk-lambda-iam-go-sam/README.md b/msk-lambda-iam-go-sam/README.md index 10b77d615..37a0c7a98 100644 --- a/msk-lambda-iam-go-sam/README.md +++ b/msk-lambda-iam-go-sam/README.md @@ -125,75 +125,34 @@ sam local invoke --event=events/event.json You should see a response similar to the below -`START RequestId: 5c10310a-abf9-416e-b017-697d2c3ba097 Version: $LATEST -Received an event: {'eventSource': 'aws:kafka', 'eventSourceArn': 'arn:aws:kafka:us-west-2:123456789012:cluster/MSKWorkshopCluster/a93759a9-c9d0-4952-984c-492c6bfa2be8-13', 'bootstrapServers': 'b-1.mskworkshopcluster.z9kc4f.c13.kafka.us-west-2.amazonaws.com:9098,b-3.mskworkshopcluster.z9kc4f.c13.kafka.us-west-2.amazonaws.com:9098,b-2.mskworkshopcluster.z9kc4f.c13.kafka.us-west-2.amazonaws.com:9098', 'records': {'myTopic-0': [{'topic': 'myTopic', 'partition': 0, 'offset': 383, 'timestamp': 1678484822068, 'timestampType': 'CREATE_TIME', 'value': 'bTE=', 'headers': []}, {'topic': 'myTopic', 'partition': 0, 'offset': 384, 'timestamp': 1678484823448, 'timestampType': 'CREATE_TIME', 'value': 'bTI=', 'headers': []}, {'topic': 'myTopic', 'partition': 0, 'offset': 385, 'timestamp': 1678484824763, 'timestampType': 'CREATE_TIME', 'value': 'bTM=', 'headers': []}, {'topic': 'myTopic', 'partition': 0, 'offset': 386, 'timestamp': 1678484825902, 'timestampType': 'CREATE_TIME', 'value': 'bTQ=', 'headers': []}, {'topic': 'myTopic', 'partition': 0, 'offset': 387, 'timestamp': 1678484827810, 'timestampType': 'CREATE_TIME', 'value': 'bTU=', 'headers': []}]}} -Event Source: aws:kafka -Event Source ARN: arn:aws:kafka:us-west-2:123456789012:cluster/MSKWorkshopCluster/a93759a9-c9d0-4952-984c-492c6bfa2be8-13 -Bootstrap Servers: b-1.mskworkshopcluster.z9kc4f.c13.kafka.us-west-2.amazonaws.com:9098,b-3.mskworkshopcluster.z9kc4f.c13.kafka.us-west-2.amazonaws.com:9098,b-2.mskworkshopcluster.z9kc4f.c13.kafka.us-west-2.amazonaws.com:9098 -Records: {'myTopic-0': [{'topic': 'myTopic', 'partition': 0, 'offset': 383, 'timestamp': 1678484822068, 'timestampType': 'CREATE_TIME', 'value': 'bTE=', 'headers': []}, {'topic': 'myTopic', 'partition': 0, 'offset': 384, 'timestamp': 1678484823448, 'timestampType': 'CREATE_TIME', 'value': 'bTI=', 'headers': []}, {'topic': 'myTopic', 'partition': 0, 'offset': 385, 'timestamp': 1678484824763, 'timestampType': 'CREATE_TIME', 'value': 'bTM=', 'headers': []}, {'topic': 'myTopic', 'partition': 0, 'offset': 386, 'timestamp': 1678484825902, 'timestampType': 'CREATE_TIME', 'value': 'bTQ=', 'headers': []}, {'topic': 'myTopic', 'partition': 0, 'offset': 387, 'timestamp': 1678484827810, 'timestampType': 'CREATE_TIME', 'value': 'bTU=', 'headers': []}]} -Current Record: [{'topic': 'myTopic', 'partition': 0, 'offset': 383, 'timestamp': 1678484822068, 'timestampType': 'CREATE_TIME', 'value': 'bTE=', 'headers': []}, {'topic': 'myTopic', 'partition': 0, 'offset': 384, 'timestamp': 1678484823448, 'timestampType': 'CREATE_TIME', 'value': 'bTI=', 'headers': []}, {'topic': 'myTopic', 'partition': 0, 'offset': 385, 'timestamp': 1678484824763, 'timestampType': 'CREATE_TIME', 'value': 'bTM=', 'headers': []}, {'topic': 'myTopic', 'partition': 0, 'offset': 386, 'timestamp': 1678484825902, 'timestampType': 'CREATE_TIME', 'value': 'bTQ=', 'headers': []}, {'topic': 'myTopic', 'partition': 0, 'offset': 387, 'timestamp': 1678484827810, 'timestampType': 'CREATE_TIME', 'value': 'bTU=', 'headers': []}]` -******************** -Now printing details of record number: 1 -Topic: myTopic -Partition: 0 -Offset: 383 -Topic: myTopic -Timestamp: 1678484822068 -TimestampType: CREATE_TIME -Key = null -Value = m1 -Now finished printing details of record number: 1 -******************** -******************** -Now printing details of record number: 2 -Topic: myTopic -Partition: 0 -Offset: 384 -Topic: myTopic -Timestamp: 1678484823448 -TimestampType: CREATE_TIME -Key = null -Value = m2 -Now finished printing details of record number: 2 -******************** -******************** -Now printing details of record number: 3 -Topic: myTopic -Partition: 0 -Offset: 385 -Topic: myTopic -Timestamp: 1678484824763 -TimestampType: CREATE_TIME -Key = null -Value = m3 -Now finished printing details of record number: 3 -******************** -******************** -Now printing details of record number: 4 -Topic: myTopic -Partition: 0 -Offset: 386 -Topic: myTopic -Timestamp: 1678484825902 -TimestampType: CREATE_TIME -Key = null -Value = m4 -Now finished printing details of record number: 4 -******************** -******************** -Now printing details of record number: 5 -Topic: myTopic -Partition: 0 -Offset: 387 -Topic: myTopic -Timestamp: 1678484827810 -TimestampType: CREATE_TIME -Key = null -Value = m5 -Now finished printing details of record number: 5 -******************** -END RequestId: 5c10310a-abf9-416e-b017-697d2c3ba097 -REPORT RequestId: 5c10310a-abf9-416e-b017-697d2c3ba097 Init Duration: 6.68 ms Duration: 1502.83 ms Billed Duration: 1503 ms Memory Size: 128 MB Max Memory Used: 128 MB +START RequestId: ec2a36a6-5b5e-40c8-bff6-e6237babd613 Version: $LATEST +EventSource = aws:kafka +EventSourceARN = arn:aws:kafka:us-west-2:123456789012:cluster/MSKWorkshopCluster/a93759a9-c9d0-4952-984c-492c6bfa2be8-13 +This Key = myTopic-0 +********** +Start of message 1 +Topic = myTopic +Partition = 0 +Offset = 250 +Timestamp = 2023-03-06 03:08:30.111 +0000 UTC +TimestampType = CREATE_TIME +Key = null +Value = f +End of message 1 +********** +********** +Start of message 2 +Topic = myTopic +Partition = 0 +Offset = 251 +Timestamp = 2023-03-06 03:08:31.086 +0000 UTC +TimestampType = CREATE_TIME +Key = null +Value = g +End of message 2 +********** +END RequestId: ec2a36a6-5b5e-40c8-bff6-e6237babd613 +REPORT RequestId: ec2a36a6-5b5e-40c8-bff6-e6237babd613 Init Duration: 1.38 ms Duration: 651.86 ms Billed Duration: 652 ms Memory Size: 128 MB Max Memory Used: 128 MB ## Cleanup From 6f11da6d7bb0a7bc0b2f58658716f535f4343f08 Mon Sep 17 00:00:00 2001 From: Julian Wood Date: Wed, 13 Sep 2023 17:21:54 +0000 Subject: [PATCH 3/3] Amend source pattern: msk-lambda-iam-go-sam --- msk-lambda-iam-go-sam/README.md | 57 ++++++++------- msk-lambda-iam-go-sam/example-pattern.json | 84 +++++++++++----------- msk-lambda-iam-go-sam/template.yaml | 6 +- 3 files changed, 76 insertions(+), 71 deletions(-) diff --git a/msk-lambda-iam-go-sam/README.md b/msk-lambda-iam-go-sam/README.md index 37a0c7a98..ea192be96 100644 --- a/msk-lambda-iam-go-sam/README.md +++ b/msk-lambda-iam-go-sam/README.md @@ -4,16 +4,9 @@ This pattern is an example of a Lambda function that consumes messages from an A This project contains source code and supporting files for a serverless application that you can deploy with the AWS Serverless Application Model (AWS SAM) CLI. It includes the following files and folders. - -```bash -. -├── Makefile <-- Make to automate build -├── README.md <-- This instructions file -├── HandlerKafka <-- Source code for a lambda function -│ ├── main.go <-- Lambda function code -│ └── main_test.go <-- Unit tests -└── template.yaml -``` +- HandlerKafka - Code for the application's Lambda function. +- events - Invocation events that you can use to invoke the function. +- template.yaml - An AWS SAM template that defines the application's AWS resources. The application creates a Lambda function that listens to Kafka messages on a topic of an MSK Cluster. These resources are defined in the `template.yaml` file in this project. You can update the template to add AWS resources through the same deployment process that updates your application code. @@ -25,7 +18,6 @@ Important: this application uses various AWS services and there are costs associ * [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) installed and configured * [Git installed](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) * [AWS Serverless Application Model](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html) (AWS SAM) installed -* [Docker installed](https://www.docker.com/community-edition) * [Golang](https://golang.org) * Create MSK cluster and topic that will be used for testing. It is important to create the topic before deploying the Lambda function, otherwise the event source mapping will stay disabled. @@ -41,39 +33,50 @@ To use the AWS SAM CLI, you need the following tools. In this example we use the built-in `sam build` to automatically download all the dependencies and package our build target. Read more about [SAM Build here](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-build.html) - 1. Create a new directory, navigate to that directory in a terminal and clone the GitHub repository: ``` git clone https://github.com/aws-samples/serverless-patterns.git ``` 1. Change directory to the pattern directory: ``` - cd msk-lambda-iam-python-sam + cd msk-lambda-iam-go-sam ``` -1. The `sam build` command is wrapped inside of the `Makefile`. +This solution uses the AWS Lambda [custom runtime](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-custom.html) `provided.al2` which is the prefered way to run Go applications in Lambda. For more information, see [https://aws.amazon.com/blogs/compute/migrating-aws-lambda-functions-from-the-go1-x-runtime-to-the-custom-runtime-on-amazon-linux-2/](https://aws.amazon.com/blogs/compute/migrating-aws-lambda-functions-from-the-go1-x-runtime-to-the-custom-runtime-on-amazon-linux-2/). - ```shell - make - ``` - -AWS Lambda Golang runtime requires a flat folder with the executable generated on build step. SAM will use `CodeUri` property to know where to look up for the application: +The AWS SAM template configures the `provided.al2` runtime and builds the Go function using the following syntax. ```yaml ... - FirstFunction: - Type: AWS::Serverless::Function - Properties: - CodeUri: hello_world/ - ... + HelloWorldGoKafkaFunction: + Type: AWS::Serverless::Function + Metadata: + BuildMethod: go1.x + Properties: + CodeUri: HandlerKafka/ + Handler: bootstrap + Runtime: provided.al2 ``` +You can also use the managed Go.1 runtime by amending the AWS SAM template: -1. To deploy your application for the first time, run the following in your shell: +AWS Lambda Golang runtime requires a flat folder with the executable generated on build step. SAM will use `CodeUri` property to know where to look up for the application: -```bash -sam deploy --guided +```yaml +... + HelloWorldGoKafkaFunction: + Type: AWS::Serverless::Function + Properties: + CodeUri: HandlerKafka/ + Handler: handler + Runtime: go1.x ``` +1. From the command line, use AWS SAM to deploy the AWS resources for the pattern as specified in the template.yml file: + ``` + sam build + sam deploy --guided + ``` + 1. During the prompts: * **Stack Name**: The name of the stack to deploy to CloudFormation. This should be unique to your account and region, and a good starting point would be something matching your project name. * **AWS Region**: The AWS region you want to deploy your app to. diff --git a/msk-lambda-iam-go-sam/example-pattern.json b/msk-lambda-iam-go-sam/example-pattern.json index 6d79b62c6..1db2402b0 100644 --- a/msk-lambda-iam-go-sam/example-pattern.json +++ b/msk-lambda-iam-go-sam/example-pattern.json @@ -1,61 +1,61 @@ - { +{ "title": "AWS Lambda function subscribed to an Amazon MSK topic using IAM auth", "description": "Creates a Lambda function that uses an Amazon MSK topic as an event source with IAM authentication.", "language": "Go", "level": "200", "framework": "SAM", "introBox": { - "headline": "How it works", - "text": [ - "This pattern provides a Lambda function along with an Event Source Mapping to a Kafka topic.", - "It requires that you already have an Amazon Managed Streaming for Kafka(Amazon MSK) cluster setup with a topic created. If you don't already have an MSK cluster ", - "you can use the example in this pattern https://serverlessland.com/patterns/msk-cfn-sasl-lambda (linked in the resources) to deploy a cluster.", - "This pattern works with either a Provisioned or Serverless MSK cluster as long as the cluster is configured to use IAM authentication. ", - "For detailed deployment instructions instructions see the README " - ] + "headline": "How it works", + "text": [ + "This pattern provides a Lambda function along with an Event Source Mapping to a Kafka topic.", + "It requires that you already have an Amazon Managed Streaming for Kafka (Amazon MSK) cluster setup with a topic created. ", + "If you don't already have an MSK cluster, you can use the example in this pattern https://serverlessland.com/patterns/msk-cfn-sasl-lambda (linked in the resources) to deploy a cluster.", + "This pattern works with either a Provisioned or Serverless MSK cluster as long as the cluster is configured to use IAM authentication. ", + "For detailed deployment instructions instructions see the README." + ] }, "gitHub": { - "template": { - "repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/msk-lambda-go-sam", - "templateURL": "serverless-patterns/msk-lambda-go-sam", - "projectFolder": "msk-lambda-go-sam", - "templateFile": "template.yml" - } + "template": { + "repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/msk-lambda-iam-go-sam", + "templateURL": "serverless-patterns/msk-lambda-iam-go-sam", + "projectFolder": "msk-lambda-iam-go-sam", + "templateFile": "template.yaml" + } }, "resources": { - "bullets": [ - { - "text": "Amazon MSK Cluster pattern", - "link": "https://serverlessland.com/patterns/msk-cfn-sasl-lambda" - }, - { - "text": "Using AWS Lambda with Amazon MSK", - "link": "https://docs.aws.amazon.com/lambda/latest/dg/with-msk.html" - }, - { - "text": "AWS CloudFormation Provisioned MSK cluster reference", - "link": "https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-msk-cluster.html" - }, - { - "text": "AWS CloudFormation Serverless MSK cluster reference", - "link": "https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-msk-serverlesscluster.html" - } - ] + "bullets": [ + { + "text": "Amazon MSK cluster pattern", + "link": "https://serverlessland.com/patterns/msk-cfn-sasl-lambda" + }, + { + "text": "Using AWS Lambda with Amazon MSK", + "link": "https://docs.aws.amazon.com/lambda/latest/dg/with-msk.html" + }, + { + "text": "AWS CloudFormation Provisioned MSK cluster reference", + "link": "https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-msk-cluster.html" + }, + { + "text": "AWS CloudFormation Serverless MSK cluster reference", + "link": "https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-msk-serverlesscluster.html" + } + ] }, "deploy": { - "text": [ - "sam deploy --guided" - ] + "text": [ + "sam deploy --guided" + ] }, "testing": { - "text": [ - "See the GitHub repo for detailed testing instructions." - ] + "text": [ + "See the GitHub repo for detailed testing instructions." + ] }, "cleanup": { - "text": [ - "Delete the template: sam delete." - ] + "text": [ + "Delete the template: sam delete." + ] }, "authors": [ { diff --git a/msk-lambda-iam-go-sam/template.yaml b/msk-lambda-iam-go-sam/template.yaml index 20536026e..9c35a7546 100644 --- a/msk-lambda-iam-go-sam/template.yaml +++ b/msk-lambda-iam-go-sam/template.yaml @@ -13,10 +13,12 @@ Globals: Resources: HelloWorldGoKafkaFunction: Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction + Metadata: + BuildMethod: go1.x Properties: CodeUri: HandlerKafka/ - Handler: handler - Runtime: go1.x + Handler: bootstrap + Runtime: provided.al2 Architectures: - x86_64 Events: