Skip to content

Commit

Permalink
refactor: simplify built-in quickstarts to a simple hello world (#849)
Browse files Browse the repository at this point in the history
  • Loading branch information
heitorlessa authored and jfuss committed Jan 14, 2019
1 parent 29e2250 commit 9600778
Show file tree
Hide file tree
Showing 41 changed files with 1,314 additions and 647 deletions.
29 changes: 25 additions & 4 deletions samcli/commands/init/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,34 @@ def do_cli(ctx, location, runtime, output_dir, name, no_input):
LOG.debug("Init command")
click.secho("[+] Initializing project structure...", fg="green")

no_build_msg = """
Project generated: {output_dir}/{name}
Steps you can take next within the project folder
===================================================
[*] Invoke Function: sam local invoke HelloWorldFunction --event event.json
[*] Start API Gateway locally: sam local start-api
""".format(output_dir=output_dir, name=name)

build_msg = """
Project generated: {output_dir}/{name}
Steps you can take next within the project folder
===================================================
[*] Install dependencies
[*] Invoke Function: sam local invoke HelloWorldFunction --event event.json
[*] Start API Gateway locally: sam local start-api
""".format(output_dir=output_dir, name=name)

no_build_step_required = (
"python", "python3.7", "python3.6", "python2.7", "nodejs", "nodejs4.3", "nodejs6.10", "nodejs8.10", "ruby2.5")
next_step_msg = no_build_msg if runtime in no_build_step_required else build_msg

try:
generate_project(location, runtime, output_dir, name, no_input)
# Custom templates can implement their own visual cues so let's not repeat the message
if not location:
click.secho(
"[SUCCESS] - Read {name}/README.md for further instructions on how to proceed"
.format(name=name), bold=True)
click.secho(next_step_msg, bold=True)
click.secho("Read {name}/README.md for further instructions\n".format(name=name), bold=True)
click.secho("[*] Project initialization is now complete", fg="green")
except GenerateProjectFailedError as e:
raise UserException(str(e))
3 changes: 1 addition & 2 deletions samcli/local/init/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,8 @@
"python2.7": os.path.join(_templates, "cookiecutter-aws-sam-hello-python"),
"python": os.path.join(_templates, "cookiecutter-aws-sam-hello-python"),
"ruby2.5": os.path.join(_templates, "cookiecutter-aws-sam-hello-ruby"),
"nodejs6.10": os.path.join(_templates, "cookiecutter-aws-sam-hello-nodejs"),
"nodejs6.10": os.path.join(_templates, "cookiecutter-aws-sam-hello-nodejs6"),
"nodejs8.10": os.path.join(_templates, "cookiecutter-aws-sam-hello-nodejs"),
"nodejs4.3": os.path.join(_templates, "cookiecutter-aws-sam-hello-nodejs"),
"nodejs": os.path.join(_templates, "cookiecutter-aws-sam-hello-nodejs"),
"dotnetcore2.0": os.path.join(_templates, "cookiecutter-aws-sam-hello-dotnet"),
"dotnetcore2.1": os.path.join(_templates, "cookiecutter-aws-sam-hello-dotnet"),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
MIT No Attribution
Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy of this
software and associated documentation files (the "Software"), to deal in the Software
Expand All @@ -11,4 +11,4 @@ INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,42 +1,20 @@
# Cookiecutter SAM for Node Lambda functions
# Cookiecutter NodeJS Hello-world for SAM based Serverless App

This is a [Cookiecutter](https://github.com/audreyr/cookiecutter) template to create a Serverless Hello World App based on Serverless Application Model (SAM) and NodeJS.

It is important to note that you should not try to `git clone` this project but use `cookiecutter` CLI instead as ``{{cookiecutter.project_name}}`` will be rendered based on your input and therefore all variables and files will be rendered properly.
A cookiecutter template to create a NodeJS Hello world boilerplate using [Serverless Application Model (SAM)](https://github.com/awslabs/serverless-application-model).

## Requirements

Install `cookiecutter` command line:

**Pip users**:

* `pip install cookiecutter`

**Homebrew users**:

* `brew install cookiecutter`

**Windows or Pipenv users**:

* `pipenv install cookiecutter`

**NOTE**: [`Pipenv`](https://github.com/pypa/pipenv) is the new and recommended Python packaging tool that works across multiple platforms and makes Windows a first-class citizen.
* [AWS SAM CLI](https://github.com/awslabs/aws-sam-cli)

## Usage

Generate a new SAM based Serverless App: `cookiecutter gh:aws-samples/cookiecutter-aws-sam-hello-nodejs`.

You'll be prompted a few questions to help this cookiecutter template to scaffold this project and after its completed you should see a new folder at your current path with the name of the project you gave as input.
Generate a boilerplate template in your current project directory using the following syntax:

**NOTE**: After you understand how cookiecutter works (cookiecutter.json, mainly), you can fork this repo and apply your own mechanisms to accelerate your development process and this can be followed for any programming language and OS.
* **NodeJS 8**: `sam init --runtime nodejs8.10`

> **NOTE**: ``--name`` allows you to specify a different project folder name (`sam-app` is the default)
# Credits

* This project has been generated with [Cookiecutter](https://github.com/audreyr/cookiecutter)


License
-------

This project is licensed under the terms of the [MIT License with no attribution](/LICENSE)

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,48 +4,33 @@ This is a sample template for {{ cookiecutter.project_name }} - Below is a brief

```bash
.
├── README.md <-- This instructions file
├── hello-world <-- Source code for a lambda function
│ ├── app.js <-- Lambda function code
│ ├── package.json <-- NodeJS dependencies
├── README.MD <-- This instructions file
├── event.json <-- API Gateway Proxy Integration event payload
├── hello_world <-- Source code for a lambda function
│ └── app.js <-- Lambda function code
│ └── package.json <-- NodeJS dependencies and scripts
│ └── tests <-- Unit tests
│ └── unit
│ └── test_handler.js
── template.yaml <-- SAM template
│ └── test-handler.js
── template.yaml <-- SAM template
```

## Requirements

* AWS CLI already configured with Administrator permission
{%- if cookiecutter.runtime == 'nodejs6.10' %}
* [NodeJS 6.10 installed](https://nodejs.org/en/download/releases/)
{%- elif cookiecutter.runtime =='nodejs4.3' %}
* [NodeJS 4.3 installed](https://nodejs.org/en/download/releases/)
{%- else %}
* [NodeJS 8.10+ installed](https://nodejs.org/en/download/)
{%- endif %}
* [Docker installed](https://www.docker.com/community-edition)

## Setup process

### Building the project
### Local development

[AWS Lambda requires a flat folder](https://docs.aws.amazon.com/lambda/latest/dg/nodejs-create-deployment-pkg.html) with the application as well as its dependencies in a node_modules folder. When you make changes to your source code or dependency manifest,
run the following command to build your project local testing and deployment:

```bash
sam build
```
**Invoking function locally using a local sample payload**

If your dependencies contain native modules that need to be compiled specifically for the operating system running on AWS Lambda, use this command to build inside a Lambda-like Docker container instead:
```bash
sam build --use-container
sam local invoke HelloWorldFunction --event event.json
```

By default, this command writes built artifacts to `.aws-sam/build` folder.

### Local development

**Invoking function locally through local API Gateway**

```bash
Expand All @@ -72,7 +57,7 @@ AWS Lambda NodeJS runtime requires a flat folder with all dependencies including

```yaml
...
FirstFunction:
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: hello-world/
Expand All @@ -89,7 +74,6 @@ Next, run the following command to package our Lambda function to S3:

```bash
sam package \
--template-file template.yaml \
--output-template-file packaged.yaml \
--s3-bucket REPLACE_THIS_WITH_YOUR_S3_BUCKET_NAME
```
Expand All @@ -103,16 +87,29 @@ sam deploy \
--capabilities CAPABILITY_IAM
```

> **See [Serverless Application Model (SAM) HOWTO Guide](https://github.com/awslabs/serverless-application-model/blob/master/HOWTO.md) for more details in how to get started.**
> **See [Serverless Application Model (SAM) HOWTO Guide](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-quick-start.html) for more details in how to get started.**
After deployment is complete you can run the following command to retrieve the API Gateway Endpoint URL:

```bash
aws cloudformation describe-stacks \
--stack-name {{ cookiecutter.project_name.lower().replace(' ', '-') }} \
--query 'Stacks[].Outputs'
--query 'Stacks[].Outputs[?OutputKey==`HelloWorldApi`]' \
--output table
```

## Fetch, tail, and filter Lambda function logs

To simplify troubleshooting, SAM CLI has a command called sam logs. sam logs lets you fetch logs generated by your Lambda function from the command line. In addition to printing the logs on the terminal, this command has several nifty features to help you quickly find the bug.

`NOTE`: This command works for all AWS Lambda functions; not just the ones you deploy using SAM.

```bash
sam logs -n HelloWorldFunction --stack-name {{ cookiecutter.project_name.lower().replace(' ', '-') }} --tail
```

You can find more information and examples about filtering Lambda function logs in the [SAM CLI Documentation](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-logging.html).

## Testing

We use `mocha` for testing our code and it is already added in `package.json` under `scripts`, so that we can simply run the following command to run our tests:
Expand All @@ -123,38 +120,87 @@ npm install
npm run test
```

## Cleanup

In order to delete our Serverless Application recently deployed you can use the following AWS CLI Command:

```bash
aws cloudformation delete-stack --stack-name {{ cookiecutter.project_name.lower().replace(' ', '-') }}
```

## Bringing to the next level

Here are a few things you can try to get more acquainted with building serverless applications using SAM:

### Learn how SAM Build can help you with dependencies

* Uncomment lines on `app.js`
* Build the project with ``sam build --use-container``
* Invoke with ``sam local invoke HelloWorldFunction --event event.json``
* Update tests

### Create an additional API resource

* Create a catch all resource (e.g. /hello/{proxy+}) and return the name requested through this new path
* Update tests

### Step-through debugging

* **[Enable step-through debugging docs for supported runtimes]((https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-using-debugging.html))**

Next, you can use AWS Serverless Application Repository to deploy ready to use Apps that go beyond hello world samples and learn how authors developed their applications: [AWS Serverless Application Repository main page](https://aws.amazon.com/serverless/serverlessrepo/)

# Appendix

## AWS CLI commands
## Building the project

[AWS Lambda requires a flat folder](https://docs.aws.amazon.com/lambda/latest/dg/nodejs-create-deployment-pkg.html) with the application as well as its dependencies in a node_modules folder. When you make changes to your source code or dependency manifest,
run the following command to build your project local testing and deployment:

```bash
sam build
```

If your dependencies contain native modules that need to be compiled specifically for the operating system running on AWS Lambda, use this command to build inside a Lambda-like Docker container instead:
```bash
sam build --use-container
```

By default, this command writes built artifacts to `.aws-sam/build` folder.

## SAM and AWS CLI commands

AWS CLI commands to package, deploy and describe outputs defined within the cloudformation stack:
All commands used throughout this document

```bash
# Invoke function locally with event.json as an input
sam local invoke HelloWorldFunction --event event.json

# Run API Gateway locally
sam local start-api

# Create S3 bucket
aws s3 mb s3://BUCKET_NAME

# Package Lambda function defined locally and upload to S3 as an artifact
sam package \
--template-file template.yaml \
--output-template-file packaged.yaml \
--s3-bucket REPLACE_THIS_WITH_YOUR_S3_BUCKET_NAME

# Deploy SAM template as a CloudFormation stack
sam deploy \
--template-file packaged.yaml \
--stack-name {{ cookiecutter.project_name.lower().replace(' ', '-') }} \
--capabilities CAPABILITY_IAM \
--parameter-overrides MyParameterSample=MySampleValue
--capabilities CAPABILITY_IAM

# Describe Output section of CloudFormation stack previously created
aws cloudformation describe-stacks \
--stack-name {{ cookiecutter.project_name.lower().replace(' ', '-') }} --query 'Stacks[].Outputs'
--stack-name {{ cookiecutter.project_name.lower().replace(' ', '-') }} \
--query 'Stacks[].Outputs[?OutputKey==`HelloWorldApi`]' \
--output table

# Tail Lambda function Logs using Logical name defined in SAM Template
sam logs -n HelloWorldFunction --stack-name {{ cookiecutter.project_name.lower().replace(' ', '-') }} --tail
```

**NOTE**: Alternatively this could be part of package.json scripts section.

## Bringing to the next level

Here are a few ideas that you can use to get more acquainted as to how this overall process works:

* Create an additional API resource (e.g. /hello/{proxy+}) and return the name requested through this new path
* Update unit test to capture that
* Package & Deploy

Next, you can use the following resources to know more about beyond hello world samples and how others structure their Serverless applications:

* [AWS Serverless Application Repository](https://aws.amazon.com/serverless/serverlessrepo/)
Loading

0 comments on commit 9600778

Please sign in to comment.