はじめに
AWSのCodePipelineから利用するCodeBuildにて、検証および本番環境のスキーマを取得、そのスキーマを元にテストを実行したかったため、RDSに接続する必要がありました。そのため、VPCに配置する必要があり、さらにmysqldump
コマンド等を使用する必要もあったため、AWS標準で用意されているイメージではなく、カスタムイメージ作成し、利用することにしました。
その際に諸々設定した際の記事となります。
全体構成
配置するSubnetはPrivateなため、Proxyを経由してインターネットに接続します。
大まかな流れは以下
- CodePipelineを起動
- CodeCommitからソースダウンロード
- CodeBuild実行
- VPC(PrivateSubnet)に配置
- 事前に用意したカスタムイメージ上でBuildSpecを実行(Docker on Docker)
- RDS接続・テスト実行など
- ECRへPUSH
- 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
-
mysqldump
を実行するためにmariadb-client
をインストール - Docker及びdocker-composeを起動・実行するためにインストール
- Dockerインストール
- docker-composeインストール
- インストールするだけだとDockerデーモンが立ち上がらないので、後述のdocker-composeに
cap_add
でcapability
を追加する
- AWSCLIを実行するために、インストール
- 既存のbuildspecに記述されてるコマンドでは
v2
だと動かないので、v1
を明示的に指定
- 既存のbuildspecに記述されてるコマンドでは
docker-compose
version: '3'
services:
custom_image:
cap_add:
- NET_ADMIN
tty: true
image: ${IMAGE_URI}
build:
context: .
dockerfile: Dockerfile
-
cap_add
でNET_ADMIN
を許可しておく(Dockerデーモンを立ち上げるため)
buildspec
上記のDockerfile
とdocker-compose.yml
を利用してbuildspecからECRにPUSHする
※ECRにプッシュするためのbuildspecファイルの設定や、CodePipeline設定についてはここでは割愛します。
アプリケーション用ビルドプロジェクト設定
カスタムイメージ指定
該当のビルドプロジェクトから環境
を編集する
ECRレポジトリから上記で作成した該当イメージを選択。
認証情報プルイメージはプロジェクトサービスロール。
またDockerを操作するので特権を付与する。
VPC配置
VPC及び、サブネットに配置する(Private配置)
RDSにアクセスする必要があるため、RDS接続用のセキュリティグループを設定する
環境変数は状況に応じて各種設定を行う
アプリケーション設定
上記で設定したビルドプロジェクトで動かすアプリケーション側の各ファイル(buildspec・Dockerfile・docker-compose)設定
buildspec
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/docker
のhttp_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_PROXY
をargs
でDockerfileに渡す
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
ARG
でHTTP_PROXY
を設定する
今回はGoを用いているため、go mod download
する際にProxyを経由するように設定
FROM golang:1.14 as builder
ARG HTTP_PROXY
省略…
RUN http_proxy=$HTTP_PROXY go mod download
省略…
まとめ
RDSに接続するために、PrivateSubnetへの配置を前提としている構成になっているため、Dockerや各言語が使用するコマンドを動かすために各所Proxyを設定していく必要があり、その辺が多少手間だと感じました。
とはいえ、動的にSchemaを取得し、テストの実行ができるようになったので、今後メンテナンスも含めて多少楽になるかと思っています。