Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Deploy Rails apps in 2021

Deploy Rails apps in 2021

事業成長を加速させたエンジニアリングのウラ側
https://medpeer.connpass.com/event/211745/

Takumi Shotoku

May 28, 2021
Tweet

More Decks by Takumi Shotoku

Other Decks in Technology

Transcript

  1. 自己紹介 • 名前: 正徳 巧 • 会社: メドピア株式会社 • 所属:

    CTO室SRE • GitHub: @sinsoku (画像右上) • Twitter: @sinsoku_listy (画像右下) よろしくお願いします。 2
  2. 7

  3. 8

  4. 9

  5. 10

  6. GitHub Flow3 Deploy With GitHub, you can deploy from a

    branch for final testing in production before merging to main. つまりmainブランチは常に安定版になっており、問題が起きたら mainブランチをデプロイすることでロールバックできる。 3 https://guides.github.com/introduction/flow/ 17
  7. デプロイパイプライン GitHub 1. Actionsで ! のビルド4 2. リリースPRのマージ CodePipeline 1.

    CodeBuildで db:migrate 2. デプロイ 4 ビルドの高速化についてはテックブログ参照。https://tech.medpeer.co.jp/entry/2021/05/28/180408 26
  8. デプロイ頻度の計測 $ git log --merges \ --first-parent \ --since='2019-1-1' \

    --format='%cd' \ --date='format:%Y-%m' origin/master \ | uniq -c masterへのマージ == デプロイ回数 29
  9. 30

  10. デプロイ頻度を増やすには • ✅ デプロイの改善 • 15〜17分 " => 約7分 #

    • 月20〜25回 => 月45〜50回 • カナリアデプロイ • 死活監視 31
  11. AWS CodeDeploy ECSの線形デプロイ、カナリアデプロイをサポートしている。6 • カナリア: 最初の増分で10%、残り90%を5分後にシフト • カナリア: 最初の増分で10%、残り90%を15分後にシフト •

    線形デプロイ: トラフィックの10%を毎分シフト • 線形デプロイ: トラフィックの10%を3分ごとにシフト 6 太字部分のカスタマイズが可能。 33
  12. 36

  13. GitHub Actionsの利点 • AWS for GitHub Actionsが便利 • Railsエンジニアが触りやすい •

    ! YAML • " HCL(Terraform) • 1つのサービス(GitHub)で完結すると楽 37
  14. db:migrate の実行 steps: - uses: actions/checkout@v2 with: fetch-depth: 2 #

    db:migrate Λ͢Δඞཁ͕͋Δ͔൑அ͢ΔͨΊɺલճͷmasterϒϥϯνͱͷdiffΛऔಘ͢Δɻ - name: Diff files in db/migrate id: migrate run: | MIGRATE_SIZE=$(git diff --name-only @^ -- db/migrate | wc -l) echo "::set-output name=size::$MIGRATE_SIZE" # ్தུ - name: Run a task on Amazon ECS if: steps.migrate.outputs.size != '0' uses: sinsoku/amazon-ecs-run-task-definition@v1 with: task-definition: ${{ steps.update-task-def-cmd.outputs.task-definition-arn }} container: ${{ env.ECS_CONTAINER }} command: '["bin/rails", "db:migrate"]' service: ${{ env.ECS_SERVICE }} cluster: ${{ env.ECS_CLUSTER }} 42
  15. デプロイ(canary) steps: - name: Deploy to Amazon ECS id: code-deploy

    uses: aws-actions/amazon-ecs-deploy-task-definition@v1 with: task-definition: ${{ steps.task-def-web.outputs.task-definition }} service: ${{ env.ECS_SERVICE }} cluster: ${{ env.ECS_CLUSTER }} codedeploy-appspec: appspec.yaml codedeploy-application: example-app codedeploy-deployment-group: example-app-dg wait-for-service-stability: false - name: Wait for the canary environment to deploy run: | names=$(aws deploy get-deployment --deployment-id ${{ steps.code-deploy.outputs.codedeploy-deployment-id }} \ --query 'deploymentInfo.loadBalancerInfo.targetGroupPairInfoList[].targetGroups[].name' \ --output text) arns=$(aws elbv2 describe-target-groups --names $names \ --query 'TargetGroups[].TargetGroupArn' \ --output text) for arn in $arns; do aws elbv2 wait target-in-service --target-group-arn $arn done 43
  16. デプロイ(production) production: needs: canary runs-on: ubuntu-latest timeout-minutes: 15 environment: name:

    production url: https://example.com concurrency: deployment steps: - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v1 with: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws-region: ap-northeast-1 - name: Wait a deployment run: aws deploy wait deployment-successful --deployment-id ${{ needs.canary.outputs.deployment-id }} 44
  17. ロールバック rollback: needs: [canary, production] if: cancelled() && needs.canary.outputs.deployment-id runs-on:

    ubuntu-latest timeout-minutes: 10 steps: - name: Stop a deployment run: aws deploy stop-deployment --deployment-id ${{ needs.canary.outputs.deployment-id }} --auto-rollback-enabled - name: Run a task on Amazon ECS if: needs.canary.outputs.migrate-size != '0' uses: sinsoku/amazon-ecs-run-task-definition@v1 with: task-definition: ${{ needs.canary.outputs.task-definition-arn }} container: ${{ env.ECS_CONTAINER }} command: '["bin/rails", "db:rollback", "STEP=${{ needs.canary.outputs.migrate-size }}"]' service: ${{ env.ECS_SERVICE }} cluster: ${{ env.ECS_CLUSTER }} 45
  18. リリースPRのマージ merge: needs: production runs-on: ubuntu-latest timeout-minutes: 5 steps: -

    name: Merge a release PR env: GITHUB_TOKEN: ${{ secrets.MEDPEER_GITHUB_TOKEN }} run: gh pr merge ${{ github.event.number }} --merge --repo ${{ github.repository }} 46
  19. デプロイ頻度を増やすには • ✅ デプロイの改善 • 15〜17分 " => 約7分 #

    • 月20〜25回 => 月45〜50回 • $ カナリアデプロイ • 死活監視 47