@ikomiki/nx-aws-s3 v0.8.3
@nx-aws/sam
Angular CLI Builders for AWS SAM projects, designed for use alongside nx
Why
nx superpowers the angular CLI, to add support for a range of backend project types.
However, what if your backend uses SAM?
This project includes builders for that!
- @nx-aws/sam:build - builds your functions and layers
- @nx-aws/sam:package - packages your SAM (ie. CloudFormation) template ready for deployment (including resolving AWS::Serverless::Application references to other apps in your monorepo)
- @nx-aws/sam:deploy - deploys your CloudFormation template
@nx-aws/sam:build
Add the following to your angular.json
{
"api": {
"root": "apps/api",
"sourceRoot": "apps/api/src",
"projectType": "application",
"prefix": "api",
"schematics": {},
"architect": {
"build": {
"builder": "@nx-aws/sam:build",
"options": {
"outputPath": "dist/apps/api",
"template": "apps/api/template.yaml",
"tsConfig": "apps/api/tsconfig.app.json"
},
...
}
}
}
}The builder will search through your CloudFormation template at apps/api/template.yaml
and find any AWS::Serverless::Function and AWS::Serverless:LayerVersion and trigger
appropriate builds.
(All the other options are the same as for nrwl's node builder.)
Functions
Given this code in your template.yaml:
Resources:
MyFunction:
Type: 'AWS::Serverless::Function'
Properties:
# CodeUri should be the directory, relative to template.yaml, where the handler file is found
CodeUri: src/my-function
# This is the name of the handler file and then the name of the exported handler function
# (standard SAM approach)
Handler: handler-file.handlerFnThe builder will run a webpack build for src/my-function/handler-file.
Lambda Layers
If you've got this in your template.yaml:
Resources:
MyLayer:
Type: 'AWS::Serverless::LayerVersion'
Properties:
ContentUri: ./src/my-layer
CompatibleRuntimes:
- nodejs10.x
- nodejs8.10
LicenseInfo: UNLICENCEDLambda layers are deployed as node modules, and so we need to include a ./src/my-layer/package.json
{
"name": "my-layer",
"main": "index.ts"
}The builder will:
- Alter the output directory to include
nodejs/node_modules, as required for a Lambda layer - Look for a package.json at
./src/my-layer/package.json - Load
package.jsonand get themainentry point (index.ts) - Run a webpack build for the
mainentry point - Re-write the
mainentry point inpackage.jsonand write it out to the output directory
@nx-aws/sam:package
Add the following to your angular.json:
{
"api": {
"root": "apps/api",
"sourceRoot": "apps/api/src",
"projectType": "application",
"prefix": "api",
"schematics": {},
"architect": {
"package": {
"builder": "@nx-aws/sam:package",
"options": {
"templateFile": "apps/api/template.yaml",
"outputTemplateFile": "dist/apps/api/serverless-output.yaml",
"s3Prefix": "api",
"s3Bucket": "my-artefacts-bucket"
},
"configurations": {
"production": {}
}
}
}
}
}For the most part, this simply wraps the aws cloudformation package command, but it will also
rewrite the Location property of AWS::Serverless::Application resources, if they refer to
another project.
AWS::Serverless::Application
The package builder will attempt to resolve a reference to another CloudFormation stack, defined
in a different project in angular.json.
If the package builder finds an AWS::Serverless::Application in template.yaml, eg:
Resources:
MySubStack:
Type: AWS::Serverless::Application
Properties:
Location: my-sub-stackit will attempt to:
- Find an project in
angular.jsonthat matches theLocationproperty, ie.my-sub-stack. - If it finds such a project, it will look for the
packagetarget. - If it finds the
packagetarget, it will replacemy-sub-stackwith the absolute path to theoutputTemplateFilefrom that target.
deploy
Add the following to angular.json:
{
...
"api": {
"root": "apps/api",
"sourceRoot": "apps/api/src",
"projectType": "application",
"prefix": "api",
"schematics": {},
"architect": {
...
"deploy": {
"builder": "@nx-aws/sam:deploy",
"options": {
"templateFile": "dist/apps/api/serverless-output.yaml",
"s3Prefix": "api",
"capabilities": ["CAPABILITY_IAM", "CAPABILITY_AUTO_EXPAND"],
"s3Bucket": "my-artefacts-bucket",
"stackNameFormat": "api-$ENVIRONMENT"
},
"configurations": {
"production": {}
}
}
}
}
}This wraps the aws cloudformation deploy command. The one nice thing it does is pull
any parameters defined in your template.yaml from environment variables, and pass them
in as parameter overrides. For example, if you have in your template.yaml:
Parameters:
MyParameter:
Type: String
Description: An example parameterThe the deploy builder will look for an environment variable MY_PARAMETER and pass it in as a parameter overrides.