3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Lambda + Goでネストされたアプリケーションを構築

Last updated at Posted at 2021-03-23

1280px-Go_Logo_Aqua.svg.png

LambdaでGoを使ったAPIを作成したときの話
あるサービスでGoを採用し、Lambda上でapiを作成することになった、最初は小規模の認識で開発を行っていたが、仕様がどんどん膨らみ気づいた時にはエンドポイントが150を超え、そしてやってきたリソース制限

Template format error: Number of resources, 206, is greater than maximum allowed, 200

ネストさせることで回避できることを知り、ネストするもsam buildできず、結局ネストされた各アプリケションを個別にビルドし、マージするシェルを書いて運用していた。
苦労した話を書こうと思い調べていると、いつの間にかネストされたアプリケーションのビルドができるようになっていた!!!

スクリーンショット 2021-03-20 23.32.41.png
https://github.com/aws/aws-sam-cli/issues/1470

前段の話が長くなりましたが、Lambdaでネストされたアプリケーションを簡単に構築できる話です

構築

2つのアプリケーションにネストさせる例です

template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  lambda-go
  Sample SAM Template for lambda-go

Parameters:
  Region:
    Type: String
    Default: ap-northeast-1
  Stage:
    Type: String
    Default: Dev
  ApiDomainName:
    Type: String
    Default: api.example.com

Resources:
  # Lambda Application
  App1Application:
    Type: AWS::Serverless::Application
    Properties:
      Location: app1.yaml
      Parameters:
        Region: !Ref Region
        Stage: !Ref Stage
        ApiDomainName: !Ref ApiDomainName
  App2Application:
    Type: AWS::Serverless::Application
    Properties:
      Location: app2.yaml
      Parameters:
        Region: !Ref Region
        Stage: !Ref Stage
        ApiDomainName: !Ref ApiDomainName

アプリケーション1

app1.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  lambda-go
  Sample SAM Template for lambda-go
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
  Function:
    Timeout: 10
    Environment: # More info about Env Vars: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#environment-object
      Variables:
        REGION: !Ref Region

Parameters:
  Stage:
    Type: String
  Region:
    Type: String
  ApiDomainName:
    Type: String

Resources:
  # ロール
  App1Role:
    Type: AWS::IAM::Role
    Properties:
      RoleName: app1-role
      Policies:
        - PolicyName: app1-policy
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - ec2:CreateNetworkInterface
                  - ec2:DescribeNetworkInterfaces
                  - ec2:DetachNetworkInterface
                  - ec2:DeleteNetworkInterface
                Resource: '*'
      AssumeRolePolicyDocument: {
        Version: "2012-10-17",
        Statement: [
          {
            Effect: "Allow",
            Principal: {
              Service: [
                  "lambda.amazonaws.com"
              ]
            },
            Action: [
                "sts:AssumeRole"
            ]
          }
        ]
      }
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
      Path: /

  # Api Gateway
  ApiGateway:
    Type: AWS::Serverless::Api
    Properties:
      StageName: !Ref Stage

  # Base path mapping
  ApiGatewayBasePathMapping:
    Type: AWS::ApiGateway::BasePathMapping
    Properties:
      DomainName: !Ref ApiDomainName
      RestApiId: !Ref ApiGateway
      BasePath: app1
      Stage: !Ref ApiGateway.Stage

  # Lambda Function
  Test1Function:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      CodeUri: ../../test1/
      Handler: test1
      Runtime: go1.x
      Tracing: Active # https://docs.aws.amazon.com/lambda/latest/dg/lambda-x-ray.html
      Role: !GetAtt App1Role.Arn
      Events:
        GET:
          Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
          Properties:
            RestApiId: !Ref ApiGateway
            Path: /test1
            Method: GET
  Test2Function:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      CodeUri: ../../test2/
      Handler: test2
      Runtime: go1.x
      Tracing: Active # https://docs.aws.amazon.com/lambda/latest/dg/lambda-x-ray.html
      Role: !GetAtt App1Role.Arn
      Events:
        GET:
          Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
          Properties:
            RestApiId: !Ref ApiGateway
            Path: /test2
            Method: GET
  Test3Function:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      CodeUri: ../../test3/
      Handler: test3
      Runtime: go1.x
      Tracing: Active # https://docs.aws.amazon.com/lambda/latest/dg/lambda-x-ray.html
      Role: !GetAtt App1Role.Arn
      Events:
        GET:
          Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
          Properties:
            RestApiId: !Ref ApiGateway
            Path: /test3
            Method: GET

アプリケーション2

app2.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  lambda-go
  Sample SAM Template for lambda-go
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
  Function:
    Timeout: 10
    Environment: # More info about Env Vars: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#environment-object
      Variables:
        REGION: !Ref Region

Parameters:
  Stage:
    Type: String
  Region:
    Type: String
  ApiDomainName:
    Type: String

Resources:
  # ロール
  App2Role:
    Type: AWS::IAM::Role
    Properties:
      RoleName: app2-role
      Policies:
        - PolicyName: app2-policy
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - ec2:CreateNetworkInterface
                  - ec2:DescribeNetworkInterfaces
                  - ec2:DetachNetworkInterface
                  - ec2:DeleteNetworkInterface
                Resource: '*'
      AssumeRolePolicyDocument: {
        Version: "2012-10-17",
        Statement: [
          {
            Effect: "Allow",
            Principal: {
              Service: [
                  "lambda.amazonaws.com"
              ]
            },
            Action: [
                "sts:AssumeRole"
            ]
          }
        ]
      }
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
      Path: /

  # Api Gateway
  ApiGateway:
    Type: AWS::Serverless::Api
    Properties:
      StageName: !Ref Stage

  # Base path mapping
  ApiGatewayBasePathMapping:
    Type: AWS::ApiGateway::BasePathMapping
    Properties:
      DomainName: !Ref ApiDomainName
      RestApiId: !Ref ApiGateway
      BasePath: app2
      Stage: !Ref ApiGateway.Stage

  # Lambda Function
  Test10Function:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      CodeUri: ../../test10/
      Handler: test10
      Runtime: go1.x
      Tracing: Active # https://docs.aws.amazon.com/lambda/latest/dg/lambda-x-ray.html
      Role: !GetAtt App2Role.Arn
      Events:
        GET:
          Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
          Properties:
            RestApiId: !Ref ApiGateway
            Path: /test10
            Method: GET
  Test11Function:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      CodeUri: ../../test11/
      Handler: test11
      Runtime: go1.x
      Tracing: Active # https://docs.aws.amazon.com/lambda/latest/dg/lambda-x-ray.html
      Role: !GetAtt App2Role.Arn
      Events:
        GET:
          Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
          Properties:
            RestApiId: !Ref ApiGateway
            Path: /test11
            Method: GET
  Test12Function:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      CodeUri: ../../test12/
      Handler: test12
      Runtime: go1.x
      Tracing: Active # https://docs.aws.amazon.com/lambda/latest/dg/lambda-x-ray.html
      Role: !GetAtt App2Role.Arn
      Events:
        GET:
          Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
          Properties:
            RestApiId: !Ref ApiGateway
            Path: /test12
            Method: GET

ネスト以外のポイントとして、API GatewayのAPI マッピングを使ってネストされたアプリケーションをマッピングしています。

app1.yaml,app2.yaml
  ApiGatewayBasePathMapping:
    Type: AWS::ApiGateway::BasePathMapping
    Properties:
      DomainName: !Ref ApiDomainName
      RestApiId: !Ref ApiGateway
      BasePath: app2
      Stage: !Ref ApiGateway.Stage

これをすると、template.yamlで指定している、ApiDomainName(api.example.com)で各ネストされたアプリケーションにアクセスできるようになる
例えば、https://api.example.com/app1/test1 とか https://api.example.com/app2/test10 など
*実際に試して頂く場合はApiDomainNameを変更して頂く必要があります

デプロイ

デプロイ時にはcapabilitiesCAPABILITY_AUTO_EXPANDを指定しデプロイをおこないます、成功するとCloudFormationでネストされたアプリケーションが表示されます

スクリーンショット 2021-03-22 20.21.31のコピー.jpg

ソース

参考までにソースをあげておきました。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?