3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

AWS CodePipeline(CodeBuild)からRDSにアクセスする

Posted at

はじめに

AWSのCodePipelineから利用するCodeBuildにて、検証および本番環境のスキーマを取得、そのスキーマを元にテストを実行したかったため、RDSに接続する必要がありました。そのため、VPCに配置する必要があり、さらにmysqldumpコマンド等を使用する必要もあったため、AWS標準で用意されているイメージではなく、カスタムイメージ作成し、利用することにしました。

その際に諸々設定した際の記事となります。

全体構成

配置するSubnetはPrivateなため、Proxyを経由してインターネットに接続します。
image.png

大まかな流れは以下

  1. CodePipelineを起動
  2. CodeCommitからソースダウンロード
  3. CodeBuild実行
    1. VPC(PrivateSubnet)に配置
    2. 事前に用意したカスタムイメージ上でBuildSpecを実行(Docker on Docker)
    3. RDS接続・テスト実行など
    4. ECRへPUSH
  4. CodeDeployでECSへデプロイ

今回は利用するカスタムイメージの作成や、buildspec/Dockerfileなど各ファイルの設定について記載します。(3-1~3)
※CodePipeline全体的な設定・ECSへのデプロイについては割愛します。

カスタムイメージの作成

最終的にアプリケーション用イメージが使用するものは以下のため、カスタムイメージではそれをインストールしておきます。
使用するベースイメージはUbuntu 20.04としました。

  • mariadb-client(mysqldumpで必要)
  • Docker
  • docker-compose
  • AWSCLI(v1)

Dockerfile

FROM ubuntu:20.04

RUN apt-get update 
RUN apt-get install software-properties-common -y
RUN add-apt-repository universe

# mysqldumpコマンド実行するためのコマンドインストール
RUN apt-get install -y mariadb-client

# Docker及びdocker-composeを実行するためにインストール
RUN apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    software-properties-common -y
RUN curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
RUN apt-key fingerprint 0EBFCD88
RUN add-apt-repository \
    "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
    $(lsb_release -cs) \
    stable"
RUN apt-get update 
RUN apt-get install -y docker-ce
RUN curl -L "https://github.com/docker/compose/releases/download/1.25.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
RUN chmod +x /usr/local/bin/docker-compose

# ECRにPUSHする必要があるためAWSCLIインストール
RUN apt-get install \ 
    unzip \
    python3-venv -y
RUN curl "https://s3.amazonaws.com/aws-cli/awscli-bundle.zip" -o "awscli-bundle.zip"
RUN unzip awscli-bundle.zip
RUN /usr/bin/python3.8 ./awscli-bundle/install -i /usr/local/aws -b /usr/local/bin/aws
RUN aws --version
  1. mysqldumpを実行するためにmariadb-clientをインストール
  2. Docker及びdocker-composeを起動・実行するためにインストール
    1. Dockerインストール
    2. docker-composeインストール
    3. インストールするだけだとDockerデーモンが立ち上がらないので、後述のdocker-composeにcap_addcapabilityを追加する
  3. AWSCLIを実行するために、インストール
    1. 既存のbuildspecに記述されてるコマンドではv2だと動かないので、v1を明示的に指定

docker-compose

docker-compose.yml
version: '3'
services:
  custom_image:
    cap_add:
      - NET_ADMIN
    tty: true
    image: ${IMAGE_URI}
    build:
      context: .
      dockerfile: Dockerfile
  1. cap_addNET_ADMINを許可しておく(Dockerデーモンを立ち上げるため)

buildspec

上記のDockerfiledocker-compose.ymlを利用してbuildspecからECRにPUSHする
※ECRにプッシュするためのbuildspecファイルの設定や、CodePipeline設定についてはここでは割愛します。

アプリケーション用ビルドプロジェクト設定

カスタムイメージ指定

該当のビルドプロジェクトから環境を編集する
ECRレポジトリから上記で作成した該当イメージを選択。
認証情報プルイメージはプロジェクトサービスロール。
またDockerを操作するので特権を付与する。

image.png

VPC配置

VPC及び、サブネットに配置する(Private配置)
RDSにアクセスする必要があるため、RDS接続用のセキュリティグループを設定する
image.png

環境変数は状況に応じて各種設定を行う

アプリケーション設定

上記で設定したビルドプロジェクトで動かすアプリケーション側の各ファイル(buildspec・Dockerfile・docker-compose)設定

buildspec

buildspec.yml
version: 0.2
proxy:
  upload-artifacts: yes
  logs: yes
phases:
  install:
    runtime-versions:
      docker: 18
  pre_build:
    commands:
      # Dockerデーモン起動+PROXY設定
      - export HTTP_PROXY=${HTTP_PROXY}
      - grep "#export http_proxy" /etc/default/docker
      - sed -i -e "/^#export http_proxy/c\export http_proxy=\"${HTTP_PROXY}\"" /etc/default/docker
      - grep "export http_proxy" /etc/default/docker
      - service docker start
      - service docker status
      # DBスキーマを取得
      - mysqldump --user=${DB_USER_NAME} --password=${DB_PASS} --quick --single-transaction -h readreplica-xxx.com targetdb -d > db/schema.sql
  build:
    commands:
      # テスト実行
      - docker-compose -f docker-compose.testing.yml build
      - docker-compose -f docker-compose.testing.yml run tester
      - $(aws ecr get-login --region ${AWS_DEFAULT_REGION} --no-include-email)
      省略…
  post_build:
    commands:
      省略…
artifacts:
  files: imagedefinitions.json

ポイントは以下
DockerfileでのイメージダウンロードなどProxyを経由するため/etc/default/dockerhttp_proxyを設定
(コメントアウトを外して、HTTP_PROXYを設定しなおす)

- export HTTP_PROXY=${HTTP_PROXY}
- grep "#export http_proxy" /etc/default/docker
- sed -i -e "/^#export http_proxy/c\export http_proxy=\"${HTTP_PROXY}\"" /etc/default/docker
- grep "export http_proxy" /etc/default/docker

Dockerのデーモンを起動(前述のNET_ADMINを設定していないと、ここでデーモンが起動しない)

- service docker start

リードレプリカに接続して、schemaを取得する

- mysqldump --user=${DB_USER_NAME} --password=${DB_PASS} --quick --single-transaction -h readreplica-xxx.com targetdb -d > db/schema.sql

テスト実行

- docker-compose -f docker-compose.testing.yml build
- docker-compose -f docker-compose.testing.yml run tester

docker-compose

同様にProxyを経由するように各種を変更
ここでは、buildspecから渡ってくるHTTP_PROXYargsでDockerfileに渡す

docker-compose.testing.yml
version: '3'
services:
  tester:
    build:
      context: .
      dockerfile: Dockerfile.testing
      args:
        - HTTP_PROXY=${HTTP_PROXY}
    links:
      - db_test
    environment:
      - UNIT_TEST_MYSQL_CONNECTION_STRING=root:password@tcp(db_test:3307)/db_test?parseTime=true&loc=Local&readTimeout=30s&writeTimeout=30s&timeout=30s
    command: go test ./... -v

  db_test:
    image: mysql:5.7.12
    environment:
      MYSQL_ROOT_PASSWORD: 'password'
      MYSQL_DATABASE: 'db_test'
    ports:
      - "3307:3307"
    command: mysqld --port 3307

Dockerfile

ARGHTTP_PROXYを設定する
今回はGoを用いているため、go mod downloadする際にProxyを経由するように設定

Dockerfile.testing
FROM golang:1.14 as builder

ARG HTTP_PROXY
省略…
RUN http_proxy=$HTTP_PROXY go mod download

省略…

まとめ

RDSに接続するために、PrivateSubnetへの配置を前提としている構成になっているため、Dockerや各言語が使用するコマンドを動かすために各所Proxyを設定していく必要があり、その辺が多少手間だと感じました。
とはいえ、動的にSchemaを取得し、テストの実行ができるようになったので、今後メンテナンスも含めて多少楽になるかと思っています。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?