CakePHP2.0 を、Laravel, GitHub Actions, ECS, CloudFormation にしました

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 が最高です。いちいちサービスを跨がなくてよいのが本当に気持ちいいです。

<img width="1027" alt="スクリーンショット 2020-05-12 15.37.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45822/e8eb6efb-b97c-72dc-7f1d-82b58cdc8ef3.png">

yaml は

- deploy-production.yml
- deploy-staging.yml
- lint.yml
- test.yml

といくつか作りました。

ECS をデプロイする際に、https://github.com/aws-actions がありますから、ここの actions を
使えば自分では何も考えずに済む点が良いです。（後述する、migration は少し詰まりました。）

# 感想: CloudFormation の導入

![81834982-aaaa6b00-957c-11ea-8d08-3a82cbcfde9c.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45822/37fb959c-cb08-e074-1fb3-9a87ed1d8d64.png)


社内では、まだインフラのコード化は進んでいません。ですが、すでに5つのサービスを運用していて、それぞれ似たようなインフラ構成ですので、コード管理して整備しておきたかったです。
CloudFormation か Terraform で迷うところですが。個人的に Terraform 使ったことないのと、CTO が CloudFormation でいいよと適当に呟いたのと、AWS リソースしか使わないので、という理由で選びました。

AWS CDK も良いという声があり、それも迷いましたが、そこは段階的に行くとして、まずは CloudFormation 導入に至りました。

結論、最高です。

これで、リソースの名前づけや、変更など綺麗にやっていけそうです。

# 感想: ECS にした

EKS か ECS で悩んだのですが、やっぱり簡単なので ECS にしました。社内には EKS も１つあるのですが、ECS に統一することにしました。
これで本番がコンテナ化できたので、デプロイスクリプトとさよならできて嬉しいです。ローカルも本番も docker 化することができで差分がなくなったことも嬉しい。

# 困ったこと: GitHub Actions のプルリクが動かない

プルリクを出したら lint や test を回すということがしたいのですが、最初それが出来ませんでした。なぜかというと、僕らの開発フローが fork したリポジトリからプルリクを出すスタイルだからです。


private リポジトリの場合、fork したリポジトリから出す pull_request ではワークフローが動きません。

https://help.github.com/en/actions/reference/events-that-trigger-workflows#pull-request-events-for-forked-repositories

なので、fork をやめました。 本体に commit して プルリクを作るスタイルに変えました。いまのところ、これで困っていません。


# 困ったこと: DB Migration をどうしたか

発想的には、one shot task でやるということでシンプルなのですが、GitHub Actions でどうやるんだ？というのに少しつまりました。

結論としては aws-actions/amazon-ecs-deploy-task-definition@v1 でタスク定義を更新して、 `ecs run-task` するという以下のようなイメージです。

```yaml
# 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](https://sentry.io/welcome/) 

もうこれがないと、やってられないと思うほど、泣くほど嬉しいツールです。案の定、リリース作業直後バグは発生しました。でも SENTRY のおかげで、エラー監視ができすぐに対処できました。本当にありがたいツールです。




# おわりに

今回の構成にしてみて、アプリケーションエンジニアにとって、デプロイやインフラの見通しがよくなったと思いました。今後もどんどん開発体験は良くなっていくんだろうなぁ。すごい。

CloudFormation のサンプルコードを置いておきます。誰かのお役に立てば幸いです。
[github.com/mochizukikotaro/cloudformation-sample](https://github.com/mochizukikotaro/cloudformation-sample)

ありがとうございました。