Neptunian Parity Mnemonic

    serverless-find-resource

    1.0.11 • Public • Published

    serverless-find-resource

    This Serverless plugin replaces AWS resource names with their ARNs or IDs in your Serverless template.

    Some Serverless resource references have to be hardcoded if they're created outside of the current Serverless template - even if they're created by another Serverless template in the same project. In multi-template projects, this results in hardcoding resource IDs or creating lots of exports just to reference AWS resource ARNs/IDs. As a result, your Serverless templates lose flexibility and require a bunch of changes when just one resource changes. For example, if you expect your system's Cognito User Pool to be manually created but still want to attach a pre-token-generation trigger to it, you have to update your template in every environment to point to the correct Cognito User Pool ID. If you need to switch between dev/QA/prod accounts, you have to update any account-specific IDs.

    This Serverless plugin fixes that. Instead of hardcoding resource ARNs and IDs, you can use your resource names in your Serverless templates, and this plugin will replace it with the appropriate resource ARN/ID by inspecting the resources in your AWS account (via the CLI). Even better, if there's only one resource of the given type, Serverless Find Resource can assume that you need that resource's ARN/ID unless you specify a name.

    That means that a simple Serverless template could reference zero AWS resource identifiers, making it far more flexible and portable across environments.

    Installation

    serverless-find-resource is available on npm: https://www.npmjs.com/package/serverless-find-resource.

    1. Run npm i serverless-find-resource --save-dev. Of course you also need Serverless to be installed because this is a Serverless plugin.
    2. In your Serverless template add serverless-find-resource to your plugins section:
    plugins:
      - serverless-find-resource
    

    Early Access

    If you don't want to wait for releases, you can get bleeding-edge updates by adding "serverless-find-resource": "https://github.com/steveperkins/serverless-find-resource#master" to your package.json's dependencies or devDependencies.

    Usage

    Replace your hardcoded IDs with find: variables anywhere in your Serverless template except region, stage, and credentials.

    For example, this:

    provider:
      name: aws
      stage: ${self:custom.stage}
      region: ${self:custom.region}
      environment:
        USER_POOL_ID: us-east-1_D93eA2
    

    becomes this:

    provider:
      name: aws
      stage: ${self:custom.stage}
      region: ${self:custom.region}
      environment:
        USER_POOL_ID: ${find:CognitoUserPoolId:yourUserPoolName}
    

    Serverless Find Resource will now replace ${find:CognitoUserPoolId} with the ID of your AWS account's user pool named yourUserPoolName.

    A more complex example is for finding an API Gateway Trigger authorizer lambda ID:

    XXXApigatewayTrigger:
          Type: AWS::Lambda::Permission
          Properties:
            Action: lambda:InvokeFunction
            FunctionName: !GetAtt AuthorizeLambdaFunction.Arn
            Principal: apigateway.amazonaws.com
            SourceArn: arn:aws:execute-api:${self:config.region}:${self:config.accountNo}:${find:ApiGatewayId:ApiGatewayName}/authorizers/${find:ApiGatewayAuthorizerId:ApiGatewayName/lambdaAuthorizerName}
    

    Spaces

    Some AWS resource names can have spaces. For example, a VPC subnet could be named something like "Private Subnet". Serverless removes all spaces before passing the value to the variable resolver, so in such cases you have to enclose the value in single quotes in order to preserve the spaces:

    ${find:SubnetId:'Private Subnet'}
    

    Finding Resources by Default

    If you have only one of a resource type in your AWS account, you don't even have to provide a name - Serverless Find Resource will just use that resource. The syntax is very straightforward - you just don't include the name:

    ${find:CognitoUserPoolId}
    

    That makes your Serverless template very clean for shared resources like Cognito User Pools, RDS databases, API Gateways, etc in smaller infrastructures. Be aware that AWS might create unexpected resources on your behalf when working via the AWS UI.

    Supported Resource Types

    Type Key Returns Example
    Cognito User Pool CognitoUserPoolId Cognito User Pool's ID ${find:CognitoUserPoolId:yourUserPoolName}
    Cognito User Pool CognitoUserPoolArn Cognito User Pool's Arn ${find:CognitoUserPoolArn:yourUserPoolName}
    Cognito App Client CognitoAppClientId Cognito App Client's ID ${find:CognitoAppClientId:yourUserPoolName.yourAppClientName}
    IAM Role RoleArn Role's ARN ${find:RoleArn:yourRoleName}
    IAM Role RoleId Role's ID ${find:RoleId:yourRoleName}
    Lambda Layer LambdaLayerArn Latest layer ARN ${find:LambdaLayerArn:yourLayerName}
    Security Group SecurityGroupId Group's ID ${find:SecurityGroupId:yourGroupName}
    Subnet SubnetId Subnet's ID ${find:SubnetId:yourSubnetName}
    API Gateway ApiGatewayId API Gateway's ID ${find:ApiGatewayId:yourApiGatewayName}
    API Gateway Authorizer ApiGatewayAuthorizerId API Gateway Authorizer ID ${find:ApiGatewayAuthorizerId:yourApiGatewayName.yourAuthorizerName}

    A note about API Gateway

    Until now Mike Souza's import-api-gateway plugin did a great job of working around the CloudFormation constraint that prevents you from attaching lambda HTTP event handlers to an API Gateway NOT created in the same Serverless file (what a weird and limiting requirement, CloudFormation team). On October 20, 2020 Mike deprecated his plugin citing Serverless' new support for attaching to existing API Gateways. However, Serverless' support does NOT work for REST API Gateways - only for HTTP API Gateways (API Gateway V2). Mike's plugin is still needed. Since it's been deprecated, I've rolled Mike's plugin with Jason Maldonis' contribution into the ${find:ApiGatewayId} functionality - because if you're trying to access the API Gateway ID, it's almost certain that you're trying to attach resources to an existing API Gateway. Therefore, when you use ${find:ApiGatewayId}, serverless-find-resource will automatically attach your Serverless template's HTTP endpoints to your API Gateway.

    An easy way to leverage this functionality in your Serverless template is to add an apiGateway.restApiId to your provider element:

    provider:
      apiGateway:
        restApiId: ${find:ApiGatewayId}
    

    A note about Serverless v1, v2, and v3 variable resolvers

    Serverless v3 introduced a new, backwards-incompatible plugin variable resolver in v3. serverless-find-resource supports v1 (now deprecated), v2, and v3. Make sure to put frameworkVersion: '3' at the top of your .serverless file if you want to use v3 plugin variable resolution. Thank you @wktk for raising a PR for this.

    Install

    npm i serverless-find-resource

    DownloadsWeekly Downloads

    23

    Version

    1.0.11

    License

    MIT

    Unpacked Size

    35.9 kB

    Total Files

    18

    Last publish

    Collaborators

    • steveperkins