1
1

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 5 years have passed since last update.

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

Posted at

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

#やりたいこと(最終的な構成)
以下のようにラムダで動くアプリケーションを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.

1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?