Alibaba CloudのAPI GatewayをHTTPS化する

独自ドメインを設定したAPI GatewayのエンドポイントをHTTPS対応させます。なお、Function Computeをバックグラウンドで動かしています。

基本は以下の公式ドキュメントを参考にしました。

jp.alibabacloud.com

SSL証明書の取得

私はさくらのRapidSSLで取得しました。SSL証明書買ったの久々です。

CSR作成なんかは完全に忘れていましたので以下を参考にしました。

qiita.com

サーバー認証

API Gatewayでちょっと苦労するのがサーバー認証キーのアップロードです。

普通のサーバーのようにファイルをアップロードすることはできないので、API Gatewayのエンドポイントを/.well-known/pki-validation/fileauth.txtと設定してGETで認証キーを返すようにします。

webコンソール画面からだとAPI Gatewayのエンドポイントに/.well-known/pki-validation/fileauth.txtを設定することができなかった(多分ドットがバリデーションエラーになる)ので、template.ymlを使ってデプロイします。

ROSTemplateFormatVersion: '2015-09-01'
Transform: 'Aliyun::Serverless-2018-04-03'
Resources:
  MyService: # service name
    Type: 'Aliyun::Serverless::Service'
    Properties:
      Description: 'my fc'
    myfunction: # function name
      Type: 'Aliyun::Serverless::Function'
      Properties:
        Handler: index.handler
        Runtime: nodejs8
        CodeUri: './'
        Timeout: 60

  MyFunctionGroup: # group name
    Type: 'Aliyun::Serverless::Api'
    Properties:
      StageName: RELEASE
      DefinitionBody:
        '/.well-known/pki-validation/fileauth.txt':
          get:
            x-aliyun-apigateway-api-name: myfunction
            x-aliyun-apigateway-fc:
              arn: acs:fc:::services/${MyService.Arn}/functions/${myfunction.Arn}/

index.jsはこちらです。

module.exports.handler = (event, context, callback) => {
  callback(null, { statusCode: 200, body: 'YOUR KEY IN fileauth.txt' });
};

API GatewayのFunction GroupにSSL証明書を追加する

画面をポチポチしてSSL証明書を追加します。

Function GroupからSSL証明書を追加します。 f:id:asmsuechan:20180912160130p:plain

秘密鍵はパスワードを削除する必要があります。 f:id:asmsuechan:20180912161000p:plain

HTTPSで通信できるようにする

次にAPI GatewayHTTPSを受け取るように変更します。template.ymlで設定を定義している人は画面からでは変更できません。template.ymlを変更しましょう。

template.ymlに以下を追加します。

            x-aliyun-apigateway-request-config:
              requestProtocol: 'https'

以下はtemplate.ymlの全体です。

ROSTemplateFormatVersion: '2015-09-01'
Transform: 'Aliyun::Serverless-2018-04-03'
Resources:
  MyService: # service name
    Type: 'Aliyun::Serverless::Service'
    Properties:
      Description: 'my fc'
    myfunction: # function name
      Type: 'Aliyun::Serverless::Function'
      Properties:
        Handler: index.handler
        Runtime: nodejs8
        CodeUri: './'
        Timeout: 60

  MyFunctionGroup: # group name
    Type: 'Aliyun::Serverless::Api'
    Properties:
      StageName: RELEASE
      DefinitionBody:
        '/':
          get:
            x-aliyun-apigateway-api-name: myfunction
            x-aliyun-apigateway-request-config:
              requestProtocol: 'https'
            x-aliyun-apigateway-fc:
              arn: acs:fc:::services/${MyService.Arn}/functions/${myfunction.Arn}/

これをfun deployしたらHTTPS対応が完了します。

Tips

curlを送った時のレスポンスのserverがTengineならFunction Computeまでリクエストが渡っていて、nginxならAPI Gatewayがレスポンスを返しています。