【Ansible🤢🤮】Python😚のリストや辞書を使って変数宣言してみた
【結論】
Ansibleの強みを活かせない案件に参画しているせいで、Ansible🤢🤮になった人が書いたブログです。
Ansibleでも、リストやキーバリュー形式で変数を宣言し動的に切り替えることは可能。
【目次】
はじめに
以前、次のようなブログを書きました。
ブログを書いた当時はAnsible🤢🤮について詳しくなくて、💩コードしか書けませんでした。
しかし、Ansible🤢🤮でもリストやキーバリュー形式で変数を宣言して使うことできることが分かったので、備忘録程度に載せておきます。
やりたいこと
現在、Ansibleでホットスタンバイ方式で構成された機器への設定を行うプレイブックを開発しています。
制御対象の機器は、Active状態とStandby状態が自動で切り替わる仕様です。
よって、設定を行う前に、現在どちらがActive状態にあるかを判断して、接続先を分岐する必要があります。
この処理をフローで表すと下図のようになります。
引用:過去の自分😊
辞書型を使った場合
【Python😚で書いた場合】
SERVER_INFO_DIC = { "HOST1":{ "IP": "111.111.111.111", "USERNAME": "admin_1", "PASSWORD": "hoge_1", }, "HOST2":{ "IP": "222.222.222.222", "USERNAME": "admin_2", "PASSWORD": "hoge_2", }, } # 仮で変数設定 # 本番では1系と2系より情報しActive機器を判定する関数を呼び出す active_host_num = 1 active_host_name = f"HOST{active_host_num}" print(SERVER_INFO_DIC[active_host_name]["IP"]) print(SERVER_INFO_DIC[active_host_name]["USERNAME"]) print(SERVER_INFO_DIC[active_host_name]["PASSWORD"])
【Ansible🤢🤮で書いた場合】
--- - hosts: localhost # 自分自身に接続する tasks: - name: 接続先情報の定義 set_fact: SERVER_INFO_DIC: HOST1: IP: "111.111.111.111" USERNAME: "admin_1" PASSWORD: "hoge_1" HOST2: IP: "222.222.222.222" USERNAME: "admin_2" PASSWORD: "hoge_2" # 仮で変数設定 # 本番では1系と2系より情報しActive機器を判定する.ymlを呼び出す - set_fact: active_host_num: 1 - set_fact: active_host_name: "{{ 'HOST%d' | format(active_host_num) }}" - name: Active機器の情報を取得 set_fact: ip: "{{ SERVER_INFO_DIC[active_host_name].IP }}" username: "{{ SERVER_INFO_DIC[active_host_name].USERNAME }}" password: "{{ SERVER_INFO_DIC[active_host_name].PASSWORD }}" - debug: msg: "ip:{{ip}} username:{{username}} password:{{password}}"
リストを使った場合
【Python😚で書いた場合】
SERVER_INFO_LIST= [ { "IP": "111.111.111.111", "USERNAME": "admin_1", "PASSWORD": "hoge_1", },{ "IP": "222.222.222.222", "USERNAME": "admin_2", "PASSWORD": "hoge_2", } ] # 仮で変数設定 # 本番では1系と2系より情報しActive機器を判定する関数を呼び出す active_host_num = 2 active_host_num -= 1 print(SERVER_INFO_LIST[active_host_num]["IP"]) print(SERVER_INFO_LIST[active_host_num]["USERNAME"]) print(SERVER_INFO_LIST[active_host_num]["PASSWORD"])
【Ansible🤢🤮で書いた場合】
--- - hosts: localhost # 自分自身に接続する tasks: - name: 接続先情報の定義 set_fact: SERVER_INFO_LIST: - { IP: "111.111.111.111", USERNAME: "admin_1", PASSWORD: "hoge_1", } - { IP: "222.222.222.222", USERNAME: "admin_2", PASSWORD: "hoge_2", } # 仮で変数設定 # 本番では1系と2系より情報しActive機器を判定する.ymlを呼び出す - set_fact: active_host_num: 1 - set_fact: active_host_num: "{{ active_host_num - 1}}" - debug: msg="{{active_host_num}}" - name: Active機器の情報を取得 set_fact: ip: "{{ SERVER_INFO_LIST[active_host_num|int].IP }}" username: "{{ SERVER_INFO_LIST[active_host_num|int].USERNAME }}" password: "{{ SERVER_INFO_LIST[active_host_num|int].PASSWORD }}" - debug: msg: "ip:{{ip}} username:{{username}} password:{{password}}"
さいごに
Ansible🤢🤮でキーバリューやリストが使えるのを知った時は感動しました。
しかし、この感動を差し置いても今後Ansible🤢🤮を使った案件への参画は全力で回避したいと思います。
ブログを120日間毎日投稿した😤と言いたかった。。。
【結論】
「会社」と「毎日ブログ投稿」の圧には耐えきれませんでした。
自己解釈としては、断念ではなくゴールの変更という認識。
【目次】
はじめに
「ブログを120日間毎日投稿した😤」という勲章が欲しくて毎日ブログを書いてきました。
が、辞めます。
毎日投稿を辞める理由
未経験からWebエンジニアになって毎日ブログを書いている同い年の人間を知っています。
そんな中で、色々理由を書いても言い訳がましく聞こえてくるので一言だけ。
「仕事と毎日ブログ投稿の両方のプレッシャーは、私には耐えられませんでした。」
ブログはどうするの?
毎日ブログ投稿は断念しましたが、ブログ投稿自体は定期的に続けます。
なぜなら、ITエンジニアとして食べていくための必須能力である、「情報を理解して、整理して、正確に伝達する能力」が私は圧倒的に足りていないからです。
この能力を鍛えるための手段として、ブログが一番有効だと考えているからです。
断念するの?
「毎日ブログ投稿を辞める」という行動の、「辞める」だけにフォーカスを当てると、
断念や挫折などネガティブな出来事として捉えてしまいます。
せっかくここまで頑張ってきた行動を、ネガティブ事として捉えるたくはありません。
よって、「自分の限界を知るいい機会だった」と前向きに捉えたいと思います。
そして、「ブログを120日間毎日投稿した😤」という勲章が取れなかった件に関しては、「ブログをN回投稿した😤」と言い換えて、N回が「120日間毎日投稿」と同等レベルになるまで、気長に積み重ねていこうと思います。
最後に
学生時代に、授業時間内に作文を書き終えることができなくて、徹夜してなんとか作文を書いていた私が、
ブログ投稿を78日間毎日続けれたことに関しては、素直に自分を褒めたいです。
浮動小数点数とは?
【結論】
- 0.0025というように、小数点の位置を固定して値を表現する方法を固定小数点という。
- これに対して、浮動小数点では0.0025を0.25×0.01(10のマイナス3乗)と表現する。
- 浮動小数点は固定小数点と比較すると、同じ情報量でより小さな数字を表現することができる。
【目次】
[TOC]
はじめに
学生時代に国試の勉強をしていた時期がある私にとって、浮動小数点という考え方には全く新鮮さを感じません。心が動かないのでブログにまとめる気力も全く湧きません。
にも関わらずブログのネタとして取り上げたのは、作文力を鍛えるためです。
https://wa3.i-3-i.info/word14959.html
固定小数点とは?
10.0や10.05の様に値を表現する際の小数点の位置を常に固定にして表現する方法です。
固定小数点はそれほど小さくない数字を表現する際には分かりやすいです。
しかし、0.000025の様な小さな数字を表現する際は分かりにくい上に、0を表示するのに桁数を消費するため表現できる数字に制限があります。
浮動小数点とは?
小さな数字を分かりやすく、かつ効率よく表現するための方法です。
同じ値を固定小数点と浮動小数点で表現すると下表のようになります。
(下表の^
はべき乗を表す記号です)
固定小数点 | 浮動小数点 |
---|---|
0.025 | 0.25×10-2 |
10 | 0.1×102 |
10.5 | 0.105×102 |
上記表で示す通り、浮動小数点では0.xxxとなる様に10のべき乗をかけてあげることで、元の値から小数点の位置が移動することから浮動小数点と呼ばれます。
浮動小数点で表現する事で、0.000025を0.25×10-4とコンパクトに表現することができます。
メリットとしては、固定小数点と比較した時に同じ情報量でより小さな数を表現できます。
デメリットとしては、2つの数値の差をとった時に値の差が殆どなかったり、逆にあったりした時に計算結果を浮動小数点で表現できなくなり誤差となってしまう可能性がある事です。
参考情報
https://wa3.i-3-i.info/word14959.html
さいごに
今までのブログは、興味があることを勉強していたので書きやすかったのですが、国試の勉強になると用語の羅列ばかりで全く興味が湧かないからブログにまとめるのがツライ。。
MacにGo言語をインストールする方法
【結論】
- ちょっとGo言語を試したいだけなら、ここで十分。
はじめに
質問:なぜGo言語をインストールしたんですか?
答え:実行したいソースがGo言語で書かれていたからです。
インストール
$ brew install go
初期設定
Goの作業場所として$GOPATH
を設定する必要があります
公式の標準は$HOME/go
なので、従うことにします。
私はbash
を使っているため、~/.bash_profile
の末尾に次の記述を追加します。
export GOPATH=${HOME}/go export PATH=$GOPATH/bin:$PATH。
作業ディレクトリの作成
Goのルールに従って標準のディレクトリを作成します。
$ mkdir $GOPATH $ cd $GOPATH $ mkdir src pkg bin
mkdir
で作成したディレクトリの役割は次のようになります。
- bin → 実行ファイルを置く
- pkg → パッケージを置く
- src → ソースファイルを置く
HerroWorldを出力してみる
src直下にhello.goを作成し、下記のコードを書きます。
package main import "fmt" func main() { fmt.Printf("Hello, world.\n") }
Goの実行はrunコマンドで行います。
$ cd $GOPATH/src $ go run hello.go
補足
$GOPATH
に設定したパスで作業する制約は、githubとの連携してソースを管理する際の制約のようです。
$GOPATH
以外の場所でも普通に実行できたのことから、ローカルでソース動かすだけであれば制約はないようです。
参考
Go言語の開発環境構築(Mac + SublimeText3)
さいごに
自分のPCにGo言語の開発環境インストールしてあったんだ😯
と、このメモを見つけた時に思いました💦
IoT向け通信プロトコルのMQTTとは?
【結論】
- MQTTは通信プロトコルの一つで、パブリッシュ/サブスクライブ方式を採用している。
- MQTTでは送受信するデータをトピックと呼ぶ。
- MQTTは、現実世界の新聞の配達方式を採用した通信方式である。
- 新聞社(送信する機器)が新聞(トピック)を発行(パブリッシュ)し、新聞(トピック)を読みたい人(トピックを受信したい機器)が購読(サブスクライブ)する。
【目次】
- はじめに
- MQTTとは
- パブリッシュ/サブスクライブ(PubSub)モデルを採用している。
- マシン側では接続先のマシンについての考慮が不要になる。
- データ通信はバイナリ形式で行うため、通信量が少ない。
- 通信品質(QoS)の設定を0,1,2の三段階で設定できる。
- パブの後からサブした人にも届けるRETAIN機能がある。
- サブスクライバの突然死を監視するWill機能がある。
- 参考情報
- さいごに
はじめに
以前、転職活動時のポートフォリオとして、LINEへのメッセージ送信でエアコンを制御するシステムを作成しました。下図はその際に書いたシーケンス図です。
スマホからエアコンは制御できないので、スマホ→LINE→AWS→RasberryPi→エアコンの流れで制御するようにしています。
動くものを作って「やったー!!」で終わってはもったいないので、ブログのネタにします。
と言っても、一気に全部ネタにすると尽きてしまうため、今回はAWSとRaspberryPi間で通信する際に使用するMQTTプロトコルについて書いていきます。
MQTTとは
Message Queue Telemetry Transportの略で、1999年にIBMとEurotech社によって作られ始めた通信プロトコル。TCP/IP上で使われることを想定しており、インターネットを介したマシン間通信や、マシンと別のインターネット上のリソースとの通信を行うことに特化している。
パブリッシュ/サブスクライブ(PubSub)モデルを採用している。
データを送信(パブリッシュ:発行)する側をパブリッシャ、データを受信(サブスクライブ:購読)する側をサブスクライバと呼ぶ。データはトピックという単位で扱われ、サブスクライバは受信したいトピックをサブスクライブ(購読)することで、パブリッシャがそのトピックにパブリッシュ(発行)したデータを受け取ることができる。
マシン側では接続先のマシンについての考慮が不要になる。
パブリッシュ/サブスクライブモデルでは、マシンとマシンの間に仲介役のブローカ(実態はサーバ)がいて、トピックの管理やサブスクライバ/パブリッシャとなるクライアントの接続管理している。マシン側では接続先のマシンは気にせず、ブローカが管理するトピックに対してデータをパブリッシュ/サブスクライブすることだけを考えればいい。
データ通信はバイナリ形式で行うため、通信量が少ない。
同じデータをHTTP通信で送る時と比較すると通信料が少ないようです。
本当は実際にPCで動かしてみたかったのですが今回はスルーします。
通信品質(QoS)の設定を0,1,2の三段階で設定できる。
QoS0:メッセージ到達は最大で1回、届かなかったとしても再送しない。
QoS1:メッセージ到達は少なくとも1回は保証するが重複する可能性もある。
QoS2:メッセージ到達は1回だけ、重複もなく確実に1回送る。
パブの後からサブした人にも届けるRETAIN機能がある。
トピックをサブスクライブ(購読)すると、基本的にはそれ以降にパブリッシュ(発行)されたトピックに対しては、データを受け取ることができるが、サブスクライブする前にパブリッシュされたデータは受け取れない。
RETAIN機能を有効にすると、そのトピックに対してパブリッシュされたデータの最新の1件だけMQTTブローカが保持してくれる。
サブスクライバの突然死を監視するWill機能がある。
Willとは「遺言」の意味で、サブスクライブする際に、Will用のトピックへ遺言メッセージを残すことができる。Willを設定したサブスクライバは、ブローカとの通信が途切れると、遺言メッセージがWillトピックに対して自動的にパブリッシュされます。このWillトピックを、例えばシステム管理者のような役割のアプリケーションがサブスクライブすることで受け取り、今ちゃんと生きているサブスクライバを一元管理できます。
参考情報
http://devcenter.magellanic-clouds.com/learning/mqtt-spec.html
http://public.dhe.ibm.com/software/dw/jp/websphere/wmq/mqtt31_spec/mqtt-v3r1_ja.pdf
さいごに
底無し沼にハマったみたいにやる気がでないけど、ブログ更新したいから昔まとめたメモを引っ張り出してきました。
【Ansible】🤢🤮
【結論】
- Ansibleでは別フィルを呼び出すことで、関数呼び出し的なことをできる。
- ただし、引数や戻り値を渡す方法はないため、全てグローバル変数でやり取りする。
- 結果、現場のエンジニアが「動いているのも不思議」とぼやくレベルの💩コードが出来上がる。
【目次】
はじめに
現在、Ansibleでホットスタンバイ方式で構成された機器への設定を行うプレイブックを開発しています。
制御対象の機器は、Active状態とStandby状態が自動で切り替わる仕様です。
よって、設定を行う前に、現在どちらがActive状態にあるかを判断して、接続先を分岐する必要があります。
この処理をフローで表すと下図のようになります。
1系と2系の状態によって設定先を変更する処理を、Ansibleで書くためにかなりの時間を溶かしてしまったため、自戒の念を込めてブログにまとめました。
Pythonで書いた場合
接続先情報を事前に定義しておき使い回しています。
#接続先情報の定義 SERVER_INFO = [ { "ip": "111.111.111.111", "username": "admin_1", "password": "hoge_1" },{ "ip": "222.222.222.222", "username": "admin_2", "password": "hoge_2" } ] #接続先情報よりActive機器のIDを取得 active_num = check_active_server(SERVER_INFO) #Active機器の接続情報を表示 print(SERVER_INFO[active_num]["ip"]) print(SERVER_INFO[active_num]["username"]) print(SERVER_INFO[active_num]["password"]) #Active機器へ設定を行う(省略)
上記処理を、以下のように実装しているPythonプログラマーはいないと思いますが、もしいたとしたら次の理由により、淘汰されるべきだと思っています。
- 辞書やリストを使ってデータ構造を定義していない。
- 関数を呼び出す際に引数や戻り値を使わず、全てグローバル変数を介してやり取りしている。
#接続先情報の定義 SERVER_1_IP = "111.111.111.111" SERVER_1_USERNAME = "admin_1" SERVER_1_PASSWORD = "hoge_1" SERVER_2_IP = "222.222.222.222" SERVER_2_USERNAME = "admin_2" SERVER_2_PASSWORD = "hoge_2" server_ip = "" server_username = "" server_password = "" active_num = -1 # 接続先情報よりActive機器のIDを取得 # 引数や戻り値はグローバル変数を直接参照する。 check_active_server() if active_num == 1: server_ip = SERVER_1_IP server_username = SERVER_1_USERNAME server_password = SERVER_1_PASSWORD if active_num == 2: server_ip = SERVER_2_IP server_username = SERVER_2_USERNAME server_password = SERVER_2_PASSWORD #Active機器の接続情報を表示 print(server_ip) print(server_username) print(server_password) #Active機器へ設定を行う(省略)
Ansibleで書いた場合
同じ処理をAnsibleで書くと次のようなイメージになります。
※あくまで、イメージを掴むためのソースであるため、動作検証しておらず間違っている可能性があります。
--- - hosts: localhost # 自分自身に接続する tasks: - name: 接続先情報の定義 set_fact: SERVER_1_IP: "111.111.111.111" SERVER_1_USERNAME: "admin_1" SERVER_1_PASSWORD: "hoge_1" SERVER_2_IP: "222.222.222.222" SERVER_2_USERNAME: "admin_2" SERVER_2_PASSWORD: "hoge_2" - name: 接続先情報よりActive機器のIDを取得 import_tasks: check_active_server.yaml - name: 1系がActiveの場合 set_fact: server_ip: "{{ SERVER_1_IP }}" server_username: "{{ SERVER_1_USERNAME }}" server_password: "{{ SERVER_1_PASSWORD }}" when: active_num == 1 - name: 2系がActiveの場合 set_fact: server_ip: "{{ SERVER_2_IP }}" server_username: "{{ SERVER_2_USERNAME }}" server_password: "{{ SERVER_2_PASSWORD }}" when: active_num == 2 # Active機器の接続情報を表示(省略) # Active機器へ設定を行う(省略)
Ansibleでは複雑なデータ構造は定義できないため、冗長なコードでデータ定義を実装する方法しかないようです。
import_task
を用いて別ファイルを読み出すことで、Pythonの関数呼び出しと同じような処理を実装することができます。
しかし、引数や戻り値を受け渡す方法はないため、set_fact
を使ってグローバル変数へ値を格納することで、擬似的に引数の受け渡しを実装しています。
さいごに
1ヶ月ほどAnsibleで開発して得た情報と、現場で活躍しているAnsibleエンジニアの話を聞いた限りでは、「AnsibleではPythonだと🤢🤮レベルの💩コードしか書けない。」という結論に至ってしまいAnsibleアレルギーになりそうです。
Ansibleアレルギーにならないための対策として「Ansible Night in Tokyo」に参加して、Ansibleラブなエンジニアに洗脳されてきます。
VLANという単語について調べてみた。
【結論】
【目次】
はじめに
下図のようにA〜Eの5台のPCをハブを介して通信できるネットワーク構成をLAN(Local Area Nettowork)といいます。
これをA,B,CとD,Eの2つに分けたい場合、下図のようにハブをもう一台追加する必要があります。
しかし、上記構成だと分けたいグループの数だけハブが必要になる上に、グループ構成が変わる度に物理的にケーブルを抜き差しする必要があります。
これを、ハブで通信制御を行うことで仮想的にグループ分けしたLAN構成をVLANといいます。
下図では物理的には一つのハブに接続されていますが、通信制御を行うことでA、B、CとD、Eの2つのグループに分けています。
通信制御は、送信元と送信先の許可有無が記載された表に従って行われます。
下表ではAからB,Cへの送信は許可するが、AからD,Eへの通信を拒否すること表します。
このように、B,C,D,Eに関しても同じように設定することで通信制御を行えます。
番号 | 送信元 | 送信先 | 通信許可 |
---|---|---|---|
1 | A | B、C | 許可 |
2 | A | D、E | 拒否 |
3 |
VLANではどの情報を元に通信許可・拒否を設定するかによって次のような手法があります。
参考情報
https://wa3.i-3-i.info/word12084.html
さいごに
VLANとスイッチングハブの違いは?
VLANタグって何?
とブログ書いてて気になるところはありましたが、ひとまずスルーします。
毎日ブログを書くには、「欲張りすぎないこと。」と「時間を決めて理解できた範囲でブログにまとめること。」が大事だと、7/27(土)に7/25(木)のブログを書いてて思いました。