LoginSignup
6
1

More than 3 years have passed since last update.

Ansible AWXでアプリケーションテスト用のMySQLコンテナを作成する

Posted at

この記事は、MicroAd (マイクロアド) Advent Calendar 2020 - Qiitaの24日目の記事です。

はじめに

マイクロアドでは、MySQLの本番スキーマを入れたDockerコンテナを用意し、開発チームのテスト用に使っていただいています。これ自体は、日次実行で最新のスキーマと同期したものが用意できていたのですが、開発案件が複数並列で進む関係上「更新が入る前のスキーマでテストがしたい」という要望が生じてきました。これまでは、要望がある度にMySQL管理者側でコンテナのビルドとプッシュを手動実行していましたが、これを開発者側でも行えるよう、AnsibleとAWXを使ったビルド・プッシュの仕組みを構築してみました。

Playbook

---
- name: Dockerイメージのビルド、プッシュを実行
  hosts: "{{ docker_operation_host }}"
  gather_facts: no
  vars:
    github_repository_name: docker-images-mysqldb
  tasks:
    - name: GitHubのリポジトリを取得
      git:
        repo: git@{{ github_domain }}/{{ github_organization }}/{{ github_repository_name }}
        dest: /opt/{{ github_repository_name }}
        accept_hostkey: true
      no_log: true

    - name: Dockerレジストリにログイン
      docker_login:
        registry_url: "{{ docker_registry_domain }}"
        username: "{{ docker_registry_user }}"
        password: "{{ docker_registry_token }}"
      no_log: true

    - name: ビルド用キャッシュとしてlatestタグのイメージをプル
      docker_image:
        name: "{{ docker_registry_domain }}/{{ github_organization }}/{{ mysql_hostname }}"
        tag: latest
        source: pull

    - name: イメージをビルドし、Dockerレジストリにプッシュ
      docker_image:
        build:
          path: /opt/{{ github_repository_name }}/images/{{ mysql_hostname }}
          cache_from:
            - "{{ docker_registry_domain }}/{{ github_organization }}/{{ mysql_hostname }}:latest"
          args:
            MYSQL_HOSTNAME: "{{ mysql_hostname }}"
            MYSQL_USER: "{{ mysql_docker_user }}"
            MYSQL_PASSWORD: "{{ mysql_docker_password }}"
        name: "{{ docker_registry_domain }}/{{ github_organization }}/{{ mysql_hostname }}"
        tag: "{{ lookup('pipe','date +%Y%m%d') }}"
        push: yes
        source: build
      no_log: true

    - name: プッシュしたイメージをローカルから削除
      docker_image:
        state: absent
        name: "{{ docker_registry_domain }}/{{ github_organization }}/{{ mysql_db_name }}"
        tag: "{{ lookup('pipe','date +%Y%m%d') }}"

MySQLのDockerfileはGitHubリポジトリ上で管理しているため、まずDockerイメージをビルドするホストにリポジトリをクローンし、ホストでビルドした後、Dockerレジストリにプッシュしています。
docker_image タスクで tag: "{{ lookup('pipe','date +%Y%m%d') }}" とすることにより、YYYYMMDD形式での実行日がタグとなってビルド、プッシュされます。

変数について

github_domain : リポジトリを取得するGitHubのドメイン名
github_organization : リポジトリを取得するGitHubのオーガナイゼーション名
github_repository_name : 取得するGitHubリポジトリ
docker_registry_domain : プッシュするDockerレジストリのドメイン名
docker_registry_user : Dockerレジストリにログインするユーザ名
docker_registry_token : Dockerレジストリにログインするユーザのトークン
mysql_hostname : イメージを作成するMySQLのホスト名
mysql_docker_user : MySQLのスキーマを取得するためのユーザ(要、SELECT権限)
mysql_docker_password : MySQLユーザのパスワード

これらの変数のうち、Playbook内で与えていないものについてはgroup_vars(秘匿情報はansible-vaultで暗号化)またはAnsible AWXの追加変数で値を付与しています。

Dockerfile

FROM mysql:8.0

ARG MYSQL_HOSTNAME=unknown
ARG MYSQL_USER=unknown
ARG MYSQL_PASSWORD=unknown

RUN apt-get update && apt-get install -y --no-install-recommends wget && rm -rf /var/lib/apt/lists/* && \
    # MySQLのスキーマをインポート
    mysqldump -h${MYSQL_HOSTNAME} -u${MYSQL_USER} -p${MYSQL_PASSWORD} -B xxxx_db --no-data --lock-tables=false --set-gtid-purged=OFF > /docker-entrypoint-initdb.d/dump.sql

# 外部から渡される引数 (docker build時に渡される)
ARG GIT_REVISION=unknown
ARG GIT_ORIGIN=unknown
ARG IMAGE_NAME=unknown
LABEL git-revision=$GIT_REVISION \
      git-origin=$GIT_ORIGIN \
      image-name=$IMAGE_NAME

Oracle公式で提供されているMySQLイメージには /docker-entrypoint-initdb.d/ 配下にあるSQLファイルをビルド時に実行する機能があるため、 mysqldump の --no-data オプションでスキーマ情報のみを取得したダンプファイルを作成し、取得した環境と同一のスキーマを持ったDockerイメージを生成します。
Dockerのビルドを行う環境に上記ファイルをクローンし、 docker_image タスクで MYSQL_HOSTNAME などの引数をAnsibleから渡すことでmysqldumpを実行できるようにしています。

Ansible AWXでのジョブテンプレート化

上記のPlaybookを使用したジョブテンプレートをAnsible AWX上で作成し、開発チームのユーザにジョブの実行権限を付与することで、ワンクリックのジョブ実行でDockerイメージのプッシュまでが完了するようになっています。
スクリーンショット 2020-12-24 20.48.46.png

6
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
6
1