GitHub ActionsでECSのタスク定義のみを更新する
GitHub ActionsでECSサービスをデプロイするときによく使われる aws-actions/amazon-ecs-deploy-task-definition ですが、 タスク定義のみを更新することもできます。READMEのサンプルコードにはその例がないので、気づきにくいです。
inputs: task-definition: description: 'The path to the ECS task definition file to register' required: true service: description: 'The name of the ECS service to deploy to. The action will only register the task definition if no service is given.' required: false
inputsにtask-definitionだけ入力してあげるだけでOKです。
# 中略 - name: register new task definition family uses: aws-actions/amazon-ecs-deploy-task-definition@v1 with: task-definition: ${{ steps.render-container.outputs.task-definition }}
ECS Scheduled Taskでバッチ処理するタスク定義の更新などで活用できると思います。
参考
GitHub Actionsがdependabotで発火した場合のみ挙動を変えたい
DependabotのPRを元に発火するGitHub Actionsはread-onlyなGITHUB_TOKEN
のみを扱うことができるため、step内で
Secretsを参照している場合はfailしてしまいます。
【Github actions】DependabotのPull RequestでSecretsが参照できずワークフローがFailになった場合の対処 - Simple minds think alike
failしていると煩わしいので、dependabotで発火した場合はそもそもジョブを実行しないようにするか pull_request_target
、workflow_run
を使うようにすると良さそうです。
今回はdependabotで発火した場合は、ジョブを実行しないようにするワークフローを例として残しておきます。
name: example on: push: jobs: verify-actor: runs-on: ubuntu-latest outputs: actor: ${{ steps.echo.outputs.actor }} steps: - name: echo actor id: echo run: | echo "::set-output name=actor::${{ github.actor }}" trigger_deploy: runs-on: ubuntu-latest needs: [verify-actor] if: needs.verify-actor.outputs.actor != 'dependabot[bot]' steps: - uses: actions/checkout@v2 - name: something run: | echo "hey"
一つのジョブ内で条件分岐をしようとすると、全てのstepにifを入れないといけません。
そのため、最初に条件分岐をするためだけのジョブを作り、後続のジョブの if
で needs
の outputs
を参照することで
条件文の記述を1回にしています。
stepの出力を後続stepから参照する場合は、echo "::set-output name=key::value
形式で参照できるようにしておく必要がありますが、
jobの出力を後続jobから参照する場合は、jobのoutputs
と needs
を使う必要があります。(ややこしい)
参考
【Github actions】DependabotのPull RequestでSecretsが参照できずワークフローがFailになった場合の対処 - Simple minds think alike
ECSでunicornを動かすときの注意点
ECSはタスクが停止すると、各コンテナにまず SIGTERM
を送ります。
しかし、Railsと一緒によく使われるunicornは SIGTERM
を受け取ると、gracefulに終了してくれません。
graceful shutdownさせるためには QUITシグナルをmasterプロセスに対して送る必要があります。 Signal handling
デフォルトの停止シグナルは SIGTERM ですが、これは Dockerfile に STOPSIGNAL ディレクティブを追加することによってオーバーライドできます。この停止シグナルは、シャットダウンの命令をアプリケーションに通知します。
やり方としてはshell scriptのハンドラーを書いたり、STOPSIGNAL
ディレクティブをDockerfileに追加する方法もあると思いますが、今回の場合は
unicorn.rb
に Signal.trap
して自身のmasterプロセスに対してシグナルを送るのが一番簡単だと思います。
before_fork do |server, worker| Signal.trap 'TERM' do Process.kill 'QUIT', Process.pid end
参考
Nginx の limit_req
Nginxの流量制限する場合に使用される limit_req の使い方について調べてみました。 NGINX Rate Limiting の簡単なメモになります。
limit_req
Nginxのrate limitでは、パケット通信の帯域制限などで使われているleaky bucket algorithmに従ってキューイングします。
基本的な設定
http { limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s; ... server { ... location /search/ { limit_req zone=one burst=5; }
ひとつずつ設定を見ていきます。
まず、limit_req_zone
directive で httpリクエストに対する制限を定義できます。
ここではあくまでも定義しているだけなので、実際に実装する場合は location
ディレクティブ内などに設定を書く必要があります。
limit_req_zone
は key、zone、rateという3つのパラメーターを持ちます。
key
その右にある $binary_remote_addr
はクライアントのIPアドレスを表現するNginxの変数です。
zone
アクセス制限のかけたURLに対して頻繁にアクセスしてくるそれぞれのIPアドレスを記録するためのメモリについての設定です。 これはNginxのワーカープロセス間で共有されます。 目安として1メガバイトには約16,000のIPアドレスを記録することが可能です。 Nginxが新しいIPアドレスを記録する必要があるときにメモリが枯渇している場合は、最も古いIPアドレスを削除し、メモリを開放します。 それでもまだスペースが足りず不十分な場合は503を返します。 また、上記の枯渇問題を防ぐためにNginxは新しいIPアドレスを登録するたびに過去60秒間に使用されていない最大2つのエントリを削除します。
rate
最大のリクエストレートを設定します。 上記の例では、1秒あたり1リクエストを超えることができないことを表していますが、 実際にはNginxはミリ秒の粒度でリクエストを追跡するため100msごとに1つのリクエストに対応します。
burst
burst パラメーターをzoneで指定されたrateを超えてクライアントが実行できるリクエストの数を定義できます。 burstを超えたリクエストは全てキューイングされます。
例: 20スロットが空でリクエストが21個飛んできた場合は、1つをアップストリームに流す。 次に残りの20リクエストをキューイングし、100ミリ秒ごとにデキューする。
burst with nodelay
nodelay が設定された場合は空きスロットがない状態は503、 空きスロットがある場合はリクエストは処理され、スロットが使用済みになります。
例: 20スロットが空でリクエストが21個同時に飛んできた場合は、21リクエスト全て処理をし、20個のスロットを確保する。 その後、100ミリ秒ごとにデキューして消化。
まとめ
burstなし、burstあり、burstあり+nodelayの3パターンあります。
本番環境で使う場合は nodelay をつける場合が多そう。
参考
Goで自作パッケージを作るときのちょっとした動作確認
SongmuさんのGo Conference 2019 Summerでの発表資料に
パッケージ内の関数の動作確認とかは gore -pkg . が異常に便利です
と書いてあって、使ってみたら結構便利だったので備忘録として残しておきます。
-pkg string the package where the session will be run inside
合わせて読みたい
RFC違反のメールアドレス
日本の大手キャリアであるdocomo、auが2009年ごろまでに作成したメールアドレスはRFCに準拠していないものも作成可能でした。 今日はRFC違反のメールアドレスを考慮した正規表現とAmazon SES、SendGridの対応状況について調べてみました。
RFC違反のメールアドレスを考慮した正規表現
https://qiita.com/sakuro/items/1eaa307609ceaaf51123
HTML5の input[type=email]
と同じ正規表現をかけると良いです。
Amazon SES
検証結果を見る限り、RFC違反のメールアドレスでも送れるものと送れないものがあるみたいです。
SendGrid
2013年頃はRFC違反のメールアドレスでも一部送れるようだったが、2019年に仕様が代わり ローカルパートをダブルクォーテーションで囲まないといけないらしいです。
合わせて読みたい
git 備忘録
任意のコミットで変更されたファイルの一覧を出力する
通常のコミット: git diff-tree --no-commit-id --name-only -r <tree-ish>
マージコミット: git log -m -1 --name-only --pretty="format:" <commit-id>
mainブランチにマージ済みのブランチを削除する
git branch --merged main | grep -v '^\*' | xargs -n 1 git branch -d