Tag Archives: AWS

Overriding Global Variables – AWS SAM Local

Hi everyone,

Today I’ve added local overrides to the global variables in my template.yml file. This was pretty finicky – a lot of conflicting suggestions out there unfortunately. These are the settings that ended up working for me.

local-env-var-overrides.json:

{
    "Parameters": {
        "RDS_HOSTNAME_TEST": "192.168.0.31"
    }
}

template.yaml

Globals:
  Function:
    Environment:
      Variables:        
        RDS_HOSTNAME_TEST:
          Type: String
          Default: 'DEFAULT'

aws sam local command:

sam local start-api --env-vars "local-env-var-overrides.json"

create.js

exports.createTrapHandler = async (event, context, callback) => {

	try {

        console.log("RDS_HOSTNAME_TEST: " + process.env.RDS_HOSTNAME_TEST)
        // Outputs: 192.168.0.31

This link ended up being pretty useful: https://www.npmjs.com/package/aws-sam-local

Advertisements

Get User Id in Lambda node.js

Hi everyone,

A quick post on where to find the user id (sub) in a lambda requested that has been authenticated with a congito authorizer.

You’ll be able to find everything you need in the event object under requestContext > authorizer > claims:


exports.viewContextHandler = async (event, context, callback) => {
    console.log(JSON.stringify(event.requestContext));
}

"requestContext": {
    "resourceId": "XXXXX",
    "authorizer": {
        "claims": {
            "at_hash": "XXXXX",
            "sub": "XXXXX-XXXXX-XXXXX-XXXXX-XXXXX",
            "aud": "XXXXX12341234512345XXXXX",
            "email_verified": "true",
            "token_use": "id",
            "auth_time": "1547371205",
            "iss": "https://cognito-XXXXX.com/XXXXX",
            "cognito:username": "XXXXX-XXXXX-XXXXX-XXXXX-XXXXX",
            "exp": "Sun Jan 13 10:20:05 UTC 2019",
            "iat": "Sun Jan 13 09:20:05 UTC 2019",
            "email": "XXXXX@XXXXX.XXXXX"
        }
    },
}

Cognito Auth with AWS SAM

Hi everyone,

I’ve spent today implementing Cognito with AWS SAM and it took quite a while to work out what needed to be done – unfortunately there’s a lot of conflicting doco out there. Posting a sample template just in case it’s able to help anyone else out.

The first thing to do is to explicitly define you rest API. By default AWS SAM will generate one with a default logical id of ServerlessRestApi. You’ll need to override this:

Resources:
  # See links for more info
  # Referencing cognito authorizer: https://github.com/awslabs/serverless-application-model/issues/512#issuecomment-411284092
  # Logical id is auto generated: https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
  # Sample template.yml: https://github.com/awslabs/serverless-application-model/blob/release/v1.8.0/examples/2016-10-31/api_cognito_auth/template.yaml
  MyCustomApi:
    Type: "AWS::Serverless::Api"
    Properties:
      StageName: Prod
      Auth: # We will eventually define other auth options here such as Usage Plans/Api Keys, AWS_IAM, and Resource Policies
        DefaultAuthorizer: MyCustomCognitoAuthorizer
        Authorizers:
          MyCustomCognitoAuthorizer:
            UserPoolArn: !GetAtt MyCustomCognitoUserPool.Arn # Can be a string, or array
            # Identity: # Optional
              # Header: ... # Optional; Default: Authorization
              # ValidationExpression: ...  # Optional; ensures the request header matches a pattern before checking in with the Authorizer endpoint; is there a default we can set for Cognito User Pools Auth?

You’ll also need to create a user pool and client:

# Creating a cognito user pool - https://github.com/awslabs/serverless-application-model/blob/master/examples/2016-10-31/api_cognito_auth/template.yaml
  MyCustomCognitoUserPool:
    Type: AWS::Cognito::UserPool
    Properties:
      UserPoolName: !Ref CognitoUserPoolName
      # LambdaConfig:
        # PreSignUp: !GetAtt PreSignupLambdaFunction.Arn
      Policies:
        PasswordPolicy:
          MinimumLength: 8
      UsernameAttributes:
        - email
      Schema:
        - AttributeDataType: String
          Name: email
          Required: false

  MyCustomCognitoUserPoolClient:
    Type: AWS::Cognito::UserPoolClient
    Properties:
      UserPoolId: !Ref MyCustomCognitoUserPool
      ClientName: !Ref CognitoUserPoolClientName
      GenerateSecret: false

You then add the api id and the auth attribute to each of your function properties. If you’ve used the default authorizer property when defining the associated api you can override it by using authorizer: none.

GetBreedFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: breed.getBreedHandler
      Policies: arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess
      Runtime: nodejs8.10
      Environment:
        Variables:
          TABLE_CAT_BREED: !Ref CatBreedTable
      Events:
        GetEvent:
          Type: Api
          Properties:
            Path: /breed/{breedId}
            Method: get
            RestApiId: !Ref MyCustomCustomApi
            Auth:
              Authorizer: NONE

Hopefully that’s able to help you out. If you run into any trouble I found the following link pretty useful: https://github.com/awslabs/serverless-application-model/blob/release/v1.8.0/examples/2016-10-31/api_cognito_auth/template.yaml

AWS SAM not re-creating DynamoDb Table that was manually deleted – CodeStar

Hi everyone,

I ran into a bit of an issue after deleting a DynamoDb table via the AWS Console that had been created via CloudFormation (using AWS SAM). After deleting it I had expected it to be re-created automatically on the next deploy. Unfortunately this didn’t happen.

I came across the following AWS article that does a pretty good job of summarising the issue: https://aws.amazon.com/premiumsupport/knowledge-center/failing-stack-updates-deleted/

To fix it, I removed all references to the table from my template.yml file (this includes the table definition and any !Ref tags). After pushing this changeset I returned all of the references and re-pushed.

Let me know if you have any issues!

Cheers,
Chris

mocha tests/* sh: 1: mocha: Permission denied – AWS CodeBuild with Node.js

Hi everyone,

I ran into the following error while running a Node.js build with AWS CodeBuild:

mocha tests/* sh: 1: mocha: Permission denied

To resolve this I removed node_modules from my repository and added it to .gitignore:

node_modules/

Thanks to the following links for the info:
Add node_modules to gitignore: https://stackoverflow.com/a/29820869/522859
Misc background issues: https://github.com/mochajs/mocha/issues/1487

Parsing DynamoDB Items – AWS Lambda with Node.js

Hi everyone,

A quick post on how to parse DynamoDB items into something more readable when using lambda with Node.js:

Original:

console.log(data["Item"]);

{
    CatBreedId: { S: '17acbc81-2b4a-462b-be87-bcc49580b1ae'},
    Name: { S: 'Cat #1'}
}

Parsed:

console.log(AWS.DynamoDB.Converter.unmarshall(data["Item"]));

{
    "CatBreedId": "17acbc81-2b4a-462b-be87-bcc49580b1ae",
    "Name": "Cat #1"
}

Official doco is here: https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB/Converter.html

Thanks to the following stackoverflow post for the info: https://stackoverflow.com/a/44536616/522859

Create DynamoDB Table – AWS CLI

Hi everyone,

A quick example of how to create a dynamodb table using the AWS CLI:

aws dynamodb create-table --table-name CatBreeds --attribute-definitions AttributeName=CatBreedId,AttributeType=S --key-schema AttributeName=CatBreedId,KeyType=HASH --provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5

For more info the following AWS page helped me: https://docs.aws.amazon.com/cli/latest/reference/dynamodb/create-table.html