Running AWS SAM CLI Local on scrutinizer
Tags: aws, devops
Published: 2020-09-11 13:28:16

If you are trying to run AWS SAM CLI Local you will run into the following message quite soon: 

```
Error: Running AWS SAM projects locally requires Docker. Have you got it installed?
```

AWS SAM requires for docker API version v1.35, when starting SAM LOCAL it will query the Docker API for the [ping endpoint](https://docs.docker.com/engine/api/v1.35/#operation/SystemPing). Scrutinizer runs a lower version of Docker by default so calling this endpoint will result in a `400` status code.

## Using a more recent version of Docker in Scrutinizer
To use a more recent version scrutinizer supplies a remote docker engine. 
```yaml
build:
  environment:
    docker: 
      remote_engine: true
```

## Installing AWS SAM Local
Installing AWS SAM Local is quite straight forward:
```yaml 
project_setup:
    before:
      # Install SAM CLI
      - pip install aws-sam-cli==1.12.0 # Fixed to version because of a bug in SAM Local: https://github.com/aws/aws-sam-cli/issues/2436
      - curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
      - unzip awscliv2.zip
      - sudo ./aws/install

      # Configure AWS defaults
      - aws configure set aws_access_key_id scrutinizer_fake_key
      - aws configure set aws_secret_access_key scrutinizer_fake_secret
      - aws configure set default.region eu-west-1

      # Install the readmodel
      - make install
      - make set_up_dynamodb

      # Start Lambda
      - command: sam local start-lambda -t cloudformation.yaml 
        background: true 
```

## Making source code available
The remote engine can not access the code that is stored in the Scrutinizer container, which means that AWS SAM Local will present you with the following result: 

`sam local {"errorType":"Runtime.HandlerNotFound"}`

Which means as much that AWS SAM Local cannot find the defined handler in your cloudformation code. 

To make the source code available to the remote engine a intermediate docker container can be used:
```yaml
- docker run -v /home/scrutinizer/build:/remote-host -d --name cp-container busybox
- docker cp /home/scrutinizer/build cp-container:/remote-host
``` 

This will copy your code to the volume attached to the busybox, this volume will be used by AWS SAM Local. 

## Tools used to figure this problem out

* `--debug` flag on AWS SAM Local commands
* Scrutinizer support which replied really fast!

## Complete Scrutinizer Setup
```yaml
build:
  environment:
    docker: 
      remote_engine: true
  project_setup:
    before:
      # Install SAM CLI
      - pip install aws-sam-cli
      - curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
      - unzip awscliv2.zip
      - sudo ./aws/install

      # Configure AWS defaults
      - aws configure set aws_access_key_id scrutinizer_fake_key
      - aws configure set aws_secret_access_key scrutinizer_fake_secret
      - aws configure set default.region eu-west-1
    
      # Copy data to remote docker volume 
      - docker run -v /home/scrutinizer/build:/remote-host -d --name cp-container busybox
      - docker cp /home/scrutinizer/build/code cp-container:/remote-host/code

      # Start API and Lambda
      - command: sam local start-lambda -t cloudformation.yaml
        background: true  
  tests:
    override:
      - sam local invoke -t cloudformation.yaml "ProcessStream" --no-event
```