kasei_sanのブログ

かせいさんのIT系のおぼえがきです。胡乱の方はnoteとtwitterへ

AWS SDK for Ruby で Application Load Balancer にいろいろな Listener を追加する方法おぼえがき

Listenerとは

リスナーとは、設定したプロトコルとポートを使用して接続リクエストをチェックするプロセスです。リスナーに対して定義したルールにより、ロードバランサーが登録済みターゲットにリクエストをルーティングする方法が決まります。

Application Load Balancer のリスナー - Elastic Load Balancing

80番ポートのリクエストを443番ポートにリダイレクトする

client = Aws::ElasticLoadBalancingV2::Client.new
client.create_listener(
  default_actions: [
    {
      type: 'redirect',
      order: 1,
      redirect_config: {
        protocol: 'HTTPS',
        port: '443',
        host: '#{host}',
        path: '/#{path}',
        query: '#{query}',
        status_code: 'HTTP_301'
      }
    },
  ],
  load_balancer_arn: LOAD_BALANCER_ARN,
  port: 80,
  protocol: 'HTTP'
)

443番ポートのリクエストを特定のターゲットグループに渡す

client.create_listener(
  certificates: [
    certificate_arn: CERTIFICATE_ARN,
  ],
  default_actions: [
    {
      target_group_arn: TARGET_GROUP_ARN,
      type: 'forward'
    },
  ],
  load_balancer_arn: LOAD_BALANCER_ARN,
  port: 443,
  protocol: 'HTTPS',
  ssl_policy: 'ELBSecurityPolicy-2015-05'
)

443番ポートのリクエストの場合503を返す

client.create_listener(
  certificates: [
    certificate_arn: CERTIFICATE_ARN,
  ],
  default_actions: [
    {
      type: 'fixed-response',
      fixed_response_config: {
        status_code: '503'
      }
    },
  ],
  load_balancer_arn: LOAD_BALANCER_ARN,
  port: 443,
  protocol: 'HTTPS',
  ssl_policy: 'ELBSecurityPolicy-2015-05'
)
  • status_code の値は数字ではなく文字列

参考

公式ドキュメント

serverless で AWS lambda のログ出力の有効期限を制御する方法

サンプル

function hoge_fuga-aaa の出力先ロググループの有効期限を30日にする場合

serverless.yml

functions:
  hoge_fuga-aaa:
    handler: handler.api_create
    events:
      - http:
          path: api/create
          method: post
resources:
  Resources:
    HogeUnderscoreFugaDashAaaLogGroup:
      Properties:
        RetentionInDays: "30"
  • resources は serverless が使用する CloudFormationリソースを上書きする設定
  • 特定の function のロググループは、#{function名をアッパーケースにした文字列}LogGroup で定義される
    • このとき -Dash に、_Underscore に変換されるので注意
  • PropertiesRetentionInDays を設定すれば、有効期限が設定される
    • デフォルトでは有効期限なし

参考

公式の解説

https://github.com/serverless/serverless/blob/master/docs/providers/aws/guide/resources.md#override-aws-cloudformation-resource

lambdaプロキシ統合を使って、API Gatewayからlambdaへ各種パラメータを渡す方法

lambdaプロキシ統合って?

API Gatewayが受け取ったパラメータやリクエストヘッダなどの情報をlambdaのevent引数にわたすようにする方法

Lambda プロキシ統合では、クライアントが API リクエストを送信すると、API Gateway は、統合された Lambda 関数に raw リクエストをそのまま渡します。ただし、リクエストパラメータの順序は保持されません。このリクエストデータには、リクエストヘッダー、クエリ文字列パラメータ、URL パス変数、ペイロード、および API 設定データが含まれます。設定データには、現在のデプロイステージ名、ステージ変数、ユーザー ID、または承認コンテキスト (存在する場合) を含めることができます。

API Gateway の Lambda プロキシ統合をセットアップする - Amazon API Gateway

どうやって設定するの?

API Gateway作成時に「lambdaプロキシ統合」をonにする

f:id:kasei_san:20200214103917p:plain

lambdaプロキシ統合した時のevent引数の中身

API Gatewayで、 /create?branch_name=aaa&commit_hash=bbb というPATHを叩いた場合のevent引数の中身

{
  "resource": "/create",
  "path": "/create",
  "httpMethod": "GET",
  "headers": null,
  "multiValueHeaders": null,
  "queryStringParameters": {
    "branch_name": "aaa",
    "commit_hash": "bbb"
  },
  "multiValueQueryStringParameters": {
    "branch_name": [
      "aaa"
    ],
    "commit_hash": [
      "bbb"
    ]
  },
  "pathParameters": null,
  "stageVariables": null,
  "requestContext": {
    "resourceId": "*****",
    "resourcePath": "/create",
    "httpMethod": "GET",
    "extendedRequestId": "*****",
    "requestTime": "29/Jan/2020:08:28:51 +0000",
    "path": "/create",
    "accountId": "*****",
    "protocol": "HTTP/1.1",
    "stage": "test-invoke-stage",
    "domainPrefix": "testPrefix",
    "requestTimeEpoch": 1580286531393,
    "requestId": "*****",
    "identity": {
      "cognitoIdentityPoolId": null,
      "cognitoIdentityId": null,
      "apiKey": "test-invoke-api-key",
      "principalOrgId": null,
      "cognitoAuthenticationType": null,
      "userArn": "arn:aws:iam::*****:*****",
      "apiKeyId": "*****",
      "userAgent": "aws-internal/3 aws-sdk-java/1.11.690 Linux/4.9.184-0.1.ac.235.83.329.metal1.x86_64 OpenJDK_64-Bit_Server_VM/25.232-b09 java/1.8.0_232 vendor/Oracle_Corporation",
      "accountId": "*****",
      "caller": "*****",
      "sourceIp": "*****",
      "accessKey": "*****",
      "cognitoAuthenticationProvider": null,
      "user": "*****"
    },
    "domainName": "testPrefix.testDomainName",
    "apiId": "*****"
  },
  "body": null,
  "isBase64Encoded": false
}

クエリパラメータを取りたい場合

event['queryStringParameters']event['multiValueQueryStringParameters'] から取る

POSTされたデータを取りたい場合

event['body'] から取る。テキストデータで来るので、parseする必要があるので注意

AWS CodeBuild の buildspec.yml のコマンドで curl の完了前に処理が終了する件とその対策

buildspec.yml(一部)

post_buildcurl を実行後にその戻り値をチェックする command を実行する

実際のコードでは、API Gatewayを叩いていた

version: 0.2

phases:
  post_build:
    commands:
      - curl https://example.com
      - echo $?

実行結果

すると、 curl が完了する前に、次のコマンドが実行され、最終的に curl が完了する前に post_build が完了してしまう

[Container] 2020/02/04 01:51:29 Running command curl https://example.com

[Container] 2020/02/04 01:51:29 Running command echo $?
0

[Container] 2020/02/04 01:51:29 Phase complete: POST_BUILD State: SUCCEEDED
[Container] 2020/02/04 01:51:29 Phase context status code:  Message: 
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed

  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0curl: (6) Could not resolve host: example.com

原因

不明

対策

curlを使わないようにした

version: 0.2

phases:
  install:
    runtime-versions:
      ruby: 2.6

  post_build:
    commands:
      - ruby ./kick_api.rb
      - echo echo $?

kick_api.rb

require 'net/https'
require 'uri'

uri = URI.parse('https://example.com')
puts "Kick API: #{uri.to_s}"

res = Net::HTTP.get_response(uri)

puts "Responce code: #{res.code}"
puts "Responce body: #{res.body}"
res.value # 200以外なら例外を返す

node.jsのリリースサイクルについてメモ

まとめ

  • 6ヶ月に1度メジャーバージョンがリリースされる
  • 6ヶ月後に、奇数バージョンは放棄される
  • 偶数バージョンはLTS(Long Term Support)。通常、重大なバグが30ヶ月間は修正される  
  • 大企業や複雑なシステムはLTSを使うことを推奨
  • 最新機能を使いたい場合、最新版を使う

リリースサイクルのステータス

  • リリースサイクルのステータスは、CURRENT(最新)、ACTIVE(有効)、MAINTENANCE(保守) の3つ
  • CURRENT〜ACTIVEの間は更新され続け、MAINTENANCEの間は重大なバグは修正されつづける
  • リリース〜6ヶ月後: CURRENT
  • 6〜18ヶ月後: ACTIVE
  • 18〜30ヶ月後: MAINTENANCE

f:id:kasei_san:20200210101759p:plain
https://nodejs.org/ja/about/releases/

各バージョンのEOL

2020/02/10 現在

  • Node.js 10 〜 2021-04-30
  • Node.js 12 〜 2022-04-30
  • Node.js 13 〜 2020-06-01

参考

公式のリリースサイクルの説明

nodejs.org

curlは-fオプションをつけないとサーバエラーでも戻り値は0になる

サーバエラーが帰ってきても、curlの戻り値は0

$ curl -Is http://ozuma.sakura.ne.jp/httpstatus/500

HTTP/1.1 500 Internal Server Error
Server: nginx
Date: Tue, 04 Feb 2020 00:51:35 GMT
Content-Type: text/html; charset=utf-8
Connection: keep-alive
$ echo $?                                          
0

ozuma.sakura.ne.jp/httpstatus は任意のステータスコードを返してくれるサービス

ozuma.hatenablog.jp

ステータスコード200以外の時に、戻り値を0以外にしたい場合は、 -f オプションをつける

man curlより

-f, --fail
(HTTP) Fail silently (no output at all) on server errors. This is mostly done to better enable scripts etc to better deal with failed attempts. In normal cases when an HTTP server fails to  deliver  a document, it returns an HTML document stating so (which often also describes why and more). This flag will prevent curl from outputting that and return error 22.

This method is not fail-safe and there are occasions where non-successful response codes will slip through, especially when authentication is involved (response codes 401 and 407).
  • -f オプションをつけると、サーバエラーの場合戻り値は 22 にになり、標準出力になにも返さなくなる
  • ただし、 401や407のような認証系のエラーの場合、うまく動作しない場合がある とのこと

試してみる

$ curl -fs http://ozuma.sakura.ne.jp/httpstatus/500
$ echo $?                                          
22

そのとおりになった

dockerfileのARGの使い方おぼえがき

ARGとは

build実行時にオプション --build-arg として渡せる可変の値

使いみち

環境毎になにかを変える時に使用する

  • ビルド時に使用する環境変数
  • entrypoint.sh
  • COPY元

など

Dockerfileでの定義方法

ARG hoge="fuga"

解説

上記は、変数 hoge を時環境変数 HOGE に定義している

  • ARG 変数名 で変数を定義する。ここで定義しない変数は使用できない
  • ARG 変数名=デフォルト値 でデフォルト値も定義可能

変数展開方法

ENV HOGE=$hoge

$変数名 で変数展開される

build実行時に ARG に値を渡す方法

$ docker build . --build-arg hoge=fuga

docker-compose.yml に build-arg を定義する方法

buildargs に定義する

  app:
    build:
      args:
        hoge: fuga

そんなかんじ