boilerplate-lambda-container/README.md

128 lines
3.6 KiB
Markdown

# Hello OpenAPI
This repo contains boilerplate code for building AWS Lambda functions using Docker. See [notes/decisions.md](notes/decisions.md) for stack decisions.
Sample containers are provided:
* [hello-deno](containers/hello-deno/) - simplest example lambda function using Deno
* [hello-openapi](containers/hello-openapi/) - opinionated OpenAPI stack
## IDE Note
In VSCode, import module resolution can be handled by the `denoland.vscode-deno`. They suggest keeping it disabled globally and only enabling it per workspace.
![enable deno extension in workspace](notes/ide-deno-extension.png)
## Build Docker Image
Build and test the docker image locally.
```sh
export CONTAINER_NAME=hello-openapi
docker build -t $CONTAINER_NAME .
```
(Optional) Run the container locally.
```sh
docker run -p 8000:8000 $CONTAINER_NAME:latest
curl http://localhost:8000
docker stop $(docker ps -q)
```
## Deployment
Overview:
1. Create the ECR repository.
2. Push the container image to the ECR repository.
3. Deploy the lambda function.
### Create the ECR repository
You'll first need to authenticate with AWS.
```sh
export AWS_REGION=us-west-1
export AWS_PROFILE=playground
aws configure sso --profile $AWS_PROFILE
```
With Terraform:
```sh
cd terraform
terraform init
terraform apply -target=aws_ecr_repository.hello_docker
export REPOSITORY_URI=$(terraform output -raw ecr_repository_url)
aws ecr get-login-password --region $AWS_REGION --profile $AWS_PROFILE | docker login --username AWS --password-stdin $REPOSITORY_URI
docker tag $CONTAINER_NAME:latest $REPOSITORY_URI:latest
docker push $REPOSITORY_URI:latest
```
With aws-sam-cli:
```sh
cd sam
sam build
sam deploy --guided --profile playground --region us-west-1 --parameter-overrides DeployECROnly=true
export REPOSITORY_URI=$(aws ecr describe-repositories --repository-names $CONTAINER_NAME --region $AWS_REGION --profile $AWS_PROFILE | jq -r '.repositories[0].repositoryUri')
aws ecr get-login-password --region $AWS_REGION --profile $AWS_PROFILE | docker login --username AWS --password-stdin $REPOSITORY_URI
docker tag $CONTAINER_NAME:latest $REPOSITORY_URI:latest
docker push $REPOSITORY_URI:latest
```
In either case, we must build the ECR repository before deploying the lambda function. For sam, the `DeployECROnly` parameter is used to control this behavior for sam. You can set it to `false` in your [samconfig.toml](sam/samconfig.toml) after the first deploy. Thereafter you can use `--no-confirm-changeset` instead of `--guided`. For terraform, simply omit the `-target` parameter to build the full stack.
### Deploy the lambda function
With Terraform:
```sh
terraform apply
```
With aws-sam-cli:
```sh
sam deploy --guided --profile playground --region us-west-1 --parameter-overrides DeployECROnly=false --resolve-image-repos
```
## Tips
Get the function url for the lambda function
```sh
export FUNCTION_NAME=
aws lambda get-function-url-config --function-name $FUNCTION_NAME --query 'FunctionUrl' --output text
```
Check the image uri for a lambda function
```sh
aws lambda get-function --function-name $FUNCTION_NAME --query 'Code.ImageUri' --output text
```
Review the images in an ECR repository
```sh
export REPOSITORY_NAME=hello-world
aws ecr describe-images --repository-name $REPOSITORY_NAME --region $AWS_REGION --profile $AWS_PROFILE
```
## Logs
With Terraform:
```sh
export FUNCTION_NAME=hello_docker
aws logs tail /aws/lambda/$FUNCTION_NAME --since 1h --profile $AWS_PROFILE --region $AWS_REGION
aws logs tail /aws/lambda/$FUNCTION_NAME --follow --profile $AWS_PROFILE --region $AWS_REGION
```
With aws-sam-cli:
```sh
sam logs -n HelloWorldFunction --profile playground --tail
```