Amazon Web Service’s serverless compute has always fascinated me. A lot of my pursuits of learning the DevOps methodology involves scripting but not full blown programming. When it comes to automation I can accomplish my goals with scripting. Now I just found out that you can run PowerShell in AWS Lambda but I think that is pretty recent. So before I knew that I decided I wanted to re-engage my brain centers for learning a programming language. I see a lot of hype and support for Google’s Go language. I started going through the tutorials and creating things. An idea came to me for a creation which I will talk about in a later post. For now I wanted to share my understanding of Lambda.
Lamba uses requests and events. The request contains the data it needs to function in kind of a HTTP post, at least that’s what it reminds me of since you can call it through a HTTP request and the Lambda library pulls out headers and the body. Then it returns in an HTTP fashion as well. Here’s a sample piece of code that leverages AWS Simple Email Service to take a name out of a HTTP body.
package main import ( "errors" "fmt" "log" "github.com/aws/aws-lambda-go/events" "github.com/aws/aws-lambda-go/lambda" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/credentials" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/ses" ) const ( // Replace sender@example.com with your "From" address. // This address must be verified with Amazon SES. Sender = "lambda@serverhobbyist.net" // Replace recipient@example.com with a "To" address. If your account // is still in the sandbox, this address must be verified. Recipient = "Recipient@Recipient.com" // Specify a configuration set. To use a configuration // set, comment the next line and line 92. //ConfigurationSet = "ConfigSet" // The subject line for the email. Subject = "Lambda Function Go!" // The character encoding for the email. CharSet = "UTF-8" ) var ( // ErrNameNotProvided is thrown when a name is not provided ErrNameNotProvided = errors.New("no name was provided in the HTTP body") ) // Handler is your Lambda function handler // It uses Amazon API Gateway request/responses provided by the aws-lambda-go/events package, // However you could use other event sources (S3, Kinesis etc), or JSON-decoded primitive types such as 'string'. func Handler(request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) { var TextBody = "Hello " + request.Body var HtmlBody = "Hello " + request.Body sess, err := session.NewSession(&aws.Config{ Region: aws.String("us-east-1"), Credentials: credentials.NewStaticCredentials("Removed", "Removed", ""), }) // Create an SES session. svc := ses.New(sess) // Assemble the email. input := &ses.SendEmailInput{ Destination: &ses.Destination{ CcAddresses: []*string{}, ToAddresses: []*string{ aws.String(Recipient), }, BccAddresses: []*string{ aws.String(BCCRecipient), }, }, Message: &ses.Message{ Body: &ses.Body{ Html: &ses.Content{ Charset: aws.String(CharSet), Data: aws.String(HtmlBody), }, Text: &ses.Content{ Charset: aws.String(CharSet), Data: aws.String(TextBody), }, }, Subject: &ses.Content{ Charset: aws.String(CharSet), Data: aws.String(Subject), }, }, Source: aws.String(Sender), // Uncomment to use a configuration set //ConfigurationSetName: aws.String(ConfigurationSet), } // Attempt to send the email. result, err := svc.SendEmail(input) log.Println(result) // Display error messages if they occur. if err != nil { if aerr, ok := err.(awserr.Error); ok { switch aerr.Code() { case ses.ErrCodeMessageRejected: fmt.Println(ses.ErrCodeMessageRejected, aerr.Error()) case ses.ErrCodeMailFromDomainNotVerifiedException: fmt.Println(ses.ErrCodeMailFromDomainNotVerifiedException, aerr.Error()) case ses.ErrCodeConfigurationSetDoesNotExistException: fmt.Println(ses.ErrCodeConfigurationSetDoesNotExistException, aerr.Error()) default: fmt.Println(aerr.Error()) } } else { // Print the error, cast err to awserr.Error to get the Code and // Message from an error. fmt.Println(err.Error()) } } // stdout and stderr are sent to AWS CloudWatch Logs log.Printf("Processing Lambda request %s\n", request.RequestContext.RequestID) // If no name is provided in the HTTP request body, throw an error if len(request.Body) < 1 { return events.APIGatewayProxyResponse{}, ErrNameNotProvided } log.Println(request.PathParameters) return events.APIGatewayProxyResponse{ Body: "Hello " + request.Body, StatusCode: 200, }, nil } func main() { lambda.Start(Handler) }