4ヶ月かかりました。
手動デプロイの CakePHP2.0 を Laravel, GitHub Actions, ECS, CloudFormation に切り替えました。
ほとんど触ってないプロダクトだったので、テスト書きつつ、仕様書かきつつ...なんとか終わって嬉しいです。
この記事では、感想や困ったこと、主に感想を書きます。
感想も要約すると「さいこうー!」と言ってるだけです。ご了承ください。
感想: CakePHP → Laravel 気持ちいい
最高です。とにかく気持ちいいです。CakePHP2.0 の配列地獄から抜け出して、プロパティへのアクセスが嬉しいです。
物量があるので、がんばって全部書き直しました。
テストコードがないので、リファクタリングはほどほどにやりながら進めました。
CakePHP → Rails のときより、PHP コードが使い回しできるので楽でした。
感想: GitHub Actions 気持ちいい
CircleCI か GitHub Actions が候補でした。
社内(同事業部)で5つのサービスを運用しているのですが、他4つは全部 CircleCI です。
でも最近の GitHub Actions の盛り上がりを見て、試したくて仕方ありませんでした。
結論、最高です。
Pull request の隣に鎮座している Actions が最高です。いちいちサービスを跨がなくてよいのが本当に気持ちいいです。
yaml は
- deploy-production.yml
- deploy-staging.yml
- lint.yml
- test.yml
といくつか作りました。
ECS をデプロイする際に、https://github.com/aws-actions がありますから、ここの actions を
使えば自分では何も考えずに済む点が良いです。(後述する、migration は少し詰まりました。)
感想: CloudFormation の導入
社内では、まだインフラのコード化は進んでいません。ですが、すでに5つのサービスを運用していて、それぞれ似たようなインフラ構成ですので、コード管理して整備しておきたかったです。
CloudFormation か Terraform で迷うところですが。個人的に Terraform 使ったことないのと、CTO が CloudFormation でいいよと適当に呟いたのと、AWS リソースしか使わないので、という理由で選びました。
AWS CDK も良いという声があり、それも迷いましたが、そこは段階的に行くとして、まずは CloudFormation 導入に至りました。
結論、最高です。
これで、リソースの名前づけや、変更など綺麗にやっていけそうです。
感想: ECS にした
EKS か ECS で悩んだのですが、やっぱり簡単なので ECS にしました。社内には EKS も1つあるのですが、ECS に統一することにしました。
これで本番がコンテナ化できたので、デプロイスクリプトとさよならできて嬉しいです。ローカルも本番も docker 化することができで差分がなくなったことも嬉しい。
困ったこと: GitHub Actions のプルリクが動かない
プルリクを出したら lint や test を回すということがしたいのですが、最初それが出来ませんでした。なぜかというと、僕らの開発フローが fork したリポジトリからプルリクを出すスタイルだからです。
private リポジトリの場合、fork したリポジトリから出す pull_request ではワークフローが動きません。
なので、fork をやめました。 本体に commit して プルリクを作るスタイルに変えました。いまのところ、これで困っていません。
困ったこと: DB Migration をどうしたか
発想的には、one shot task でやるということでシンプルなのですが、GitHub Actions でどうやるんだ?というのに少しつまりました。
結論としては aws-actions/amazon-ecs-deploy-task-definition@v1 でタスク定義を更新して、 ecs run-task
するという以下のようなイメージです。
# migration タスク定義の登録
- name: Register migration task def
id: register-migration-task-def
uses: aws-actions/amazon-ecs-deploy-task-definition@v1
with:
task-definition: ${{ steps.task-def.outputs.task-definition }}
cluster: sample
# migration タスク実行
- name: migrate
run: aws ecs run-task
--launch-type FARGATE --cluster sample
--task-definition ${{ steps.register-migration-task-def.outputs.task-definition-arn }}
CloudFormation でまだよく掴めていないこと
今回初めて触りましたので、
どこまで、CloudFormation でやるのか?ということについて、答えは見えていません。
VPC、サブネット、ALB、セキュリティグループなどは、CloudFormation で作っていますが、DB インスタンス、ECS サービス、踏み台サーバインスタンスなどは、手動です。時間と体力がなく、今はこのような状態です。どこまで CloudFormation でやるのかは、今後の課題として模索していきたいと思います。
今後対応していきたいこと
まず、Log です。いまは nginx も app からなんの加工もせずに CloudWatch に流していますが、見れたものではありません。json 形式にするとか FireLens とかやっていきたいとおもいます。
つづいて踏み台サーバです。そもそも VPN でやるとか、他にもいろいろ踏み台サーバをなくす方法があると思うのですが、この辺も考えて行きたいと思います。が、BI ツールの DOMO が DB に繋げないといけなかったりして、障壁はいろいろありそうです。
そして、AWS CDK。これは、追い追いでいいかなと思っています。良い良いという声は聞こえてくるので、CloudFormation に馴染んだら検討したいと思いました。
リリース作業で改めて感謝したツール
もうこれがないと、やってられないと思うほど、泣くほど嬉しいツールです。案の定、リリース作業直後バグは発生しました。でも SENTRY のおかげで、エラー監視ができすぐに対処できました。本当にありがたいツールです。
おわりに
今回の構成にしてみて、アプリケーションエンジニアにとって、デプロイやインフラの見通しがよくなったと思いました。今後もどんどん開発体験は良くなっていくんだろうなぁ。すごい。
CloudFormation のサンプルコードを置いておきます。誰かのお役に立てば幸いです。
github.com/mochizukikotaro/cloudformation-sample
ありがとうございました。