MicroAd Developers Blog

マイクロアドのエンジニアブログです。インフラ、開発、分析について発信していきます。

Ansible AWXでMySQLの構成管理を行う

マイクロアドでインフラエンジニアをやっている長田です。おもにMySQLなどのDBA業務に携わっていますが、今回はAnsible AWXを用いてMySQLのユーザやパラメータといった構成の管理を導入したことについてお話したいと思います。

Ansible / Ansible AWXとは

ご存知の方も多くおられると思いますが、AnsibleとはRed Hat社が主導して開発されているオープンソースの自動化・構成管理ツールです。最新バージョンは2019/05/16にリリースされたv2.8で、現在も様々なミドルウェア・クラウド・ネットワーク機器に対応する機能が精力的に開発されています。

Ansible AWXとはRed Hat社が有償で提供しているAnsible Towerのアップストリーム版にあたるOSSであり、AnsibleをWeb GUI上もしくはAPIによって操作することができます。プレイブックの実行をテンプレートという形で保存でき、複数のテンプレートを組み合わせたワークフローやそれらのスケジュール実行、秘匿情報の保持、ジョブ履歴の確認といったAnsibleの活用に便利な機能が多く実装されています。
github.com

以下に記載する内容はそれぞれ以下のバージョンを基準としています。

  • Ansible: 2.7.10
  • AWX: 3.0.1

導入の経緯

もともとマイクロアドでは構成管理ツールとしてPuppetを使用していましたが、MySQLについてはパッケージのインストールのみを行っており、ユーザの作成やレプリケーションの構築、パラメータの修正などはインストール後手動で行っていました。また作成したユーザの管理・一覧化も別のパスワードマネージャで行っていたため、ユーザの追加やMySQLスレーブの増築を行う度にそれなりの手作業が発生していました。これらの作業を自動化するべく、まずMySQLのユーザ管理にAnsibleを導入しました。その後、新規構築するMySQLサーバのためにパッケージインストールやレプリケーション構築、バックアップスケジュール設定、MySQLパラメータの変更といった機能を追加していきました。PuppetからAnsibleへの全面的な移行も検討しています。

Ansibleリポジトリの構成

Ansibleで使用する各ファイルはBest Practicesgeerlingguy/ansible-role-mysqlを参考に以下のようなディレクトリ構成として、GitHubで管理しています。

.
├── README.md
├── group_vars
│   ├── group_a
│   │   ├── general.yml
│   │   ├── mysql_users.yml
│   │   ├── mysql_vars.yml
│   │   └── vault.yml
│   └── group_b
├── inventory
├── playbook.yml
└── roles
    └── mysql
        ├── defaults
        │   └── main.yml  # 変数のデフォルト値を記載
        ├── handlers
        │   └── main.yml  # 特定タスク実行時にのみ行う処理を記載
        ├── molecule  # moleculeによるロールのテストを実施するためのファイル群を格納
        │   ├── ...
        ├── tasks
        │   ├── databases.yml  # MySQLのスキーマを作成
        │   ├── main.yml  # include_tasksにより、機能ごとに分割したymlファイルを読み込む
        │   ├── package.yml  # MySQLのインストールを実行
        │   ├── replication.yml  # MySQLのレプリケーションを設定
        │   ├── secure_installation.yml  # mysql_secure_installationを実行
        │   ├── setup.yml  # MySQLインストール前に必要な設定、パッケージのインストールを実行
        │   ├── users.yml  # MySQLのユーザを設定
        │   └── variables.yml  # MySQLのパラメータを設定
        ├── templates
        │   └── my.cnf.j2  # /etc/my.cnfとして配置するコンフィグファイルのテンプレート
        └── vars
            ├── master.yml  # マスタサーバでの実行時のみ適用する変数
            └── slave.yml  # スレーブサーバでの実行時のみ適用する変数

上記group_vars/****配下のymlファイルにAnsibleで使用する変数を記載しています。
mysql_users.ymlには追加するユーザの名称・ホスト・権限の一覧を、mysql_vars.ymlには設定するMySQLパラメータを、general.ymlにその他変数を保持させています。また、MySQLのユーザパスワードなど秘匿情報についてはansible-vaultで暗号化したvault.ymlに保持させており、平文ファイルは.gitignoreでコミットしないよう指定しています。

  • mysql_users.yml
---
# MySQL users
mysql_users:
  # 管理用ユーザ
  - name: admin
    host:
      - 'localhost'
      - '%'
    priv: '*.*:ALL,GRANT'
    state: present

  # レプリケーション用ユーザ
  - name: repl
    host:
      - '%'
    priv: '*.*:REPLICATION SLAVE,REPLICATION CLIENT'
    state: present

  # バックアップ用ユーザ
  - name: bkpuser
    host:
      - '%'
    priv: '*.*:SELECT,INSERT,CREATE,SUPER,RELOAD,FILE,LOCK TABLES,PROCESS,REPLICATION CLIENT,SHOW VIEW'
    state: present
  • mysql_vars.yml
---
# my.cnf settings
innodb_buffer_pool_size: 24G
innodb_log_file_size: 2G

# Online settings
mysql_vars:
  - variable: innodb_io_capacity
    value: 500
  - variable: innodb_io_capacity_max
    value: 2000
  - variable: expire_logs_days
    value: 7
  - variable: max_connections
    value: 3000
  - variable: max_allowed_packet
    value: 67108864
  - variable: thread_cache_size
    value: 64
  - variable: max_connect_errors
    value: 10000

また、プレイブックは以下のような簡素な作りにしています。

---
- name: Execute a role
  hosts: "{{ target_hosts }}"
  gather_facts: yes
  roles:
    - "{{ role_name }}"

Ansible AWXでは単一のプレイブックを実行するジョブテンプレートと、複数のジョブテンプレートを連結して実行するワークフローテンプレートとがあるのですが、ジョブテンプレート1つあたりの機能はなるべく少なくし、1つのホストグループに対する一連の操作はワークフローテンプレートで実行したほうが妥当と考えたため、プレイブックには1つのロールを実行する機能のみを与えています。
変数として設定している target_hostsrole_name については後述します。

AWXのジョブ構成

AWXのインストール手順や組織、ユーザ、チームの設定については省略します。
以下では、実際にAnsible AWXでプレイブックを実行する際の構成の一例について述べたいと思います。

あらかじめ、認証情報として以下を登録しておきます。

  • GitHubへの接続情報
  • 各ホストへSSH接続するためのユーザ情報
  • ansible-vaultによる暗号化ファイルを復号するためのVault認証情報

Ansible AWXは認証情報を持たせることでGitHubリポジトリを直接ソースとして使用することができます。
「プロジェクト」の項目で以下の図のようにSCMタイプを「git」とし、リポジトリのURLを指定します。
リポジトリ参照のためにSCM認証情報としてGitHubへの接続情報を設定します。

次に、プレイブックの実行対象とするサーバをインベントリーとして登録します。
今回は test_inventory というインベントリを作成し、その中にホストグループ group_a およびそれに属するホストを登録します。

インベントリの登録ができたら、ジョブテンプレートの作成を行います。 上記で登録したインベントリおよびプロジェクトを選択し、PLAYBOOKにはプロジェクト内にある playbook.yml を設定します。PLAYBOOKは選択したプロジェクト内にあるAnsibleプレイブックの書式で記載されたymlファイルを自動的に選択肢として表示してくれます。
また、追加変数として role_namemysql という値を設定することでroles配下のmysqlロールを実行するようにしています。

最後に、各グループ毎に複数のジョブを一連で実行するためのワークフローテンプレートを作成します。

追加変数として target_hosts にグループ名 group_a を与えています。これにより、 インベントリーの group_a に属するホストに対して今回作成したワークフローテンプレートが実行されます。

ワークフローテンプレートの新規作成時、または作成後「ワークフロービジュアライザー」を選択すると実行するジョブテンプレートのワークフローを設定することができます。

ワークフロー内に別のワークフローテンプレートを設定することもできます。上記の例では、管理者ユーザの設定やカーネルパラメータの変更など全サーバ共通で実行するジョブを wf_base として設定し、その後サーバの役割に応じたジョブテンプレートを実行するように設定しています。

以上の設定が終わりましたら、作成したワークフローを実行することで対象のホストに設定が適用されます。

おわりに

Ansible AWXでMySQLの構成管理を行うことで、ユーザの追加やパラメータの変更といった手作業を自動化することができ、また設定した内容の管理や確認も簡単に行うことができるようになりました。Ansible AWXは非常に多機能であり、まだまだ使いこなせていない部分もありますが、以上の例が何かの役にたてば幸いです。

マイクロアドではMySQL、Hadoop、Kafkaなどを用いたPB規模のデータ基盤の運用やチューニング、監視について日々改善を続けています。
Infrastructure as Codeの実践や新しい技術を使ってみたいというインフラエンジニアの方を積極的に募集していますので、ご興味を持たれた方は是非ご応募ください!

参考資料

Ansibleでできることを中の人が教えます - インストールと実行
Ansible with AWX