remote containersの初期位置

デフォルトだと/workspacesなので、DockerfileのWORKDIRとズレてて「あれ?」ってなる場合が多いと思われるので注意

設定箇所は.devcontainer/devcontainer.jsonworkspaceFolder

 // The optional 'workspaceFolder' property is the path VS Code should open by default when
    // connected. This is typically a file mount in .devcontainer/docker-compose.yml
    "workspaceFolder": "/app/",

Cannot find name 'structuredClone'

@types/node@^17入れてteconfig.jsonいじったら直りました。

stackoverflow.com


その後lockファイル消してライブラリの再インストールなどしてたら上記の操作不要で動くようになってしまった。
2年前に作ったツールでの問題だったので、typescript入れた当時の@types/nodeが古かったっぽい

ポートフォリオ用サイトの維持費

ポートフォリオの維持費

ポートフォリオの一部として公開しているwebサービスがあります。

githubだけじゃなくて何か動くもの1個持っときたいよね程度のもので、ほぼ自分しか使わないにも関わらず約60USD/月かかってしまってるので何とか削れないか考えました。

React、ECS Fargate、MySQLの基本的なアプリケーションで、
ALB、Fargate、RDS、EC2(NATインスタンスとRDSアクセス兼用)などの起動時間に対して発生する課金が一月でおよそ60$弱になります。
ストレージや通信量に対する課金は無視できる程度です。

サーバレス化

サーバレス(lambda/DynamoDB)化については最初からこれにしとけよという感じですが、まずはポピュラーな実装方法でリリースまでを経験しておきたかったので採用しませんでした。
そして色々削ってもこれだけ維持費がかかるとは思ってませんでした。。

今からサーバレスに仕様変更するには大幅にコードを修正する必要があり、どちらかというと需要があると思われる現在の構成も捨てがたいので微妙な感じです。

インフラを都度落とす

幸いterraformでインフラ管理しているのと、一般ユーザーからのアクセスを見込んでないので定期的にアクセスログをチェックしてterraform destroy/applyを自動的に叩く方針で進めることにしました。

terraformのアクションはgithub上に用意済みで、これを叩くためのlambdaを作ろうということになります。
destroyのタイミングは簡単そうですが、落とした後はアクセスログが残せないのでapplyさせるタイミングがややこしくなりそうです。

API

applyは手動で行うこととして、フロントから実行できるようにしたいということでバックエンドインフラの起動停止を行うAPI作ることにしました。
現在のバックエンドサーバーとは別枠で作る必要があり、かつめちゃめちゃ小規模なためどうせならということでlambda+API Gatewayで作ることにします。

かなり余計な機能ですが、サーバレス方面にも手広げていくきっかけになればと思います。


(追記)

ALBをAPI Gatewayに置き換える

ALBをSSL終端にしか使っていないので、API Gatewayへの変更に支障なければする予定です。 APIGatewayからVPCに接続するためのVPC LinkにALBの6割程度ですが時間課金発生するようなので見送りました。

n時間以内にアクセスがあるかどうかの確認

当初はCloudwatch Logsから時間内のログあるか見ればいいでしょ程度に考えてました。

ユーザーだけでなくBOTのアクセスもロギングされてしまっているのと、そもそも見ようとしてたCloudwatch LogsがECSからの標準出力を保存してるだけでアクセスログでもなんでもなかったのでこの方法は意味がありませんでした。

またALBとCloudfrontのアクセスログは保存先がS3であり、S3を直接調べるのは日付順にファイルを取得できなかったり、ログを解凍する必要があったりで面倒なことがわかりました。
Athenaの出番かもしれませんが、おまけの機能に時間割いてもしょうがないのでCloudwatch Logsからの出力をフィルターしてなんとかお茶を濁してます。


コストの都合で現在localとprod環境しか作れてませんが、自動で落とせるようになったのでstaging環境を用意することができそうです。
prodに直リリースとか実際はあり得ないので、どうアクセス制限するのかしっかり身につけておきたいところです。

CloudfrontからAPI Gatewayに繋がらない(502)

こちらと全く同じ(cloudfront, APIGatewayを別ドメインSSL化している)状況で大変参考になりました。
oji-cloud.net

ビヘイビアのオリジンリクエストポリシーにAllViewerExceptHostHeaderというドンピシャのプリセットがあり、なんとなくで指定していたAllViewerから変更したところ通信できるようになりました。

同じdistributionでのCloudfrontからALB(からECS)への接続が既に上手くいってたので、その設定を流用すればOKだと思ってたんですが甘くないですね〜。

lambdaで/var/runtime/bootstrap no such file or directory

ただの凡ミスだったのですが数時間潰されたので、、、

docs.aws.amazon.com

古いイメージpublic.ecr.aws/lambda/go:1を使ったlambda用のDockerfileを新しいイメージpublic.ecr.aws/lambda/provided:al2用に書き換える際、
Dockerfileの実行コマンド部分がCMDからENTRYPOINTになってるのでご注意ください。。

CMD [ "main" ]
↓
ENTRYPOINT [ "./main" ]

エラーやコンテナの中を調べた結果、ドキュメント間違ってない?と思ってbuildした生成物を/var/runtime/bootstrapに直置きしたりしましたが、ドキュメント通りで全く問題ありませんでした。


(おまけ)

ECRに再プッシュした後はlambda側を更新してやる必要があります。

aws lambda update-function-code --function-name  {function_name} --image-uri {image_uri}