独自ドメインを作りました
今後はこちらに移行していく予定です。
環境変数
- ANSIBLE_RETRY_FILES_ENABLED: 失敗した時にsite.retryファイルを作成するかどうか。
0
とすると、作成しなくなる。
設定
Ansible Configuration Settings — Ansible Documentationより。
adhoc実行
例えば以下のコマンドで、対象マシンの情報が得られる。
ansible all -i ホスト名, -m setup
オプションは以下の意味を持つ。
all
: ホスト名のパターン。通常はall
-i <ホスト名 or IPアドレス>
: インベントリ文字列、ホスト名の最後に,
をつけるのを忘>れないこと1。-m
: 起動するモジュール
よく使う起動オプション
-i <インベントリファイル>
: インベントリファイルを指定-C
: 実行しない(dry run)-D
: 結果の差分表示-t <タグ>
: 指定したタグのみ実行--step
: タスクごとに確認を行う。--syntax-check
: 文法チェックを行う。-l <パターン>
: 指定したパターンにマッチするホストのみ処理
環境変数
- ANSIBLE_KEEP_REMOTE_FILES
- この値を
1
にすると、リモートの一時ファイルをクリーンアップしない。デバッグ時に便利。
- この値を
インベントリファイル
1つのホストに2つのポートは設定できない(回避策あり)
インベントリファイルに以下のように記述しても、意図した通りに動きません。 グループを分けてもダメです。
[some_group]
foo.example.com:1111
foo.example.com:1234
この指定ができないことで何が困るのかというと、 SSH接続ポートを変えてPlaybookを2つ管理したい場合に困ります。
ただし、これには回避策があります。
GitHubにあるIssue Cannot specify two different ports to the same host in inventoryのリンク先にある
python - Ansible multiple hosts with port forwarding - Stack Overflowで書かれているように、
ansible_host
と ansible_port
を使って書きます2。
変更があったときだけ実行
いくつか方法がある。 1つ目は、handlerを使う(notifyの項目参照)。 2つ目は、registerで値を代入して、whenを使う方法。 rebootはこれでないとうまく動かなかった。
- file: state=...
register: foo
- file: ...
when: foo.changed
変数定義
以下の場所に書ける。
- group_vars
- host_vars
- インベントリ中
- roles/ロール/vars/
- set_fact
set_fact
set_fact中で複数定義する場合、 同じset_fact中で定義されている他の変数は参照できない。 以下のように書くとエラーになる。
- set_fact:
value_a: "abc"
value_b: "{{ value_a }}def"
notify
ハンドラが呼ばれるタイミング
role
を使用する場合は、tasks
3の終了タイミングで呼ばれる4。
handlers notified within roles section are automatically flushed in the end of tasks section, but before any tasks handlers.
ハンドラを強制的に呼ぶ方法
metaモジュールの flush_handlers
を使うと、そのタイミングでハンドラが呼ばれます。
ハンドラで複数のタスクをこなす方法
今はサポートされていないようです。チケットに代替案があります。
Add support for blocks in role handlers · Issue #14270 · ansible/ansible
ロール
ロール単位での実行オプションはないようです。 自分でtagsを付けるしかありません。
ループ
-
with_items
- 配列を取る。
- 配列の値が文字列のときは、
{{ item }}
として値を取得。 - 配列の値がハッシュのときは、
{{ item.name }}
などとして値を取得する。
-
with_nested
- 配列の配列を取る。
- 値は先頭に定義されたものから、
{{ item[0] }}
などとして値を取得。
モジュール
ファイルの展開
unarchiveを使う。
- コピー元の指定に注意
- デフォルト:
src
をローカルファイルと解釈して、リモートに転送して解凍 remote_src=yes
がある場合src
に://
がある場合はURLと解釈してダウンロード- それ以外のときは、ターゲットホストのパスと解釈して実行
- デフォルト:
- チェックサムは未対応
- Issue #13665に挙がっている通り、チェックサムには未対応です。
- get_urlモジュールを使ってからダウンロードが良いと思います。
- Issue #13665に挙がっている通り、チェックサムには未対応です。
ファイルの取得(ダウンロード)
get_urlを使う。 Proxyが環境変数で設定されているときは、Proxyを使用します。
大きいファイルをダウンロードする時は、checksumを付けること。 checksumを付けると、ダウンロード前にチェックサムを調べて、 一致していたらダウンロードしません。
if a checksum is passed to this parameter, and the file exist under the dest location, the destination_checksum would be calculated, and if checksum equals destination_checksum, the file download would be skipped (unless force is true).
- get_url:
url: http://example.com/path/
dest: /root/
checksum: sha256:xxxx
対応しているチェックサムは、sha1は対応しているようですが、 それ以外はpythonのバージョンによるので分からないみたいです。 ソースコード見れば分かるかも。。。
文字列置換
- 1行の追加・置き換え: lineinfile
- ブロックの追加: blockinfile
- 既存のブロックの置き換えには向いていない。
- ブロックの置き換え: replace
- これだけUTF-8以外をサポート。
ファイルごと置き換えていいのであれば、template、 またはcopyのcontentもアリだと思います。
AWS
- botoを入れる必要がある。
boto required for this module
と出るときは、インベントリファイルにansible_python_interpreter=python
と書く。単にpython
と書くと、PATHにあるものが適用される模様。デフォルトは/usr/bin/python
になる。
- モジュール
MySQL
Google Cloud
認証
サービスアカウントを作成する。
- 左上のメニューから、「IAMと管理」→「サービスアカウント」を選択
- 「サービスアカウントを作成」をクリック
- 値を入力
- サービスアカウント名: サービスの内容を表す文字列(日本語でもOK)
- 役割: 必要な役割を追加
- 例: Google Cloud DNS: DNS→DNS管理者
- サービスアカウントID: 一意のものを割り当て
- 新しい秘密鍵の提供: オン、キーのタイプはJSON
- 作成ボタンを押すと、JSONファイルがダウンロードされる。
Ansibleでは以下のように使用する。 まず、資格情報を直接渡す場合(秘密鍵を直接指定するので注意)。
- credentials_file: 秘密鍵の入ったJSONファイル。
- パスはプロジェクトトップからの相対パスが使用可能(roles/xxx/filesではない)
- service_account_email: サービスアカウントID(gserviceaccount.com)
- project_id: プロジェクトID
DB作成時のみインポートする方法
以下のように、mysql_dbが実行されたときだけインポートするのが良いと思います。
テンプレート
Jinja2を使う。
- 制御
{%
〜%}
で囲む。if
〜endif
のように囲む。
- 空白の制御(Whitespacde Control
{%-
や-%}
のように囲む。- Ansibleから使用する場合は、Jinja2を制御するためのヘッダが書ける(Notes)。
#jinja2: trim_blocks: "true", lstrip_blocks: "true"
のように書ける。
フィルタ
変数名の後に|
(パイプ)を付けることで、フィルタできる。
- Filters
- List of Builtin Filters
- lower: 小文字化
- upper: 大文字化
個人的に気をつけていること
- ファイル変更後にリロードしたいときは、
notify
を使う。 - nameには変数を使わない。環境変数は
$VAL
みたいな書き方をする。--start-at
とかで指定しづらいため。
- 何百台もデプロイする場合は別として、手動での作業を無理に排除しない。
- 例: サーバ再起動とかOracleのインストーラとか
- サーバ再起動は手順を整備したので、今後は使えそうです。
- とは言え手作業はなるべく減らしたいので、開発環境のマスタ設定は行う。
- 例: サーバ再起動とかOracleのインストーラとか
- 大きいファイルは手元に置かない。http経由で取得。
ディレクトリ構成
自分の場合、開発環境はVagrantですが、本番環境はオンプレや、VMなど様々です5。 なので、以下の要件を満たす必要があります。
- Vagrantとそれ以外を同一のPlaybookで扱いたい
- しかし、初期設定やテストデータは分離したい
この場合、以下のようなディレクトリ構成にしています。
- Vagrantfile
- bootstrap.sh: Vagrant起動時に読み込まれるスクリプト。
- yum updateや最低限のユーザ作成など。
- AWSではcloud-initとう仕組みがありますが、これを意識したものです。
- pre-install
- Vagrant固有の初期設定。
- 開発時はsshで作業する事が多いので、そのままrootになれるようにしています。
- ansible
- Vagrantと本番環境共通の設定。
- post-install
- テストデータなど、開発環境固有の設定。
この場合の難点は、Ansibleの変数が共有できないことですが、 以下のようにVagrantから変数を定義することで対処可能です。
config.vm.provision "ansible" do |ansible|
ansible.host_vars = {
"default" => {
"key" => "val"
}
}
ansible.playbook = "ansible/site.yml"
end
公式サイト
- Ansible Documentation
- ansible-playbook — Ansible Documentation
- ansible — Ansible Documentation
- Patterns — Ansible Documentation
外部サイト
- Ansible マジック変数の一覧と内容 - Qiita
- Ansible オレオレベストプラクティス - Qiita
- Ansibleのplaybookで使用できるアトリビュートの一覧 - Qiita
- jinja2 - Ansible: Get all the IP addresses of a group - Stack Overflow
- ansible で prompt (入力待ち) の実現とその周辺テクニックのまとめ - Qiita
関連項目
逆引きマニュアル
- Ansible: tarファイルをディレクトリ指定で展開する方法
- Ansible: ドキュメントをローカルで表示する方法
- Ansible 2.7でyum + with_itemsを使うと出る警告の直し方
- Ansibleでリブートする方法
- Ansible: Mavenアーティファクトの利用方法
- Ansible: 開発環境と本番環境を同じように管理する方法
- Ansible: チェックモードでエラーが起きて停止してしまう場合の修正
- Ansible: 文字列からファイルを作成
- Ansible + Vagrant + CentOS: パスワード認証を有効化する
- Ansible: command,shellモジュールの結果を検証したい場合
- Ansible: sudoで環境を引き継ぎたい場合
- Ansible: ルーティング対応
- Ansible: 設定の外部ファイルによる管理
- Ansible: 対象ホストを間違えないようにする方法
- Ansible: 相対パスでシンボリックリンクを作成する方法