🤤

プライベートネットワークにあるRDSにGithub Action使ってマイグレーションする話

2024/01/16に公開

タイトル長くてすみません。

背景

ECS構成のプロダクトのORMとして、prismaを採用してます、Github Actionを使ってデプロイをする際に、もしDBスキーマに変更があった場合、マイグレーションも一緒に実行したい。

課題

  1. RDSはAWSのプライベートネットワークに配置しているため、踏み台サーバー、もしくはECSにEXECしなければ、DB操作できません。
  2. prisma使用してるため、マイグレーションもprismaの機能を使用したい。
  3. サードパーティーの怪しいGithub Actionライブラリを使用したくありません。

結論

ECSタスクを使用してマイグレーション回すことにした。
一部の実装は下記の通りです。

release.yaml
前略...
- name: Render TaskDefinition And Data replacement
        id: task-def
        uses: aws-actions/amazon-ecs-render-task-definition@v1
        with:
          task-definition: task-definition.json
          container-name: ${{ env.PROJECT_NAME }}-app
          image: ${{ steps.build-image.outputs.image }}

      - name: Deploy app with CodeDeploy Blue/Green deployment
        uses: aws-actions/amazon-ecs-deploy-task-definition@v1
        with:
          task-definition: ${{ steps.task-def.outputs.task-definition }}
          cluster: ${{ env.PROJECT_NAME }}-dev-app-cluster
          service: ${{ env.PROJECT_NAME }}-dev-app-service
          wait-for-service-stability: true

      - name: ECS Run Task for Execute DB Migration
        id: run-task-for-exec-command
        run: |
          network_config=$(
            aws ecs describe-services \
              --cluster ${{ env.PROJECT_NAME }}-dev-app-cluster \
              --services ${{ env.PROJECT_NAME }}-dev-app-service | jq '.services[0].networkConfiguration'
          )
          task_arn=$(
            aws ecs run-task \
              --cluster ${{ env.PROJECT_NAME }}-dev-app-cluster \
              --launch-type "FARGATE" \
              --network-configuration "$network_config" \
              --overrides '{
                "containerOverrides": [
                  {
                    "name": "${{ env.PROJECT_NAME }}-app",
                    "command": ["npx", "prisma", "migrate", "deploy"]
                  }
                ]
              }' \
              --task-definition ${{ env.PROJECT_NAME }}-dev-app-task-definition | jq '.tasks[0].taskArn'
          )
          task_id=$(echo $task_arn | cut -d "/" -f 3)
          task_url="https://${{ env.AWS_REGION }}.console.aws.amazon.com/ecs/v2/clusters/${{ env.ECS_CLUSTER }}/tasks/${task_id}/configuration"
          echo "task_url=${task_url}" >> "$GITHUB_OUTPUT"

ECSデプロイをする際に、task-definition.jsonファイルはAction内に作られるため、
それを再利用して、ECSのタスクを実行し、マイグレーションを実行します。

ECS採用してるプロダクトのマイグレーションのやり方は多岐に分かれています、
プロダクトの個性にあったものを採用できたら良いかと思います。
より良いやり方があればぜひ教えていただければ幸いです。

Discussion