もりはやメモφ(・ω・ )

インフラなエンジニアからSREへ

AWS Code兄弟の自分なりの理解メモ殴り書き

これは

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使っておく方が安全かもしれない