Skip to content
This repository has been archived by the owner on Nov 4, 2022. It is now read-only.

Commit

Permalink
Minor updates and cleanup
Browse files Browse the repository at this point in the history
What
-----

- Minor cleanup to workshop instructions
- Update cleanup script so that it waits for stacks to delete before
  moving to the next one
  • Loading branch information
brianz committed Mar 17, 2022
1 parent 82fe67c commit efe632c
Show file tree
Hide file tree
Showing 13 changed files with 133 additions and 53 deletions.
14 changes: 13 additions & 1 deletion workshop/content/buildpipe/done/_index.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,19 @@ CodeBuild created the `sam-app-dev` stack during the `DeployTest` Pipeline step.
CodeBuild created `sam-app-prod` during the `DeployProd` step.

Look at the `Outputs` tab for each of these CloudFormation stacks to see the API endpoints. You can
use `curl` or other methods to verify the functionality of your two new APIs.
use `curl` or other methods to verify the functionality of your two new APIs. You can export the URL
endpoints for both stages in a terminal.

```bash
export DEV_ENDPOINT=$(aws cloudformation describe-stacks --stack-name sam-app-dev | jq -r '.Stacks[].Outputs[].OutputValue | select(startswith("https://"))')
export PROD_ENDPOINT=$(aws cloudformation describe-stacks --stack-name sam-app-prod | jq -r '.Stacks[].Outputs[].OutputValue | select(startswith("https://"))')

echo "Dev endpoint: $DEV_ENDPOINT"
echo "Prod endpoint: $PROD_ENDPOINT"

curl -s $DEV_ENDPOINT
curl -s $PROD_ENDPOINT
```

![API endpoints](/images/chapter4-pipelines/sam-app-dev-cfn-outputs.png)

Expand Down
6 changes: 5 additions & 1 deletion workshop/content/buildpipe/gitpush/_index.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ Branch 'main' set up to track remote branch 'main' from 'origin'.

### Verify in CodeCommit

Navigate to the [AWS CodeCommit console](https://console.aws.amazon.com/codesuite/codecommit/home), find your _sam-app_ repository and click on it to view its contents. Make sure your code is there. You should see a screen like the following:
Navigate to the [AWS CodeCommit console](https://console.aws.amazon.com/codesuite/codecommit/home),
find your `sam-app` repository and click on it to view its contents. Make sure your code is there.
You should see a screen like the following:

![VerifyCodeCommit](/images/screenshot-verify-codecommit.png)

#### Now that you repo has your code let's start building a CI/CD pipeline!
22 changes: 10 additions & 12 deletions workshop/content/buildpipe/howto/_index.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ weight = 20

The best way to automate the creation of CI/CD pipelines is by provisioning them programmatically
using Infrastructure as Code (IaC). This is useful in a microservices environment, where you may have
a pipeline per microservice. In such environments there could be dozens, or even hundreds,
a pipeline per service. In such environments there could be dozens, or even hundreds,
of CI/CD pipelines. Having an automated way to create those CI/CD pipelines enables developers move quickly
without the burden of building them manually. SAM Pipelines, which you'll be using, is a tool to
ease that burden.
Expand All @@ -30,8 +30,6 @@ test our serverless application locally. AWS SAM is a toolset meant to increase
developing serverless applications and provides capabilities such as `sam local` that are not
present in other IaC tools.

In this section you will be using another feature from SAM to create a CI/CD pipeline.

### Introducing AWS SAM Pipelines

[**SAM Pipelines**](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-pipeline-bootstrap.html)
Expand All @@ -49,14 +47,14 @@ As of this writing, SAM Pipelines can bootstrap CI/CD pipelines for the followin
{{% notice note %}}
SAM Pipelines is a feature which bootstraps CI/CD pipelines for the listed providers. This saves
saves you the work of setting them up from scratch. However, you can use SAM as a deployment tool
with _any_ CI/CD provider. You use the `sam build` and `sam deploy` commands to build and deploy SAM
with _any_ CI/CD provider. You use various `sam` commands to build and deploy SAM
applications regardless of your CI/CD toolset. Furthermore, the configurations SAM Pipelines creates
are a convienence to get you started quickly. You are free to edit these CI/CD configuration
are a convienence to get you started. You are free to edit these CI/CD configuration
files after SAM creates them.
{{% /notice %}}

SAM Pipelines creates appropriate configuration files for your CI/CD provider of choice. For
exampoe, when using
example, when using
GitHub Actions SAM will synthesize a `.github/workflows/pipeline.yaml` file. This file defines your CI/CD
pipeline using GitHub Actions. In this workshop we will be using AWS CodePipeline. As you will soon
see, SAM creates multiple files, one of which is a CloudFormation template named
Expand All @@ -68,11 +66,11 @@ serverless application automatically.
At the end of this section we will have a self-updating CI/CD pipeline using CodePipeline that will
perform the following steps.

1. Trigger after a commit to the `main` branch
1. Look for changes to the pipeline itself, and self-update using CloudFormation
1. Run unit tests via CodeBuild
1. Build and package the application code via CodeBuild
1. Deploy to a dev/test environment
1. Deploy to a production environment
1. Trigger after a commit to the `main` branch (`Source` in the screenshot below)
1. Look for changes to the pipeline itself, and self-update using CloudFormation (`UpdtatePipeline`)
1. Run unit tests via CodeBuild (`UnitTest`)
1. Build and package the application code via CodeBuild (`BuildAndPackage`)
1. Deploy to a dev/test environment (`DeployTest`)
1. Deploy to a production environment (`DeployProd`)

![](/images/sam-pipeline-architecture.png)
4 changes: 2 additions & 2 deletions workshop/content/buildpipe/sampipeinit/_index.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ cd ~/environment/sam-app
sam pipeline init --bootstrap
```

A list of the questions and required anwers for this workshop is enumerated below. Note that numbers
may be different when choosing from an enumerated list. The full output and answers are provided
A list of the questions and required anwers for this workshop is enumerated below. **Note that numbers
may be different when choosing from an enumerated list.** The full output and answers are provided
below as an additional reference.

1. Select a pipeline template to get started: `AWS Quick Start Pipeline Templates` (1)
Expand Down
8 changes: 5 additions & 3 deletions workshop/content/canaries/add-error/_index.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ exports.lambdaHandler = async (event, context) => {

`~/environment/sam-app/hello_world/app.py`

```python
```python {hl_lines=["3-4"]}
def lambda_handler(event, context):

if True:
Expand Down Expand Up @@ -100,6 +100,7 @@ def test_lambda_handler(apigw_event, mocker):
In the terminal, run the following commands from the root directory of your `sam-app` project.

```
cd ~/environment/sam-app
git add .
git commit -m "Breaking the lambda function on purpose"
git push
Expand All @@ -111,14 +112,15 @@ Once you've pushed the code you will need to generate traffic on your production
endpoint. **If you don't generate traffic for your Lambda function the CloudWatch alarm will not be
triggered!**

Fetch the API Gateway endpoint for your production deployment. This command will export the
production URL to the environment variable `PROD_ENDPOINT`.
{{%expand "If you haven't exported the PROD_ENDPOINT, run the following command." %}}

```bash
export PROD_ENDPOINT=$(aws cloudformation describe-stacks --stack-name sam-app-prod | jq -r '.Stacks[].Outputs[].OutputValue | select(startswith("https://"))')
echo "$PROD_ENDPOINT"
```

{{% /expand%}}

Start a `watch` command which will hit this endpoint twice per second.

```bash
Expand Down
28 changes: 18 additions & 10 deletions workshop/content/canaries/codedeploy/_index.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Remember to update the unit tests!

`~/environment/sam-app/hello-world/app.js`

```javascript
```javascript {hl_lines=["4"]}
response = {
statusCode: 200,
body: JSON.stringify({
Expand All @@ -31,7 +31,7 @@ response = {

`~/environment/node-sam-app/hello-world/tests/unit/test-handler.js `

```javascript
```javascript {hl_lines=["12"]}
describe("Tests index", function () {
it("verifies successful response", async () => {
const result = await app.lambdaHandler(event, context)
Expand All @@ -54,7 +54,7 @@ describe("Tests index", function () {

`~/environment/sam-app/hello_world/app.py `

```python
```python {hl_lines=["4"]}
return {
"statusCode": 200,
"body": json.dumps({
Expand All @@ -65,7 +65,7 @@ return {

`~/environment/sam-app/tests/unit/test_handler.py`

```python
```python {hl_lines=["7"]}
def test_lambda_handler(apigw_event, mocker):
ret = app.lambda_handler(apigw_event, "")
data = json.loads(ret["body"])
Expand Down Expand Up @@ -96,16 +96,21 @@ completes.
First, get the `https` endpoint of your dev stage. In a terminal on your Cloud9 enviroment run the
following command.

{{%expand "Export the HTTP endpoints if you haven't already" %}}

```bash
aws cloudformation describe-stacks --stack-name sam-app-dev | jq -r '.Stacks[].Outputs[].OutputValue | select(startswith("https://"))'
export DEV_ENDPOINT=$(aws cloudformation describe-stacks --stack-name sam-app-dev | jq -r '.Stacks[].Outputs[].OutputValue | select(startswith("https://"))')
export PROD_ENDPOINT=$(aws cloudformation describe-stacks --stack-name sam-app-prod | jq -r '.Stacks[].Outputs[].OutputValue | select(startswith("https://"))')
```

Copy the url returned by the previous command run the following `watch` command. This will hit your
API endpoint every second and print the return value to the screen. This command will also append
the output to the `outputs.txt` file. You can run this command from any directory.
{{% /expand%}}

Hit your `dev` API endpoint every second and print the return value to the screen. This command will
also append the output to the `outputs.txt` file that you can inspect later. You can run this
command from any directory.

```bash
watch -n 1 "curl -s https://123123123.execute-api.us-east-2.amazonaws.com/Prod/hello/ | jq '.message' 2>&1 | tee -a outputs.txt"
watch -n 1 "curl -s $DEV_ENDPOINT | jq '.message' 2>&1 | tee -a outputs.txt"
```

You should see `Hello my friend` in the terminal. Now that your script is logging the API output turn
Expand All @@ -117,7 +122,8 @@ the `In Progress` status navigate to the CodeDeploy console.
![CanaryCodeDeploy](/images/screenshot-canary-codedeploy-00.png)

In the CodeDeploy console click on `Deployments`. You should see your deployment `In progress`. If
you do not see a deployment, click the refresh icon. Click on the Deployment Id to see the details.
you do not see a deployment, click the refresh icon. **This may take a few minutes to show up!**
Click on the Deployment Id to see the details.

![CanaryCodeDeploy](/images/screenshot-canary-codedeploy-0.png)

Expand All @@ -130,6 +136,8 @@ ellapsed. In this case we specified the interval to be 5 minutes.
When you are in this stage, take a look at your terminal where you started the `watch` command. You
will see the message occasionally flash to `I'm using canary deployments`.

![CanaryDeploymentMessages](/images/code-pipeline-canary.gif)

After five minutes CodeDeploy will shift the remaining traffic to the new version and the deployment
will be done:

Expand Down
4 changes: 4 additions & 0 deletions workshop/content/canaries/sam/_index.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ with your `template.yaml` file.
{{< tabs >}}
{{% tab name="Node" %}}

`~environment/sam-app/template.yaml`

```yaml {linenos=true,hl_lines=["2-4"],linenostart=20}
Runtime: nodejs14.x
AutoPublishAlias: live
Expand All @@ -24,6 +26,8 @@ Architectures:
{{% /tab %}}
{{% tab name="python" %}}
`~environment/sam-app/template.yaml`

```yaml {linenos=true,hl_lines=["2-4"],linenostart=20}
Runtime: python3.7
AutoPublishAlias: live
Expand Down
36 changes: 30 additions & 6 deletions workshop/content/cleanup/delete-cf-stacks.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,17 @@ need to make adjustments. The cleanup script in its entirety is shown below.
```bash
#!/bin/bash

ROLE_NAME=Cloud9-MyAwesomeAdmin
ROLE_NAME=Cloud9-AwesomeAdmin

# Function to get the status of a CFN template
get_stack_status () {
status=$(aws cloudformation describe-stacks --stack-name $1)
if [ $? -eq 0 ]; then
echo "$status" | jq -r ".Stacks[].StackStatus"
else
echo "DELETE_COMPLETE"
fi
}

cat > cfn-policy.json<< EOF
{
Expand All @@ -42,18 +52,32 @@ ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text)
## Create a temporary Admin role
aws iam create-role --role-name "$ROLE_NAME" --assume-role-policy-document file://cfn-policy.json
aws iam attach-role-policy --role-name "$ROLE_NAME" --policy-arn "arn:aws:iam::aws:policy/AdministratorAccess"
rm cfn-policy.json

## Wait a bit for this role to stick. It cannot be used immediately after creation.
sleep 15
sleep 10

## Delete stacks
stacks=(sam-app-prod sam-app-dev sam-app-pipeline aws-sam-cli-managed-prod-pipeline-resources aws-sam-cli-managed-dev-pipeline-resources)

for name in "${stacks[@]}"
for stack_name in "${stacks[@]}"
do
echo "Deleting stack: $name..."
aws cloudformation delete-stack --role-arn "arn:aws:iam::$ACCOUNT_ID:role/$ROLE_NAME" --stack-name "$name"
sleep 10
echo "Deleting stack: $stack_name..."

aws cloudformation delete-stack \
--role-arn "arn:aws:iam::$ACCOUNT_ID:role/$ROLE_NAME" \
--stack-name "$stack_name"

status="$(get_stack_status $stack_name)"

# Wait until the stack is actually deleted
while [ "$status" != "DELETE_COMPLETE" ]
do
sleep 5
status="$(get_stack_status $stack_name)"
echo "$stack_name: $status"
done

done

## Delete the temporary Admin role
Expand Down
4 changes: 2 additions & 2 deletions workshop/content/local/change/_index.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ simple change. Change the response message to return `hello my friend` instead o

`~environment/sam-app/hello-world/app.js`

```js
```js {hl_lines=["8"]}
let response

exports.lambdaHandler = async (event, context) => {
Expand All @@ -37,7 +37,7 @@ exports.lambdaHandler = async (event, context) => {
{{% tab name="python" %}}
`~environment/sam-app/hello_world/app.py`

```python
```python {hl_lines=["7"]}
import json

def lambda_handler(event, context):
Expand Down
10 changes: 4 additions & 6 deletions workshop/content/sam/code/_index.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,12 @@ date = 2019-10-02T15:21:26-07:00
weight = 15
+++

{{% notice note %}}
If you consider yourself an expert using Lambda functions, you can probably skip this page.
{{% /notice%}}

Let's take a look at the code of the Hello World Lambda function.

**Note** that your function may have additional commented out code, those lines have been removed
from the following example for clarity.
{{% notice note %}}
Your function may have additional comments. Those lines have been removed from the following example
for clarity.
{{% /notice%}}

{{< tabs >}}
{{% tab name="Node" %}}
Expand Down
12 changes: 8 additions & 4 deletions workshop/content/sam/init/_index.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,14 @@ Which runtime would you like to use?
14 - ruby2.7
```

- Node: `nodejs14.x`
- Python: `python3.7`
- Java: `python3.7`
- C#: `dotnet6`
{{< tabs >}}
{{% tab name="Node" %}}
`nodejs14.x`
{{% /tab %}}
{{% tab name="python" %}}
`python3.7`
{{% /tab %}}
{{% /tabs %}}

Select `Zip` as the package type and leave `sam-app` as the `Project name`.

Expand Down
Loading

0 comments on commit efe632c

Please sign in to comment.