Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
15
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

Organization

AWS CodeBuildのコンテナから、RDSへ直接マイグレーションを実行する方法

概要

サービスを全部ECS + Fargateで行うサービスで、簡単かつCoolにマイグレーション実行する方法を記します。
具体的にはCodePipeline & CodeBuildを設定し、ビルド中にマイグレーションが走るように設定します。

この記事が役に立ちそうな人

  • ECS + Fargateでサービスを構築しようとしている人
  • サービスにはRDSを用いているが、マイグレーションをどこから行おうか悩んでいる人

背景

マイグレーションをいかにCoolに行うかはサーバーサイドの至上命題と言っても過言ではありません。(?)

前述の通りECS + Fargateでサービスを構築すると、FargateにはSSHできないのは周知の事実です。
よってコンテナに入れないため、フレームワークの機能を用いたマイグレーションを実行できません。
そして、マイグレーションは必ずソースコードのデプロイ前に実行される必要があります。

以上のことから、ソースコードのデプロイを行うCodePipelineのフローでマイグレーションを行うフェーズを追加し、マイグレーション含めたアプリケーションのデプロイを管理できたらCoolだなと思った次第です。

こちらの方法で実はその例が示されているのですが、タスク定義をjsonで書く必要があり、ステージング環境などの環境ごと対応が手間のように見受けられました。

もっと簡単でセキュアな方法はないかと考えていたところ、CodeBuildのドキュメントにCodeBuildが特定VPC, サブネットで実行できると書いていました。

RDSにはプライベートサブネットからしかアクセスできないようにしていましたが、これならCodeBuildインスタンスに立ち上げたコンテナから、マイグレーションを直接実行できるのでは? と思いついたわけです。

実際に

プライベートサブネット上に分離された Amazon RDS データベース内のデータに対して、ビルドから統合テストを実行する。

とあるように、RDSへのアクセスが想定されているようです。

目的

  • CodePipelineのフェーズ中にmigrationフェーズを追加し、ソースコードのデプロイに加えてマイグレーションも制御したい
  • ECSタスク定義を書きたくない
  • もちろんセキュリティは維持する
  • フレームワークのマイグレーション機能を使いたい 1

インフラ構成の説明

CBMirationDesc.png

これが全貌ではありませんが、プライベートサブネットについてはこの構成です。AZの冗長化は端折っています。
ECSのセキュリティグループとは別のSGを用意し、CodeBuildにはそれを設定しておきます。

セキュリティグループ3にはセキュリティグループ1のインバウンドトラフィックを許可しておきます。
セキュリティグループ1には特に設定は不要です。

具体的な設定

CodeBuild

vpcsettings.png

上記画像のようなVPCに関する設定があります。
ここにインフラ構成で記した通りの設定をしておきます。

あと環境変数AWS_ENVIRONMENTを設定しておきます。
これでどの環境のデータベースへ接続するかを、laravelのenvファイルの読み込みを切り替えることで選択できるようになります。
つまり後述のbuildspecは全環境で共通利用できます。

加えて使用するbuildspecは後述のbuildspec-migration.ymlを指定してください。

buildspec

実例を示します。

buildspec-migration.yml
version: 0.2
phases:
  install:
    runtime-versions:
      docker: 18
    commands:
      - echo Install started on `date`
      - cat /etc/issue
      - curl -L "https://github.com/docker/compose/releases/download/1.21.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose && chmod +x /usr/local/bin/docker-compose
      - docker-compose --version
      - docker -v
      - pwd && ls -l
  build:
    commands:
      - echo Build started on `date`
      - echo Building the Docker image...
      - sed -e 's/AWS_ENVIRONMENT/$AWS_ENVIRONMENT/g' docker-compose-migration.yml > docker-compose.yml
      - docker-compose build
      - docker-compose up -d
      - docker ps
      - docker exec laravel-api bash /project/build.sh
  post_build:
    commands:
      - echo Build completed on `date`
      - echo Start migrate
      - docker exec laravel-api php project/artisan migrate

私はdocker-composeを用いてコンテナを立ち上げています。2

sed -e 's/AWS_ENVIRONMENT/$AWS_ENVIRONMENT/g' docker-compose-migration.yml
これで環境ごとにdocker-compose.ymlを生成します。これでこのymlは全環境で使いまわせます。

docker exec laravel-api bash /project/build.sh
ここではcomposer installを行うだけのシェルを実行しています。でないとmigrateが動かないので。

docker exec laravel-api php project/artisan migrate
ここでついにmigrationを実行しています。

docker-compose

私はdocker-composeを用いているので、その設定も例を示します。

docker-compose-migration.yml
version: '3.3'

services:
  # web - api
  api:
    build: ./alpine-apache-php7
    container_name: laravel-api
    environment:
      - APP_ENV=AWS_ENVIRONMENT
    volumes:
      - "./project:/project"
    ports:
      - "18080:80"

APP_ENVには設定すればdevelopmentなどの任意のテキストを入れられるので、読み込む環境設定ファイルの制御ができます。

CodePipeline

パイプラインの例を示します。

cp.png

上記のようにECRへのビルドフェーズと、マイグレーション含むデプロイフェーズは分けています。
こうすることでマイグレーションとデプロイが自動的に実行されないようになります。

参考文献

LaravelをElastic BeanstalkからFargateに移行しました
https://qiita.com/hareku/items/73f7730c1adc01bbe5a0

AWS公式CodeBuildのVPCサポートについてのドキュメント
https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/vpc-support.html


  1. フレームワークはLaravelを使っています。多分他のフレームワーク、言語でも同じことができるはずです。 

  2. どこかのタイミングからCodeBuildでdocker-composeを動かすとエラーを吐くようになりました。どうやら標準イメージを使うようになってから追加の設定が必要になったようです。このように別のソフトをインストールするときは、CodeBuildの環境設定においてEnable this flag if you want to build Docker images or want your builds to get elevated privileges.にチェックを入れないとエラーとなります。注意してください。 

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
15
Help us understand the problem. What are the problem?