LoginSignup
1

More than 3 years have passed since last update.

posted at

Serverlessで独自ドメイン適用+Lambdaへ色々まとめてデプロイ

サーバーレスアプリケーションをデプロイする際に、色々とハマッたのでメモ。
前回、フロントのデプロイについてのメモを書きましたが、今回はバックエンド編です。

やりたいこと(最終的な構成)

以下のようにラムダで動くアプリケーションをAWS上にデプロイするために、
必要な設定ファイルを作成する。
AWS network diagram (2).png

前提

・独自ドメインとその証明書が取得済みである
・node.js及びServerless Frameworkがインストール済みである

手順

大まかな手順は以下の通り。
-Serverless.ymlの設定
1.APIベースパスマッピング
2.Functionと対応するAPIの記述
3.DynamoDBの指定
4.Cognitoの指定

-初回デプロイ前に必要な作業
1.AWSのアカウント認証
2.create_domain

もう少し詳しく書いていきます。

serverless.ymlの設定

1.APIベースパスマッピング(custom:エリア)

以下のように、custom:エリアに必要な情報を記載する。
basePathにAPIコールする際のベースとなるドメインを記載。
(APIはhttps://[api.domain.name]/[bathPath]/***の形でコールされる)

serverless.yml
service: [service-name]

provider:
  name: aws
  runtime: go1.x
  stage: ${opt:stage, env:STAGE, 'dev'}
  region: ${opt:region, env:REGION, '[region]'}

plugins:
  - serverless-domain-manager

custom:
  customDomain:
    domainName: [api.domain.name]
    stage: ${self:provider.stage}
    basePath: '[basePath_name]'
    certificateName: '[*.api.domain.name]'
    createRoute53Record: true

2.Functionと対応するAPIの記述(functions:エリア)

以下のように対応するFunctionを記述していく。
(APIはhttps://[api.domain.name]/[bathPath]/[api_name]の形でコールされる)

serverless.yml
service: [service-name]

functions:
  Function_name:
    handler: bin/[Functionのmain.goが配置されたフォルダ名]
    events:
      - http:
          path: /[api_name]
          method: post
          cors: true

3.DynamoDBの指定(environment:エリア)

APIコールをトリガーとしてS3やDynamoDBに接続したい場合、environmentにS3bucketNameやDynamoDBの名前を記載する。
接続先がCloudFormationを利用して作られている場合、"cf:"をつけて指定するだけでよい。
参考:Serverless FrameworkからCloudFormationの出力値(Outputs)を参照する

serverless.yml
service: [service-name]

provider:
  name: aws
  runtime: go1.x
  stage: ${opt:stage, env:STAGE, 'dev'}
  region: ${opt:region, env:REGION, '[region]'}
  environment:
    STAGE: ${self:provider.stage}
    REGION: ${self:provider.region}
    TABLE_NAME: ${cf:[スタック名].[テーブル名]}

4.ユーザー認証の記述(custom:エリア、functions:エリア)

今回はAWS Cognitoを使ってユーザー認証を行うので、その際はauthorizer欄に
arn: COGNITO_USER_POOL_ARNを指定する。
CloudFormtaionを使ってUserPoolを作成している場合は以下のように書く。

serverless.yml
service: [service-name]

custom:
  authorizer:
    arn: arn:aws:cognito-idp:${self:provider.region}:99999999999:userpool/${cf:[スタック名].[UserPool名]}
    identitySource: method.request.header.Authorization
  customDomain:
    domainName: [api.domain.name]
    stage: ${self:provider.stage}
    basePath: '[basePath_name]'
    certificateName: '[*.api.domain.name]'
    createRoute53Record: true

functions:
  Function_name:
    handler: bin/[Functionのmain.goが配置されたフォルダ名]
    events:
      - http:
          path: /[api_name]
          method: post
          cors: true
          authorizer: ${self:custom.authorizer}

初回デプロイ前に必要な作業

1.AWSアカウント認証

まずServerless用のIAMユーザーを作成する。
・Policyは「AdministratorAccess」
・アクセスの種類は、「プログラムによるアクセス」のみチェック。
作成後に表示されるアクセスキーIDとシークレットアクセスキーを利用し、以下のコマンドを実行する。

serverless config credentials --provider aws --profile serverless --key [アクセスキーID] --secret [シークレットアクセスキー]

create_domain

以下の記事を参考に、create_domainコマンドを実行。
Serverless(node.js)で独自ドメインSSLの適用方法

実行に成功すると、カスタムドメイン名が登録されているのが確認できます。
image.png

以上!

sls deployをすればデプロイされます。

参考

デプロイ成功後に、以下のCORSエラーが出て、なぜ???と思っていたのですが、
指定するUserPoolが間違っていたためでした。
全然関係ないHTTPヘッダーのセット箇所とか見てしまっていて解決に時間かかりました…。

Access to XMLHttpRequest at 'https://api.domain.name/bath-path/function' from origin 'https://reqested.url' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

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
What you can do with signing up
1