ISUCON11予選を4位で通過しました

今年もやってきました ISUCON の季節です。

ISUCON は 8 までは(出題を含めて)予選本選の全てに参加できていたのですが、9, 10 では連続で予選落ちしていました。10は予選であと1チーム上回れば、というところで及ばずでしたが、本選には並行参加チームというオープン参加扱いで参加させてもらい、ひっそり全体の3位相当のスコアを出していたんですよね。なのでチームのポテンシャルとしてはまだまだいけるはず!ということで ISUCON 11 にも10と同様、同僚の @acidlemon と @mackee_w (macopy) と参戦しました。

結果、全体の4位のスコアで予選を通過できました!

isucon.net

やったこととか

使用したのは Go 実装です。ミドルウェアは特に変更せず、最後まで nginx + MariaDB のままでした。 3台のうち1台を MySQL(MariaDB)専用、残りの2台を nginx + アプリケーションにしています。

コードの変更については、リポジトリを公開しています。

github.com

最終的に取りこまれた PR のタイトルとスコア、時刻をざっと並べるとこんな感じでした。

  • isu_conditionのorder by狙い #1 by mackee
    • 最初に slowlow をみて index を貼ったやつ。これで初期スコアから 16,168 へ (11:10:12)
  • いつものinterpolateParams=true #2 by acidlemon
    • Go の MySQL ドライバでデフォルトだと server side prepeare をするのをやめるやつ。17,918
  • debugのログをoffにする #3 by mackee
  • generateIsuGraphResponseが全部取るのは意味がないので1日の範囲だけにする #4 by mackee
  • trendは最新だけだからLIMIT 1 #6 by acidlemon
    • このあたりでスコア 30,000 程度 (まだ1台) (12:27:17)
  • isu_character_idx 追加 #7 by fujiwara
  • ログレベルをINFOにしてアクセスログも黙らせる #8 by mackee
  • 9割落としてるのはわかったので静かにしてもらう #9 by acidlemon
  • 9割おじさんから8割おじさんへ #10 by acidlemon
    • dropProbability という数値の調整でスコアの傾向を探っています
    • ここで3台構成にして 39,704 までアップ (13:00:43)
  • 9割に戻しつつpostIsuをbulk insert #11 by mackee
    • 48,346 (13:04:11)
  • initializeでalter #16 by acidlemon
  • image はファイルに書く#17 by fujiwara
    • isu.image カラムに入っていた画像バイナリをファイルで読み書きするよう改修
  • condition_true_countカラムに対応するstruct定義にする #18 by acidlemon
    • 1カラムに文字列で入っていたフラグを分解して true の数を別に持つ改修
  • true_countで絞り込み #19 by mackee
  • userテーブルへのfetchをキャッシュする #23 by mackee
    • オンメモリ化を進めている 73,570 (15:31:31)
  • 全量さばけるようになったので全部コメントアウト!#24 by mackee
    • ここで dropProbability=0 で通るようになったのでスコアが跳ね上がりました。一気に桁が上がって 374,366 (15:41:40)
  • isu nameをオンメモリ #26 by fujiwara
  • isuの画像をNULLで潰す #28 by acidlemon
  • isuを引いてくるところでcacheする #29 by mackee
    • このあたりで並行して Redis branch を作っていました(by acidlemon)がスコアが出ず、取り込みは諦め
  • インデックス1個にまとめて書き込み負荷を下げる #30 by mackee
    • 最後、isu_condition の primary key を変更して復号 pkey にしたのが効果を発揮して 684,959 (18:31:27)
    • id bigint AUTO_INCREMENTid bigint DEFAULT NULL (カラム自体は使わないけど残す)
    • PRIMARY KEY(jia_isu_uuid, timestamp)

再起動試験後、18:38:02 に 704,779 を記録して打ち止めでした。

f:id:sfujiwara:20210823173306p:plain
スコア推移(最終上位4チーム)

感想とお礼

出題はなるほど IoT で時系列データ(今までなかったのでそろそろ来そうだとは思った)、極端なところがなくて、いい問題でしたね。最終的には isu_condition の書き込みをどう捌くかに帰着するので、ここを上手く圧縮できたらもっとブレイクスルーできたのかな…と思います。時系列DBを使ったチームとかあったんでしょうか。

ベンチは大変快適で、例年ありがちな謎 fail に悩まされることがほぼなかったので、競技に集中できてとてもありがたかったです。近年、めきめきと ISUCON 運営力の向上を感じますね。頼もしい限りです。

運営の皆様、大変良い問題をありがとうございました。3大会ぶりの本選参加なので、本選でも楽しみたいと思います。よろしくおねがいします!

ecspresso v1.6.0 をリリースしました

このブログはすっかり ecspresso のリリースノートとなっている昨今ですが、今回もリリースのお知らせです。

Amazon ECS デプロイツール ecspresso の v1.6.0 をリリースしました。

github.com

非互換変更

これまで GitHub で配布しているリリースバイナリのパッケージが .zip 形式でしたが、リリースを GoReleaser で行うようにした関係で、tar.gz 形式に変更になっています。 (追記: GoReleaserでもzipにはできるのですが、パッケージ内部のファイル名を揃えることが難しかったため、どのみちインストーラーなどの対応が必要になるためtar.gzに変更しました)

手動でインストールしている場合は、zip ではなく tar で展開してください。

CircleCI Orb の場合は、 fujiwara/ecspresso@0.0.15 を使用してください。それ以前のバージョンでは、latest や v1.6.0 以降のバージョンが正しくインストールできません。

GitHub Actions の場合は、kayac/ecspresso@v1 で latest, v1.6.0 以降もインストールできるようになっています。もしまだ @v0 を使用している場合は @v1 へ更新をお願いします。

Homebrew でのインストールは今まで通り行えます。

新機能

ECS サービスなしでのコマンド実行

ecspresso はこれまで、一見 ECS にサービスが存在しなくてもよさそうな操作でも、サービスが存在しないと行えない操作がありました。単体タスクの実行 (run)、タスクの一覧 (tasks)、ECS Exec (exec) の各コマンドは、ECS サービスが存在している状態でないと正常に動作しませんでした。

v1.6.0 ではこれらの機能を、ECS にサービスがなくても実行できるようになりました。

  • run については、実行時の networkConfiguration など、ECS サービス定義と同等の情報が必要なため、サービス定義ファイルが必要です
  • tasks, exec については、サービス定義も不要です。タスク定義の family が同一なものを ECS クラスタ内から検索して操作対象とします

tfstate 参照機能で Terraform Cloud, Terraform Enterprise をサポート

Terraform Cloud で管理している tfstate を参照できるようになりました。URL を指定する場合は remote://app.terraform.io/{myorg}/{myworkspace} という形式で指定してください。

認証情報は TFE_TOKEN 環境変数から読み取ります。

--config のデフォルト値として ecspresso.yml が設定されます

これまで ecspresso の設定ファイルを指定する --config オプションの値はデフォルト値が存在しませんでしたが、ecspresso.yml というデフォルト値が設定されました。

バグ修正

exec コマンドでログ出力を KMS 暗号化する設定の場合動作しないのを修正しました

session-manager-plugin の呼び出し方法の問題でした。

CodeDeploy アプリケーションが100個以上ある場合にデプロイできない問題を修正しました

APIで一度に100個しか取得できない関係で、失敗することがありました。世の中にはいっぱいアプリケーションがある環境があるんですね…

tfstate 参照のキーに - が入っていると panic する問題を修正しました

outputs を定義している場合、リソース名には - が含まれる可能性があります。

CodeDeploy で使用する AppSpec に CapacityProviderStrategy を追加しました

ドキュメントの英語の誤りが修正されました

英語がグダグダなのを直していただいて、ありがとうございます!

短い ARN 形式を利用している場合に ecspresso init が失敗する問題を修正しました


パッケージングが変更になった以外は基本的に互換性を保ったリリースとなっています。Pull Requestをお寄せいただいた皆様、ありがとうございました。

どうぞご利用ください。

ECS Execに対応した ecspresso v1.5.0 をリリースしました

Amazon ECS のデプロイツール、ecspresso の v1.5.0 をリリースしたのでお知らせです。

github.com

今回は Amazon ECS Exec という新機能対応が目玉です。ほかにもお送りいただいたPRを取りこんだ各種修正が入ったリリースになります。どうぞご利用ください。

PRをお送りいただいた皆様、ありがとうございました!

新機能

ECS Exec への対応を追加しました

ホストから docker exec するように、Fargate に対しても起動しているコンテナに入ってコマンドを実行できる ECS Exec 機能がリリースされています。

aws.amazon.com

ecspresso v1.5 では exec コマンドを追加して、AWS CLI なしで exec できるようにしました。session-manager-plugin は必要です。

exec を使用するためには、まずサービス定義で enableExecuteCommand を true に設定して create / deploy します。(起動中の ECS サービスに対してもあとから変更可能です)

{
  "enableExecuteCommand": true
}

必要な権限などが揃っているかどうかは amazon-ecs-exec-checker で確認すると便利です。

その後は ecspresso exec コマンドを使用して、起動中のタスクに対して exec ができます。タスクに複数コンテナがある場合は、更に選択肢がでます。

実際に実行してみた様子は以下をご覧ください。

この例ではタスクやコンテナの絞り込みに peco を使っていますが、絞り込みに使うコマンドは設定ファイルの filter_command で指定可能です。未指定の場合は ID / コンテナ名入力するダイアログが表示されます。

タスクを一覧/詳細表示する tasks コマンドを追加

これまで ecspresso ではサービスとタスク定義の管理に主眼を置いていたため、起動済みのタスクの情報を見る手段がありませんでした。

ecspresso tasks を実行すると、サービスから起動されたタスクと、同じタスク定義を持ったタスク(単体で run されたものも含む) を表示します。

$ ecspresso --config config.yaml
|                ID                |   TASKDEFINITION   | INSTANCE |   LASTSTATUS   | DESIREDSTATUS |         CREATEDAT         |         GROUP         |  TYPE   |
+----------------------------------+--------------------+----------+----------------+---------------+---------------------------+-----------------------+---------+
| 28852184e15e48e0aad6b7549f92ed65 | ecspresso-test:274 |          | RUNNING        | RUNNING       | 2021-04-13T13:45:23+09:00 | service:nginx-local   | FARGATE |
| bed89f2e492e44cd82d75776ff2d8a7f | ecspresso-test:276 |          | RUNNING        | RUNNING       | 2021-04-13T13:48:04+09:00 | service:nginx-local   | FARGATE |
| fad8863654f945588273916a3a56bd95 | ecspresso-test:275 |          | DEPROVISIONING | STOPPED       | 2021-04-13T13:46:21+09:00 | family:ecspresso-test | FARGATE |

--find オプションを付けると exec 同様にタスクを絞り込んで、決定するとそのタスクの情報を JSON で出力もできます。

停止したタスクについても API で取得できる時点までは閲覧できるので、なぜか上手く起動できずに落ちてしまったタスクでも詳細を表示すれば、マネージメントコンソールを見に行かずに理由が分かります。

次の例では、"stoppedReason": "Essential container in task exited" などが読み取れます。

$ ecspresso --config config.yaml --id fad8863654f945588273916a3a56bd95 --output json
{
  "attachments": [ ... ],
  "availabilityZone": "ap-northeast-1c",
  "capacityProviderName": "FARGATE",
  "clusterArn": "arn:aws:ecs:ap-northeast-1:123456789012:cluster/ecspresso-test",
  "connectivity": "CONNECTED",
  "connectivityAt": 1618289185.693,
  "containers": [ ... ],
    {
      "containerArn": "arn:aws:ecs:ap-northeast-1:123456789012:container/ecspresso-test/fad8863654f945588273916a3a56bd95/8a04958b-4918-4a15-b6d4-6b40791c4fba",
      "cpu": "0",
      "exitCode": 137,
      "healthStatus": "UNKNOWN",
      "image": "debian:buster-slim",
      "lastStatus": "STOPPED",
      "managedAgents": [
        {
          "lastStatus": "STOPPED",
          "name": "ExecuteCommandAgent"
        }
      ],
      "name": "bash",
      "networkBindings": [],
      "networkInterfaces": [
        {
          "attachmentId": "bcb4aa98-1dfe-4a08-9a29-9db6e15d8334",
          "privateIpv4Address": "10.3.3.161"
        }
      ],
      "runtimeId": "fad8863654f945588273916a3a56bd95-987533343",
      "taskArn": "arn:aws:ecs:ap-northeast-1:123456789012:task/ecspresso-test/fad8863654f945588273916a3a56bd95"
    }
  ],
  "cpu": "256",
  "createdAt": 1618289181.026,
  "desiredStatus": "STOPPED",
  "enableExecuteCommand": true,
  "executionStoppedAt": 1618289229,
  "group": "family:ecspresso-test",
  "healthStatus": "UNKNOWN",
  "lastStatus": "STOPPED",
  "launchType": "FARGATE",
  "memory": "512",
  "overrides": {
    "containerOverrides": [
      {
        "command": [
          "nginx",
          "-V"
        ],
        "name": "nginx"
      },
      {
        "name": "bash"
      }
    ],
    "inferenceAcceleratorOverrides": []
  },
  "platformVersion": "1.4.0",
  "pullStartedAt": 1618289214.039,
  "pullStoppedAt": 1618289223.039,
  "startedAt": 1618289229.039,
  "stopCode": "EssentialContainerExited",
  "stoppedAt": 1618289345.672,
  "stoppedReason": "Essential container in task exited",
  "stoppingAt": 1618289280.886,
  "tags": [],
  "taskArn": "arn:aws:ecs:ap-northeast-1:123456789012:task/ecspresso-test/fad8863654f945588273916a3a56bd95",
  "taskDefinitionArn": "arn:aws:ecs:ap-northeast-1:123456789012:task-definition/ecspresso-test:275",
  "version": 6
}

rollback コマンドが CodeDeploy に対応

これまで ecspresso rollback は CodeDeploy でデプロイされた場合には機能しませんでしたが、機能するようになりました。 Feature Request: Rollback by CodeDeploy by cohalz · Pull Request #261 · kayac/ecspresso · GitHub

タスク定義へのタグ付けに対応

これまではタスク定義ファイルに tags を記述してもタグを付与することができませんでしたが、タグをつけられるようになりました。

これに伴って、タスク定義ファイルを取り扱うときに AWS SDK Go の ecs.TaskDefinition を使用していた部分が、ecs.RegisterTaskDefinitionInput を使用するように変わっています。JSON ファイルとして扱う場合には互換性を持たせていますが、もし何か問題がありましたらお知らせください。

{
  "tags": [
     {
        "key": "TagKey",
        "value": "TagValue"
     }
   ]
}

Feature Request: Support add Tags to TaskDefinition by Hirofumi-Narita · Pull Request #256 · kayac/ecspresso · GitHub

Support tagging for task definition. by fujiwara · Pull Request #260 · kayac/ecspresso · GitHub

バグ修正

init コマンド実行時に ECS サービスの propagateTags 属性を扱えるように

これまでは init コマンドで既存 ECS サービスを定義ファイル化した時点で propagateTags 属性が消えていましたが、保持するようになりました。

Support tags&propagateTags to `init` & `create` by cohalz · Pull Request #270 · kayac/ecspresso · GitHub

verify コマンド実行時に ELB の検証をタスク実行ロールではなく ecspresso の実行権限で行うように

これまでは verify コマンド実行時の ELB (target group) の検証を、タスク実行ロール(にAssumeRoleした状態)で行っていましたが、ecspresso 自体の実行権限で行うように変更しました。

タスク実行ロールには最小限の権限しか持たせない方が望ましい、という理由です。v1.5 の時点ではecspresso の実行権限での検証に失敗した場合、タスク実行ロールでの検証にフォールバックしますが、この挙動は移行措置として次のリリースで削除する予定です。

Don't require `elasticloadbalancing:DescribeTargetGroups` in task execution role to `verify` by cohalz · Pull Request #262 · kayac/ecspresso · GitHub

ecspresso handbook も改訂予定です

すみません、v1.4.0 リリース時に改訂予定としていましたが、まだ handbook は v1.3 対応のままです。v1.4, 1.5 での変更について加筆予定ですので、引き続きよろしく願いします。

zenn.dev

GitHub Sponsors はじめました

github.com

One-time のスポンサーもできるようになっていますので、よろしければこちらもご検討ください。

ecspresso v1.4.0 をリリースしました

Amazon ECS のデプロイツール、ecspresso の v1.4.0 をリリースしたのでお知らせです。

github.com

今回はそこまで大きな機能追加はないのですが、地味に嬉しい機能が入っております。どうぞご利用ください。

run コマンドに --overrides-file が追加

単体タスクを実行する run コマンドに、--overrides-file オプションが追加されました。

タスク実行時に上書きするコマンドや環境変数は、これまで --overrides オプションでJSON文字列として渡す必要がありましたが、これが結構複雑な構造をしているので組み立てが面倒でした。

{
    "containerOverrides": [
        {
            "name": "foo",
            "command": ["my-command"]
        }
    ]
}

こんな構造なので、CLI で渡すのはだいぶ煩雑です。ということで、あらかじめファイルとして JSON を記述しておいて、それを --overrides-file で指定することができるようになりました。また、このファイルは他の ecspresso の定義ファイルと同様、テンプレートとして解釈されます。

{
    "containerOverrides": [
        {
            "name": "foo",
            "command": ["{{ must_env `COMMAND` | json_escape }}"]
        }
    ]
}

このように環境変数COMMAND という値を展開するように定義しておけば、コマンドだけを変更したい場合に以下のように実行できます。便利!

$ COMMAND="echo hoge" ecspresso run --overrides-file overrides.json ...

verify コマンドに --no-get-secrets オプションが追加

ecspresso verify でのタスク定義の検証時に、これまでは secrets の値が SSM パラメータストアや SecretsManager に存在して読み取れる必要がありました。権限的に読み取れない場合は verify が失敗してしまいますが、値によっては verify を行う環境からは読ませたくない、という要望がありました。

--no-get-secrets オプションを指定すると、secrets が読み取れるかどうかの検証をskipします。

--envfile オプションが追加

ecspresso の各種定義ファイルでは環境変数を展開できる機能があり、動作のカスタマイズには欠かせない機能です。

しかし、複数の環境に対するデプロイを1つの定義ファイルで行う場合には ecspresso 実行環境変数を定義し直す必要があります。これはちょっと面倒な場合があるため、あらかじめ環境変数を定義した envfile を指定できるようにしました。

指定できるファイルは一般的な .env 形式で、export は付いていてもいなくても同様に動作します。

export FOO=foo
BAR=bar

envfile のパースには hashicorp/go-envparse を使用しています。hashicorp のライブラリ、いつもながら渋いけど便利ですね。

github.com

init コマンドに --force-overwrite オプションが追加

指定すると、init コマンドでの定義ファイル出力時に、既にファイルが存在していても確認なしで上書きします。

ecspresso の構成管理ファイルをバックアップ目的でリポジトリ管理していて、それを自動化する場合には確認なしで上書きしたいことはありますね。

テンプレート関数に tfstatef が追加

Terraform state file をテンプレートから参照する機能で tfstate 関数がありますが、tfstatef という関数が追加されました。これは要するに print に対する printf です。resource.name["foo"].id のような参照を行う場合に、部分的に文字列を変数から組み立てたい場合に便利です。

例えば環境変数 AZ を使用して aws_subnet.public['$AZ'].id というリソース名を tfstate から参照したい場合、従来は printf で組み立てた文字列を tfstate 関数で渡す、という若干のテンプレート芸が必要でした。

{{ printf `aws_subnet.public['%s'].id` (must_env `AZ`) | tfstate }}

これが、以下のように分かりやすく記述できます。

{{ tfstatef `aws_subnet.public['%s'].id` (must_env `AZ`) }}

verify 時にタスク実行ロールに assume できない場合の警告を warning から info に変更

verify コマンド実行時、ecspresso はタスク実行ロールに assume role を試みて、成功したらタスク実行ロールで、失敗したら現在の権限で検証を行います。

タスク実行ロールに assume することでより確実な検証が行えるのですが、assume role できる設定をわざわざ行わない場合は毎回以下のような警告が(黄文字で)出力されてしまいます。

WARNING: failed to assume role to taskExecutuionRole.

実際にはこれは害があるとまでは言い切れない警告だったため、ログレベルを INFO に変更しました。

作者の周囲でも、この警告が出ていてもほとんど全員が無視するという結果が観測されたため、WARNING を無視させる習慣を付けてしまうのは望ましくない、という理由もあります。

リリースバイナリを Go 1.16 でビルド

Go 1.15 から Go 1.16 に変更しました。今回から、M1 macdarwin むけ arm64 バイナリも同時にビルドしています。


ecspresso handbook も改訂予定です

zenn.dev

v1.4.0 で追加、変更された機能については、ecspresso handbook でも順次改訂予定です。

ecspresso で CloudFormation のリソース読み込みに対応 + その他機能追加した v1.3.0 をリリースしました

あけましておめでとうございます。Amazon ECS デプロイツール ecspresso の v1.3.0 をリリースしたのでお知らせです。

[2021-01-16 追記] v1.3.0 は init コマンドでクラッシュする問題があります。v1.3.1 をご利用ください。

今回は機能追加が盛り盛りなので、まとめて紹介します。

Release v1.3.0 · kayac/ecspresso · GitHub

【新機能】 cloudformation プラグインを追加

これまで ecspresso は Terraform tfstate を読み込んでそのリソース名から属性値を解決できる機能を持っていましたが、CloudFormation でも同様の処理ができるようになりました。

README に例がありますが、次のように Output と Export を定義したテンプレートで構築された、Stack 名が ECS-ecspresso という CloudFormation stack がある場合に

Outputs:
  SubnetAz1:
    Value: !Ref PublicSubnetAz1
  SubnetAz2:
    Value: !Ref PublicSubnetAz2
  EcsSecurityGroupId:
    Value: !Ref EcsSecurityGroup
    Export:
      Name: !Sub ${AWS::StackName}-EcsSecurityGroupId

ecspresso の設定ファイルで cloudformation plugin を指定すると

plugins:
  - name: cloudformation

定義ファイルで cfn_outputcfn_export という関数が使用可能になります。cfn_output スタック名 OutputKey で Outputs の値を名前で解決できます。cfn_export エクスポート名 で、エクスポートされた値を名前で解決できます。

サービス定義での使用例は次のようになります。

{
  "networkConfiguration": {
    "awsvpcConfiguration": {
      "subnets": [
        "{{ cfn_output `ECS-ecspresso` `SubnetAz1` }}",
        "{{ cfn_output `ECS-ecspresso` `SubnetAz2` }}"
      ],
      "securityGroups": [
        "{{ cfn_export `ECS-ecspresso-EcsSecurityGroupId` }}"
      ]
    }
  }
}

ご意見をくださった @torics さん、@hamako9999 さん、@_sisisin さん、ありがとうございました!

【新機能】scale コマンドを追加

これまでサービスのタスク数を変更するためには deploy --no-update-service --skip-task-definition --tasks タスク数 を指定していましたが、これをショートカットにした scale コマンドを追加しました。

$ ecspresso --config config.yaml scale --tasks 10

これで ecspresso --config config.yaml deploy --no-update-service --skip-task-definition --tasks 10 とおなじ意味になります。

タスク数だけを変えたい場合でも指定するオプションが多いため、うっかりサービスやタスクを更新してしまう事例がありました。scale コマンドを使用すると必要なのは --tasks のみ(必須) になるため、事故を防げます。

【新機能】tfstate plugin が URL を直接読み込めるようになりました

これまで tfstate plugin はローカルファイルの読み込みのみが可能でしたが、直接 s3, http(s) URL からも読み込めるようになりました。デプロイする環境に terraform.tfstate が存在していない場合、これまではわざわざ aws s3 cp などでローカルにコピーする必要がありました。

plugins:
  - name: tfstate
    config:
      url: s3://my-bucket/terraform.tfstate

tfstate-lookup コマンドも v0.1.0 で URL からの tfstate 読み込みをサポートしています。 https://github.com/fujiwara/tfstate-lookup/releases/tag/v0.1.0

【新機能】設定ファイルで required_version が使用可能に

特定のバージョン以降で追加された機能を要求する場合など、ecspresso のバージョンに制約を持たせたい場合に設定ファイルで使用できる機能です。

required_version: ">= v1.3.0, < v2"

このように semver で指定することで、条件を満たしていないバージョンの ecspresso で実行しようとするとエラーになります。hashicorp/go-version を使用しています。

この機能をサポートしていない v1.3.0 未満のバージョンでは無視されるため、v1.3.0 がリリースされた時点では指定する意味はありません。将来新しいバージョンがリリースされ、その時点で入った機能や修正に依存した処理があるためそれ未満のバージョンでは実行させたくないような場合に役に立つ予定です。

PR を送ってくださった mashiike さん (同僚) ありがとうございました!

【新機能】run コマンドでタスクにタグが付けられるように

ecspresso run --tags Foo=Bar で、実行するタスクに Foo という名前のタグが Bar という値で設定されます (複数指定可能)。

ecspresso run --propagate-tags=(SERVICE|TASK_DEFINITION) で、実行するタスクに付けるタグをサービス定義もしくはタスク定義から引き継ぐことができます。

実は現状では、ecspresso でタスク定義を登録する際にはタグを附与することができません。これは定義ファイルを SDKecs.TaskDefinitionマッピングしていて、この構造体にはタグの定義がないためです。(サポート方法を悩みつつ、具体的な需要が今のところないので何もしていません)

その他修正いろいろ

  • [Fix] Unable to update platformVersion and networkConfiguration for CodeDeploy services. #209
    • CodeDeploy でデプロイする際に、--update-service を付けていても platformVersion と networkConfiguration が変更できなかった問題を修正しています。
  • [Fix] diff command becomes to compare local task definition and remote task definition. #218
    • diff コマンドが比較するタスク定義のリモート(ECS)側が、これまで latest (一番リビジョンが大きい) のものになっていましたが、サービスが現在使用しているリビジョンのものと比較するようになりました。
  • [Fix] Support to Docker Registry V2 API. Enables to read any public image repository using V2 API. (public.ecr.aws, gcr.io, ghcr.io and etc.) #214 #213
    • ECR Public repo など、一般の公開 image を verify できなかった問題を修正しています。Docker Registry API V2 を利用している任意の公開リポジトリの image が存在検証できます。
    • この修正に伴って、verify に 必要な IAM 権限から ecr:ListImages が不要になりました。

ecspresso handbook も改訂予定

昨年末に公開した ecspresso handbook ですが、こちらも v1.3.0 の新機能へ追従して近日改訂予定です。ご購入の方はそのままお読みいただけます。まだの方は是非この機会にお求めください。

zenn.dev

ecspresso handbookをZennで公開しました

激動の2020年もいよいよ押し詰まってきましたが、皆様いかがお過ごしでしょうか。

今年は ecspresso advent calendar 2020 というひとりアドベントカレンダーを唐突に思いついて始めてしまったのですが、なんとか完走することができました。

拙作の OSS である Amazon ECS 用のデプロイツール ecspresso の基本的な使い方から応用編、コマンドリファレンス、設計思想までを一通り書ききることができたので、せっかくなので Zenn で本としてまとめることにしました。

zenn.dev

9万字弱とそこそこのボリュームになり、書くのも大変だったしなあということで、500円の有料本としています。

内容自体はアドベントカレンダーに書いたものを再編集(章立ての変更と校正など)したものなので、特に新しい情報が入っているわけではないですが、もしよろしかったらお買い求め頂けると大変ありがたいです。売れると開発にもやる気が出ます(重要)。冬休みのお供にいかがでしょうか!

ecspresso の今後ですが、CloudFormation との連携 (OutputとExportの論理名を指定して物理名を解決できる) の実装の目処が付いたので、年明けぐらいにリリースできるといいなと思っております。

それでは、皆様良いお年を (よろしければ ecspresso handbook と一緒に) お迎えください。

Amazon Lightsail Container を Mackerel で監視する

Mackerel Advent Calendar 2020 8日目の参加記事です。

2020年11月に、Amazon Lightsail Container というサービスがリリースされました。

dev.classmethod.jp

最低月額 $7 で、コンテナを気軽に(ロードバランサー込みで!) Amazon Lightsail 上にデプロイできるというものです。普通に AWS で Fargate のコンテナとロードバランサー(ALB)を動かすと最低でも$25/月程度はかかってしまうので、これはお手軽でよさそうですよね。

ということで、この Lightsail Container を Mackerel で監視してみましょう。

Lightsail Container の実体は?

なにはともあれ、Ligtsail Container に環境変数を出力する Web アプリケーションをデプロイして素性を探ってみます。環境変数JSON で出力する HTTP サーバを起動してくれる便利な phamviet/printenv という Public Image があるので、これを適当に Lightsail Container にデプロイしてアクセスしてみると、以下のようなレスポンスが得られました。

{
  "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI": "/v2/credentials/03aed4fb-11f7-4c84-967a-34389ff48412",
  "AWS_DEFAULT_REGION": "ap-northeast-1",
  "AWS_EXECUTION_ENV": "AWS_ECS_FARGATE",
  "AWS_REGION": "ap-northeast-1",
  "ECS_CONTAINER_METADATA_URI": "http://169.254.170.2/v3/3715f73c-a351-4df9-a923-02163d4df095",
  "ECS_CONTAINER_METADATA_URI_V4": "http://169.254.170.2/v4/3715f73c-a351-4df9-a923-02163d4df095",
  "HOME": "/root",
  "HOSTNAME": "ip-172-26-26-31.ap-northeast-1.compute.internal",
  "NODE_VERSION": "10.16.3",
  "PATH": "/usr/src/app/node_modules/.bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
  "PWD": "/usr/src/app",
  "SHLVL": "1",
  "YARN_VERSION": "1.17.3"
}

"AWS_EXECUTION_ENV": "AWS_ECS_FARGATE" なるほどですね。

Lightsail Container = Fargate を簡単に使えるようにいい感じにしてくれているなにか、のようです(あくまで推測ですよ?)

ということは普通に mackerel-container-agent で ECS / Fargate を監視するのと同じ方法でいけそうですよね。サイドカーを追加してみましょう。

mackerel-container-agent のサイドカーを追加する

公式のドキュメントをもとに、以下のような設定でコンテナを追加しました Amazon ECSにmackerel-container-agentをセットアップする

f:id:sfujiwara:20201205022844p:plain

  • image: mackerel/mackerel-container-agent:v0.5.0
  • environment
    • MACKEREL_APIKEY: *************
    • MACKEREL_CONTAINER_PLATFORM: ecs

デプロイしてしばらく待ってみると…

f:id:sfujiwara:20201205022918p:plain

普通に Fargate task として認識され、同様のメトリックが得られました。よかったですね。

[PR] デプロイツール sailtrim 開発中

現在、fujiwara/sailtrim という、Lightsail Container 用のデプロイツールを開発しています。

まだまだ荒削りですが、ECSのデプロイツール ecspresso や Lambda のデプロイツール lambroll と同じような使い勝手で Lightsail Container をコード管理してデプロイできるツールです。よろしくどうぞ。