Perlでansibleライブラリを作成する方法
Perlでansibleライブラリを作成する方法を紹介します。
1.問題点
ansibleのシナリオを作成する中で、既存のansibleライブラリに存在しない処理をする必要が生じました。
が、ライブラリの作り方がわかりません。
具体的には、
- 配置場所
- 引数の送受信
- 返却値の送受信
です。
ということで、Perlでansibleライブラリを作成する方法を紹介します。
ここではPerlで説明していますが、他の言語にも応用できると思います。
2.ansibleのディレクトリ構造
本題に入る前に、サンプルとして使用するansibleシナリオのディレクトリ構造を示します。
複雑ですいませんが、ansibleのベストプラクティスで記載しています。
ansible実行ディレクトリ/
inventory
send_user_password.yml
roles/
send_user_password/
tasks/
main.yml
files/
lib.tar.gz perlで使用するライブラリ
library/
send_user_password Perlスクリプト
このansibleシナリオの実行方法は下記です。
$ cd ansible実行ディレクトリ
$ ansible-playbook -i inventory send_user_password.yml
これで、roles/send_user_password/tasks/main.ymlが動作します。
そして、main.ymlの中でライブラリを使用します。
ansibleライブラリは"library"が該当します。詳細については後述します。
ここでは、ライブラリ以外の、各ファイルの内容を示します。
設定内容は環境に合わせてて適宜修正してください。
inventory
server_00 ansible_host=192.168.0.123
[all:vars]
ansible_user=root
ansible_ssh_pass=hogehoge
[server1]
server_00
send_user_password.yml
- hosts: server1
roles:
- role: send_user_password
vars:
work_path: "/tmp"
main.yml
- name: "Perlライブラリ転送"
unarchive:
src: lib.tar.gz
dest: "{ work_path }"
- name: ユーザ・パスワード送信
send_user_password:
user: test
password: hoge
register: result
- name: "結果出力"
debug:
msg: "{{ result }}"
3.ライブラリ用Perlスクリプトのサンプル
Perlスクリプトのサンプル(send_user_password)を下記に示します。
このスクリプトは、受信した引数をそのまま返却するだけのものです。
#!/usr/bin/perl
use lib '/tmp/lib';
my $file = shift(@ARGV);
open( my $fh, "<", $file );
my $contents = do { local $/; <$fh> };
my @content = split( /\s/, $contents );
my $user;
my $password;
for my $data ( @content ) {
my @tmp1 = split( /user=/, $data );
if ( $tmp1[1] ) {
$user = $tmp1[1];
}
my @tmp2 = split( /password=/, $data );
if ( $tmp2[1] ) {
$password = $tmp2[1];
}
}
if ( !$user || !$password ) {
print "{ \"msg\" : \"illegal parameter\", \"rc\" : 0, \"changed\" : \"false\", \"failed\" : \"1\" }";
exit;
}
print "{ \"msg\" : \"OK\", \"user\" : \"$user\", \"password\" : \"$password\", \"rc\" : 0, \"changed\" : \"false\" }";
4.ライブラリの実行
まず、ansibleシナリオに記述した"send_user_password"が、そのままライブラリの実行ファイル名になります。
ansible実行ディレクトリ直下にlibraryディレクトリを配置することで、その配下のスクリプトがライブラリとして自動認識されます。
なお、このansibleのサンプルのライブラリ"send_user_password"は、ターゲットサーバに転送されて実行されます。
必要なライブラリがターゲットサーバに存在しない場合、ライブラリをlib.tar.gz等のファイル名でアーカイブして、roles/send_user_password/files/に配置し、unarchiveモジュールでターゲットサーバに転送・展開します。
- name: "Perlライブラリ転送"
unarchive:
src: lib.tar.gz
dest: "{ work_path }"
展開されたPerlライブラリは、Perlスクリプト内のlibモジュールで追加して利用します。
use lib '/tmp/lib';
5.ライブラリの引数
send_user_passwordの引数となるuserとpassword(のキーと値)は、ファイルとして保存され、そのファイル名がPerlスクリプトに渡されます。
- name: ユーザ・パスワード送信
send_user_password:
user: test
password: hoge
register: result
サンプルの場合、ファイルの中身は次のようになるはずです。
user=test password=hoge
下記に引数を取得するサンプルを示します。
# 引数としてファイル名を取得
my $file = shift(@ARGV);
# ファイルオープン
open( my $fh, "<", $file );
# 中身をすべで取得
my $contents = do { local $/; <$fh> };
# 半角スペースで分割
my @content = split( /\s/, $contents );
# 引数を取得
my $user;
my $password;
for my $data ( @content ) {
my @tmp1 = split( /user=/, $data );
if ( $tmp1[1] ) {
$user = $tmp1[1];
}
my @tmp2 = split( /password=/, $data );
if ( $tmp2[1] ) {
$password = $tmp2[1];
}
}
6.ライブラリの返却値
返却値はJSON形式です。ダブルクォーテーション等にはエスケープが必要です。
ここでは受信した引数をそのまま返却しています。
print "{ \"msg\" : \"OK\", \"user\" : \"$user\", \"password\" : \"$password\", \"rc\" : 0, \"changed\" : \"false\" }";
サンプルのansibleでは、受信した返却値を変数resultに保存し、出力するようにしています。
- name: ユーザ・パスワード送信
send_user_password:
user: test
password: hoge
register: result
- name: "結果出力"
debug:
msg: "{{ result }}"
個別に出力したい場合は、result.userやresult.passwordとします。
- perlのCPANモジュールからRPMを作成する方法
- Perlで「Subroutine permission redefined at~」を抑止する方法
- XML::Simpleのインストールでエラーになる場合の対処
- YAML::Tinyで「YAML::Tiny found bad indenting in line~」というエラーになる場合の対処
- Perlの正規表現を使って文字列をまとめて取得する方法
- Perlのハッシュでキーの有無を調べる方法
- perlで配列の途中の要素を削除する方法
- YAML::Tinyでコロンを利用する方法
- Perlで改行コードがCRのファイルを読み込む方法
- Perlで「Possible precedence issue with control flow operator」という警告の対処
- PerlのLWPで「Can't verify SSL peers without knowing which Certificate Authorities to trust」というエラーになったときの対処
- Perl+Windowsでファイルを再帰的にリネームする方法
- Perlプログラムの中でファイルの一部を書き換える方法
- Perlの「Bareword "%s" not allowed while "strict subs" in use~」というエラーについて
- Perlで文字列結合しながらs///演算子で置換する方法