2018/07/30
Ansibleでサーバ作業を簡単に
目次
こんにちは。機器管理/監視・システム運用チームの刑です。
アトラスでは、業務の効率化・自動化のために様々なツールを使っています。今回は、私の所属する機器管理/監視・システム運用チーム(以下、システム管理チーム)に導入している構成管理ツールAnsibleについて、社内での運用の仕組みを紹介します。
Ansibleとは
Ansible(アンシブル)は、Pythonで記述されたオープンソースの構成管理ツールです。サーバを構築する際、設定ファイルを予め用意することで、ソフトウェアのインストールやサーバ設定の修正、サービスの起動/停止、ネットワーク設定といったサーバの各種作業が自動的に実行されます。Ansibleは構成管理ツールの中でも後発製品なので、従来のツール(ChefやPuppetなど)の不足点を克服し、シンプルな設定ファイルとエージェントレスで動くようになったので、たくさんのユーザ企業が使い始めています。Ansibleの使い方などは公式ドキュメントをご参照ください。
アトラスでは去年、サーバ運用・管理上の定型作業を自動化する目的でAnsibleを導入しました。現在では、サーバの新規構築やユーザアカウントの一元管理、ミドルウェアの一括アップデートなど多くの業務をAnsibleで簡単に対応できるようにしています。まだ改善する余地がありますが、今までにできた仕組みを早速紹介していきます。
まずはAnsibleコードをGitHubで管理
AnsibleはInfrastructure as a Code理念を実践する構成管理ツールなので、ソースコード(以下、Ansibleコード)でリモートのサーバの設定と管理を行うことができます。サーバ構築作業のたびにAnsibleコードを追加作成していくため、プログラムのソースコードのように適切にバージョン管理することが必要になります。アトラスでは、すべてのAnsibleコードをGitHubで管理しています。また、作業時に本番環境と開発環境が混ざらないようにリポジトリを分けています。
作業ディレクトリ構成
Ansibleコードは主に2種類の設定ファイル(インベントリ、プレイブック)から構成されています。
- インベントリ(Inventory):被管理ホストの情報を記述するファイル(hosts)、変数定義ファイル(group_vars, host_vars)など。
- プレイブック(Playbook):YAMLという形式で記述される、タスク記述と実行のためのファイル。
Ansibleコードの可読性を高めるため、インベントリとプレイブックを適切に分割することが重要です。アトラスでは、次のようにAnsibleのRole機能を使って作業ディレクトリを配置しています。
- 変数定義ファイル(group_vars、host_vars):各ホストグループごと、各ホストごとの変数定義ファイルを格納するディレクトリです。
ホスト記述ファイル(hosts):被管理ホストやホストグループを記述したインベントリファイルです。 - ロール実行ファイル(roleXXX.yml):ロールディレクトリ内に定義したタスクをまとめて実行するためのプレイブックです。
- ロールディレクトリ(role/role1/、 role/role2/ など):サーバ上に実行するタスクやアップロードしたいファイルなどを配置するためのディレクトリです。
- 作業テンプレート(role/temlate1/、 role/template2/ など):テンプレート用のコードを格納するディレクトリです。
ロール実行ファイルとロールディレクトリだけは作業毎に作成します。こうするメリットは、インベントリファイルが共有できることと、既存のロールディレクトリをコピーして新しいタスクを作成できることです。
Ansibleでのサーバ作業例
以下、ユーザアカウント一括作成を例として、ロール実行ファイルとロールディレクトリの作成方法を紹介します。
今回、作成に必要なファイルはrole-new.yml、add_users.yml、main.ymlです。role-new.ymlはロールを実行する大元のプレイブックですので、作業ディレクトリのルートに配置します。role-newのロールディレクトリにtasks/add_users.yml、 tasks/main.ymlを作成します。
追加したいユーザの権限やユーザ名、パスワードをadd_users.ymlに設定します。パスワードは秘密情報なので、ハッシュ化した文字列を使用します。
1 2 3 4 5 6 7 8 9 10 |
- name: sudoユーザ権限を持つユーザの追加(adminグループ) user: name={{item.name}} password={{item.pass}} groups=admin state=present #ユーザ権限設定 with_items: #ユーザ作成(ハッシュ化したパスワードを使用) - { name: 'testUser1', pass: '$6$rounds=656000$bclWpPPTuLtLrKJR$iIdejfW0aTWclMnZJng95PAudqvqxxjDwlHN/3Q4YevYcRv8cO.0OhzONSfS8nphFgdXcwLKKhuBtw.fR4.5x/' } - { name: 'testUser2', pass: '$6$rounds=656000$8IhLxluyIfesNnC/$fMVde6XnNTN.3QqjLN6xSXFRebPbfLA8gEhTZY/9ZVZgHU/KyogSKLAg/xVkvCI5RUgKi5G0LLutGcIVsQSW2/' } - { name: 'testUser3', pass: '$6$rounds=656000$qf5lzLG5YSqWqXRx$N0rK8L7S2FrvZmaWc1DQTIyYyFpC2E.6MaGR91SE9QDmpsnCu4UpiBdCvZ97R6UPgrGb0GU.EFH0Ij0JeVUuh1' } - { name: 'testUser4', pass: '$6$rounds=656000$kV0cYl6KtO.09hOv$UT4a0tIuAkPdmAIyjN6bUFTyawjm5rWnWRgOnMKxTtD845WZINuZUG9.2M97B2cYgXT0pKXL8Nrl/L3IfugQR1' } tags: - add_users |
main.ymlはロールがデフォルトで実行するプレイブックです。コードを読みやすくするため、main.ymlの中では具体的なタスク内容を書かず、読み込みたいプレイブックのみ記述します。
1 2 |
### ユーザ追加 - import_tasks: add_users.yml |
role-new.ymlの構成は以下のとおりです。ホスト名とロールディレクトリを指定します。
1 2 3 4 5 |
- name: テストホストにユーザアカウントを一括作成 hosts: {host_name} #hosts.ymlに記載されたホスト名を入力 become: yes roles: - role-new #ロールディレクトリを指定 |
ターミナルでrole-new.ymlを実行すれば、add_users.ymlの中で記入したユーザアカウントが一括作成されます。
コードテンプレートの設計
サーバを構築する際、OSの基本設定やミドルウェア(iptables、apacheなど)のインストールはよくある作業だと思います。こういう作業はサーバごとに大きな差がないので、適切にコードテンプレートを作成すれば、毎回似たような作業をする必要がなくなります。システム管理チームは、サーバ運用管理によくある作業を定型化できるまで細分化して、コードテンプレートを作成しています。サーバ構築などの作業時には、必要なコードテンプレートを選ぶだけでプレイブックが簡単に作れます。
次の図は作ったコードテンプレートの一部です。CentOSサーバ構築時によくある作業をミドルウェア別に分割してファイルを作成しています。
コードテンプレートの中身はこんな感じです。
1 2 3 4 5 6 7 8 9 10 11 12 |
- name: IPアドレス・ホスト名追記 lineinfile: dest: "{{hosts_file}}" line: "{{private_ip}} {{hostname_fqdn}} {{hostname}}" insertafter: '^127.0.0.1' tags: - hosts_file - name: /etc/hostsの修正 replace: dest="{{hosts_file}}" regexp="^::1" replace="#::1" tags: - hosts_file |
サーバ特有の定義値をすべて変数にしているので、該当する変数の値をインベントリファイルで指定すれば、テンプレートをそのまま実行できるようになり、コードの修正は必要ありません。
おわりに
以上、アトラスでのAnsibleの使い方について紹介しました。1年間の運用を経て、私はAnsibleの「導入が容易」「設定ファイルがシンプル」という点をすごく実感しました。社内のサーバ運用・管理業務の中で、効率化・自動化できる部分がまだたくさんあると思いますので、引き続きAnsibleを活用していきたいと思います。