これは
AWSのCode兄弟を最近触り始めていて、雰囲気がわかったので一度言語化しておこう&ブログ止まっててまずいので小ネタで、という記事
想定読者
完全に自分
- EC2へのデプロイ(Lambda/ECSは出てこない)
- GitLabCIとかJenkinsでパイプラインは作ってきた
- 完全にCode兄弟初めて
一言で言うと
- CodeCommit -> 超シンプルなGitLab/GitHub。pushとpullとpullreqができる
- CodeBuild -> コンテナ使ってビルドやテストできる。成果物はS3に置ける
- CodeDeploy -> CodeBuildが作った成果物をEC2にデプロイできる。AgentをEC2に入れておく必要がある(AmazonLinux2はデフォで入ってる)。オンプレのインスタンスにもデプロイできる
- CodePipline -> 上述した3兄弟(Commit/Build/Deploy)を順番に実行するジョブ管理的な役割
GitLabCI触ってるとgitlab-ci.ymlでbuild/deploy/pipline全部書いちゃうケースが多かったので、最初なんでこんなに分割されてるんだと思ったけれど、慣れてくると役割がしっかりしてて良くできてるなあと関心。
なお最低限の理解が上の箇条書きだと感じており、付加的な機能もまだまだあるので全くもって完全に理解してない。
理解の勘所
- Pipelineは最後に作れば良いので、Commit/Build/Deployをそれぞれ単体で動かせるとこまで最初にやる
- CodeBuildはbuildspec.ymlを書いてCodeCommitに置く
- CodeBuildで使うカスタムイメージはECRに置く(Dockerfile自分で書く)
- CodeDeployはappspec.ymlとhook用のシェルを書いてCodeCommitに置く
- hook用のシェルもbuildの成果物に入れる必要がある
ハマりどころ
- appspec.ymlでのCodeDeployを使ったデプロイは、直接ファイルを上書きできないのでhook用のシェルで対応する。4年越しのissueがあり、hookシェルの中での対応方法がレスされてる
- CodeBuild単体とCodePipelineからの実行で、secondaryなsourceの展開場所が異なるのでbuildspec.ymlで吸収した
- build単体実行だとカレントに
- pipeline実行だと全く別のパスに(これ本当にトラップ)
具体的にはこんな感じで吸収した。理由としてはsettings.gradleの中で includeFlat
してビルドするケースだった。
version: 0.2 phases: pre_build: commands: - gradle --version - pwd - bash -c "[ ! -d ../<reponame> ] && mv ${CODEBUILD_SRC_DIR_<reponame>} ../" - ls -l ../ - ls -l build: commands: - echo Build started on `date` - echo Building by gradle ... - gradle war post_build: commands: - echo Build completed on `date` - ls -l build/gradle/libs/hogehoge.war artifacts: files: - build/gradle/libs/hogehoge.war - appspec.yml - codedeployhooks/* discard-paths: yes
- CodeDeployのhookシェルのライフサイクルを理解する必要があるけど、とりあえずApplicationStopは初回時実行されないのでAfterInstall使っておく方が安全かもしれない