かべぎわブログ

ブログです

Ansibleのwith_itemsで複数の変数を利用する

概要

Ansibleのwith_itemsディレクティブで複数の変数を利用する方法をご紹介します。

playbook例

こんなかんじでwith_itemsの項目を{}で囲ってあげます。

実行例

msgの部分を見るとちゃんと指定したとおりに出力されていることがわかる。

$  ansible-playbook -i ansible_hosts with_items_2.yml
PLAY [localhost] *****************************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************
ok: [localhost]

TASK [名字だけ] **********************************************************************************************************************************
ok: [localhost] => (item={u'myouji': u'tanaka', u'namae': u'tarou'}) => {
    "changed": false, 
    "item": {
        "myouji": "tanaka", 
        "namae": "tarou"
    }, 
    "msg": "tanaka"
}
ok: [localhost] => (item={u'myouji': u'yamada', u'namae': u'jirou'}) => {
    "changed": false, 
    "item": {
        "myouji": "yamada", 
        "namae": "jirou"
    }, 
    "msg": "yamada"
}

TASK [フルネーム] *********************************************************************************************************************************
ok: [localhost] => (item={u'myouji': u'tanaka', u'namae': u'tarou'}) => {
    "changed": false, 
    "item": {
        "myouji": "tanaka", 
        "namae": "tarou"
    }, 
    "msg": "(u'tanaka', u'tarou')"
}
ok: [localhost] => (item={u'myouji': u'yamada', u'namae': u'jirou'}) => {
    "changed": false, 
    "item": {
        "myouji": "yamada", 
        "namae": "jirou"
    }, 
    "msg": "(u'yamada', u'jirou')"
}


PLAY RECAP ***********************************************************************************************************************************
localhost                  : ok=3    changed=0    unreachable=0   

おわりに

複数個でもできるということだ。


入門Ansible

入門Ansible

Ansibleのwith_itemsで一気にいろいろyumインストールする

概要

Ansibleのwith_itemsディレクティブというループ処理(シーケンシャル呼び出し処理)を実行できるものを利用して、いろいろ一気にyum installしてみたいと思います。

playbook例

playbookはこんなかんじです。
今回の例ではdockernginxをインストールしようとしています。
with_itemsに定義した項目は{{ item }}変数に代入されます。
そのため処理としてはyum: name=docker-ioyum: name=nginxが実行されることになります。

実行結果

このplaybookを実行してみるとこんなかんじです。
changedはいくらループをまわしても1つとしてカウントされるので要注意です。

$  ansible-playbook -i ansible_hosts yum_with_items.yml

PLAY [localhost] *****************************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************
ok: [localhost]

TASK [yum install] ***************************************************************************************************************************
changed: [localhost] => (item=[u'docker-io', u'nginx'])

PLAY RECAP ***********************************************************************************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0 

実際にインストールされました!

$ sudo yum list installed | grep docker
docker.x86_64                      17.06.2ce-1.102.amzn2             @amzn2-core

$ sudo yum list installed | grep nginx
nginx.x86_64                       1:1.12.2-2.el7                    @epel      
nginx-all-modules.noarch           1:1.12.2-2.el7                    @epel      
nginx-filesystem.noarch            1:1.12.2-2.el7                    @epel      
nginx-mod-http-geoip.x86_64        1:1.12.2-2.el7                    @epel      
nginx-mod-http-image-filter.x86_64 1:1.12.2-2.el7                    @epel      
nginx-mod-http-perl.x86_64         1:1.12.2-2.el7                    @epel      
nginx-mod-http-xslt-filter.x86_64  1:1.12.2-2.el7                    @epel      
nginx-mod-mail.x86_64              1:1.12.2-2.el7                    @epel      
nginx-mod-stream.x86_64            1:1.12.2-2.el7                    @epel   

おわりに

with_itemsを利用して一気にyum installすることができました。
ループ処理を使うことでplaybookを短くわかりやすく記述することができるようになるかと思います。


入門Ansible

入門Ansible

Ansibleでshellをつかってもchanged_whenで絶対にchangedにしない

概要

Ansibleでshellcommandモジュールを利用すると、結果が常にchangedになってしまいます。
なんか気持ち悪いなーということで絶対にchangedにしない方法です。

playbook例

changed_when: Falseとすることで絶対にchangedにはならなくなります。

実行例

実行するとこんなかんじ。

$  ansible-playbook -i ansible_hosts always_ok.yml


PLAY [localhost] *****************************************************************************************************************************

TASK [ls] ************************************************************************************************************************************
ok: [localhost]

PLAY RECAP ***********************************************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0   

おわりに

Ansibleの冪等性維持のためにcommandとかshellとかはあんまりつかわないほうがいいと思うんだけれども使わなきゃいけなくなったかつなんかごまかしたいときにおすすめの記述方法です。

だれにおすすめかはわからないけど。


Infrastructure as Code ―クラウドにおけるサーバ管理の原則とプラクティス

Infrastructure as Code ―クラウドにおけるサーバ管理の原則とプラクティス

cd - で一つ前にいたディレクトリに戻る

概要

cd -コマンドを利用することで一つ前に自分が居たディレクトリに戻ることができます。

コマンド例

$ pwd
/Users/kabegiwa/Downloads

$ cd
$ pwd
/Users/kabegiwa

$ cd -
/Users/kabegiwa/Downloads

おわりに 

これでまちがってcd実行してホームディレクトリにもどちゃってわーーー
みたいなときにも大丈夫ですね!!!

[改訂第3版]シェルスクリプト基本リファレンス ──#!/bin/shで、ここまでできる (WEB+DB PRESS plus)

[改訂第3版]シェルスクリプト基本リファレンス ──#!/bin/shで、ここまでできる (WEB+DB PRESS plus)

pipをプロキシ環境で利用する

概要

pipコマンドをプロキシ環境で利用する方法についてご紹介します。

コマンド例

こんなかんじでオプションをつけてあげることでプロキシをとおした環境でもpipを利用することができます。

pip install awscli --proxy http://example.proxy:8080

[試して理解]Linuxのしくみ ~実験と図解で学ぶOSとハードウェアの基礎知識

[試して理解]Linuxのしくみ ~実験と図解で学ぶOSとハードウェアの基礎知識

Google Apps Script でカレンダーをスプレッドシートにエクスポートする

概要

Google Apps Scriptを利用して自分のGoogle カレンダー上の1日分の予定をスプレッドシートにエクスポートしてみたいと思います。

スクリプト

スクリプトはこんなかんじ

CalendarApp.getDefaultCalendar().getEvents(oneDayAgo, now)でカレンダーの予定を取得することができます。
.getEvents(oneDayAgo, now)の箇所で取得する期間を指定できます。
今回は一日前(oneDayAgo)から現在(now)としています。

実行してみる

ためしにこのスクリプトを実行してみます。

前提として、カレンダーがこんなかんじだとすると f:id:kabegiwakun:20180404190811p:plain


こんなかんじで出力することができます。
f:id:kabegiwakun:20180404191403p:plain

おわりに

Google Apps Scriptでカレンダー上の予定を取得することができました。
カレンダー上の予定を取得して、なにか予定表のようなものを作ったりとかそういうことができそうです。

詳解! Google Apps Script完全入門 ~Google Apps & G Suiteの最新プログラミングガイド~

詳解! Google Apps Script完全入門 ~Google Apps & G Suiteの最新プログラミングガイド~

Ansibleのec2.pyの結果のJSONをホストグループ形式のファイルにしてみる

AnsibleでAWSのイントラを管理するときに利用するec2.pyの結果で応答されるJSONを人間に優しいホストグループ形式に変換してみたいと思います。

スクリプトはこんなかんじ

スクリプト自体はこんなかんじです。
シェルスクリプトでsedで変換かけているだけです。(要jqコマンド)

うごかしてみる

ec2.pyの結果が以下のようだとします。

$ ./ec2.py 
{
"_meta": {
  "ap-northeast-1a": [
    "172.140.1.1", 
    "172.140.1.2"
  ], 
  "tag_Name_kabegiwa_ansible_server": [
    "172.140.1.1"
  ], 
  "tag_Name_kabegiwa_ansible_client": [
    "172.140.1.2"
  ], 
  "type_t2_micro": [ 
    "172.140.1.2"
  ], 
  "type_t2_large": [ 
    "172.140.1.2"
  ], 
  "vpc_id_vpc_12345678": [
    "172.140.1.1", 
    "172.140.1.2"
  ]

それをこのスクリプトで実行するとこんなかんじに出力してくれます。

$ ./ec2.py 
[ap-northeast-1a]
172.140.1.1
172.140.1.2
 
[tag_Name_kabegiwa_ansible_server]
172.140.1.1

[tag_Name_kabegiwa_ansible_client]
172.140.1.2
  
[type_t2_micro] 
172.140.1.2
  
[type_t2_large] 
172.140.1.2

[vpc_id_vpc_12345678]
172.140.1.1
172.140.1.2

おわりに

ちょっとべんり

Ansible実践ガイド 第2版 (impress top gear)

Ansible実践ガイド 第2版 (impress top gear)

commコマンドで2つのテキストファイルの比較結果を出力する

あんまり知られてないような気がするけれど結構便利なcommコマンドについてまとめてみます。

commコマンドとは?

commコマンドとは、2つのソートされたテキストファイルを比較できるコマンドです。 ファイルを比較して、片方のファイルにしか存在しない行や、両方のファイルに共通して存在する行などを出力することができます。

ためしにうごかしてみる

たとえば以下のようなテキストファイルが存在するとします。

$ cat wawawa.txt 
AAA
BBB
CCC
DDD
EEE
$ cat sasasa.txt 
BBB
CCC
FFF

これをcomm コマンドで比較してみると以下のような出力になります。

$ comm wawawa.txt sasasa.txt 
AAA
        BBB
        CCC
DDD
EEE
    FFF

1カラム目(左)がwawawa.txtにのみ存在する行
2カラム目(真ん中)がsasasa.txtにのみ存在する行
3カラム目(右)がwawawa.txtとsasasa.txtに存在する行が出力されています。

オプションは以下のような物があります。

オプション 説明
-1 1カラム目を出力しない
-2 2カラム目を出力しない
-3 3カラム目を出力しない
--check-order ソートされているかどうかを確認する
--nocheck-order ソートされているかどうか確認しない
--output-delimiter=でりみた カラムを区切る文字列を指定

実用的な使い方

おもいついた使い方を書いていきます。

wawawa.txtにしか存在しない行を出力

$ comm -23 wawawa.txt sasasa.txt
AAA
DDD
EEE

sasasa.txtにしか存在しない行を出力

$ comm -13 wawawa.txt sasasa.txt
FFF

両方のファイルに存在する行を出力

$ comm -12 wawawa.txt sasasa.txt
BBB
CCC

おわりに

commコマンドを利用することでかんたんに2つのファイルの比較をすることができました。
diffでこねこねしなくてもいいのでかんたんですね!!!

新しいLinuxの教科書

新しいLinuxの教科書

Ansibleでプロキシ経由でインターネットに接続する

概要

社内イントラなど、プロキシを経由しないとインターネットと接続できないのでyumでインストールができない。など色々あると思います。

今回はAnsibleでプロキシを経由してインターネットと接続してみたいと思います。

playbook例

以下のようにenvironmentディレクティブにプロキシを設定します。

tasksが複数あっていちいちproxy書くのめんどくさいわー
という場合には以下のようにvarsに記載しておくこともできます。

おわりに

プロキシはただしくつかいましょう

初めてのAnsible

初めてのAnsible

Ansibleで新規ホストへのssh接続時にyes/noを確認しないようにする

概要

Ansibleではターゲットへssh接続をしています。
ですので、sshのデフォルトの動きとして新規ホストへの接続時は以下のように「接続するかい?いいかい?」と聞かれます。

Are you sure you want to continue connecting (yes/no)?

ですので今回はそれを回避してみたいと思います。

設定方法

ansible.cfgに以下のように設定します。

ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no

重要なのはStrictHostKeyChecking=noの箇所です。
これを設定すると、新規ホスト(~/.ssh/known_hostsに記載のないホスト)に接続する際に確認をしないようにしてくれます。

おわりに

セキュリティ的には「接続するかい?」と聞かれるほうが正しいのですが、大量のホストが作成/削除を繰り返すようなImmutableなインフラを構築していたり、Ansibleの実行を自動化して裏で動かしていたりすると、そこで処理が止まったりしてしまいます。

そういうときはこの設定をいれることを検討してもよいかもしれません。

Infrastructure as Code ―クラウドにおけるサーバ管理の原則とプラクティス

Infrastructure as Code ―クラウドにおけるサーバ管理の原則とプラクティス

AnsibleでAnsibleをインストールする

概要

AnsibleでAnsibleをインストールします。
なんとAnsibleを実行するだけでAnsibleをインストールすることができます。

playbook

rpmをwgetしてきて、epelリポジトリを追加して、yumでAnsibleを実行しています。

おわりに

おわれ

Ansible実践ガイド 第2版 (impress top gear)

Ansible実践ガイド 第2版 (impress top gear)

Pythonで引数をランレングス符号化する

趣味と実益を兼ねてPythonでランレングス符号化(圧縮)するスクリプトを書きました。

スクリプト

こんなかんじ。

#実行結果
こんなかんじで利用できます。

$ ./run_length.py aaabbbbbcccdddefffgggggh

a3b5c3d3e1f3g5h1

おわり

おわれ

Python 1年生 体験してわかる!会話でまなべる!プログラミングのしくみ

Python 1年生 体験してわかる!会話でまなべる!プログラミングのしくみ

AnsibleでCentOSにAWSCLIをオフラインインストールする

概要

Ansibleを利用してCentOSにAWSCLIをオフラインインストールしてみます。

playbook例

ちょっとした制限事項と前提

なんらかの方法でAnsibleを実行するサーバにAWSCLIのバンドルされたインストーラを格納する必要があります。

↓これ
https://s3.amazonaws.com/aws-cli/awscli-bundle.zip

それを解凍して、files/配下においています。

$ unzip awscli-bundle.zip
$ mv ./awscli-bundle files/.

ちょっとした解説

ターゲットノードにバンドルされたインストーラをコピーした後、インストールを実施しています。
インストールの実行はbecomeディレクティブを利用してrootユーザで実行しています。

おわりに

制限事項を解消したいなぁ…

入門Ansible

入門Ansible

Ansibleでwhenをつかってエラーハンドリングしてみる

概要

whenディレクティブを利用してAnsibleのplaybookでエラーハンドリングしてみます。

playbook

playbookはこんなかんじです。
copyの結果をもとにwhenでエラーハンドリングしています。

ちょっとした解説

3行目のcopyを実行し、4行目のregister: resultでその結果を取得しています。
5行目のignore_errors: Trueはエラーとなっても処理をつづける記載です。
エラーハンドリングしたいのにそこでAnsibleが終了してしまっては意味ないので記載しています。

8行目や11行目にあるwhenは条件をみたすときに処理を実行するというディレクティブです。
今回の場合はcopyの結果(result)の値によって判定を行っています。

実行結果

実際に動いているところを見てみます。

コピーの結果ファイルが変更されたとき

copyが実行されてファイル(今回の場合はsasasa.txt)が変更されたときはcopyの成功と変更が行われますので、以下のような感じの実行結果になります。

$  ansible-playbook -i ansible_hosts when.yml 

PLAY [localhost] **********************************************************************

TASK [Gathering Facts] **********************************************************************
ok: [localhost]

TASK [copy] **********************************************************************
changed: [localhost]

TASK [debug] **********************************************************************
ok: [localhost] => {
    "msg": "成功したよ(succedded)"
}

TASK [debug] **********************************************************************
skipping: [localhost]

TASK [debug] **********************************************************************
ok: [localhost] => {
    "msg": "変更したよ(changed)"
}

TASK [debug] **********************************************************************
skipping: [localhost]

PLAY RECAP **********************************************************************
localhost                  : ok=4    changed=1    unreachable=0    failed=0   

成功と変更の旨のメッセージが出力されていることがわかります。

コピーしてもファイルに変化がなかったとき

続けざまにもう一度実行するとファイルの内容は同じでchangedにはなりませんので、成功した旨のメッセージだけが出力されます。

$  ansible-playbook -i ansible_hosts when.yml 

PLAY [localhost] *************************************************************************************

TASK [Gathering Facts] *******************************************************************************
ok: [localhost]

TASK [copy] ******************************************************************************************
ok: [localhost]

TASK [debug] *****************************************************************************************
ok: [localhost] => {
    "msg": "成功したよ(succedded)"
}

TASK [debug] *****************************************************************************************
skipping: [localhost]

TASK [debug] *****************************************************************************************
skipping: [localhost]

TASK [debug] *****************************************************************************************
skipping: [localhost]

PLAY RECAP *******************************************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0   

コピーが失敗したとき

コピーするファイルが存在しなかった場合にはcopyは失敗(failed)となりますので以下のような動きになります。

$  ansible-playbook -i ansible_hosts when.yml 

PLAY [localhost] *************************************************************************************

TASK [Gathering Facts] *******************************************************************************
ok: [localhost]

TASK [copy] ******************************************************************************************
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: AnsibleFileNotFound: Could not find or access '/home/ec2-user/wawawa.txt2'
fatal: [localhost]: FAILED! => {"changed": false, "msg": "Could not find or access '/home/ec2-user/wawawa.txt2'"}
...ignoring

TASK [debug] *****************************************************************************************
skipping: [localhost]

TASK [debug] *****************************************************************************************
ok: [localhost] => {
    "msg": "失敗したよ(failed)"
}

TASK [debug] *****************************************************************************************
skipping: [localhost]

TASK [debug] *****************************************************************************************
skipping: [localhost]

PLAY RECAP *******************************************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0 

コピーがスキップされたとき

例が思いつかなかったけど以下のような動きになると思います。

$  ansible-playbook -i ansible_hosts when.yml 

PLAY [localhost] *************************************************************************************

TASK [Gathering Facts] *******************************************************************************
ok: [localhost]

TASK [copy] ******************************************************************************************
ok: [localhost]

TASK [debug] *****************************************************************************************
ok: [localhost] => {
skipping: [localhost]
}

TASK [debug] *****************************************************************************************
skipping: [localhost]

TASK [debug] *****************************************************************************************
skipping: [localhost]

TASK [debug] *****************************************************************************************
ok: [localhost] => {
    "msg": "しなかったよ(skipped)"
}

PLAY RECAP *******************************************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0   

おわりに

Ansibleでエラーハンドリングをやってみました。
基本的には各タスクはすべて正常であるべきだと思いますが、異常な値がかえってくる可能性がある処理をコントロールしない場合にはこのようにやってみるといいとおもいます。

入門Ansible

入門Ansible

AnsibleのGathering Factsを実行しないようにする

今回はansible-playbookを実行するときに毎回実行されるGathering Factsを実行しないように設定してみたいと思います。
(意外と実行に時間がかかってるようなきがするので)

そもそもGathering Factsってなにやってんの?

ターゲットノードのメタデータ(IPアドレスからCPUやディスクの情報)を取得してくれています。
ちなみにこの取得したデータのことをファクト変数といいます。

設定方法

設定する方法はかんたんです。
playbookに以下のように設定してあげるだけ

gather_facts: no

デフォルトではgather_facts: yesと設定されているのと同じですので明示的にnoと設定してあげます。

動作を見てみる

こんなかんじの超単純なplaybookを実行してみます。

gather_facts_no.yml

- hosts: localhost
  gather_facts: no

実行結果

Gathering Factsが実行されていないことがわかります。

$ ansible-playbook -i ansible_hosts gather_facts_no.yml

PLAY [localhost] *******************************************************************************************************

PLAY RECAP *************************************************************************************************************

補足: Gathering Factsの実行時間検証

gather_factsの実行ありなしをtime`コマンドで実行時間を比較してみる。
だいたいこんなかんじ。

gather_facts: yes

real 0m1.690s
user 0m1.312s
sys  0m0.076s

gather_facts: no

real 0m1.036s
user 0m0.960s
sys  0m0.056s

まあ微々たるものですね…

おわりに

確実にファクト変数をつかわないのであればgather_facts: noに設定したほうがいいんじゃないかなぁとは思います。

入門Ansible

入門Ansible