[go: up one dir, main page]
More Web Proxy on the site http://driver.im/

彩り

私の作業が誰かの役に立つといいな。IT系のTech記事中心です。

Ansibleの便利さを伝える時に考えたこと

これは Ansible Advent Calendar 2024 の16日目の記事となります。
毎年この時期にしかブログ書いていないのに、公開遅くなりました。

はじめに

今年は人生初の転職をしたのですが引き続きAnsibleとは業務でも関わりを持てて嬉しい限りです。
毎年このブログではその年のAnsibleとの関わりを振り返ったりまとめたりしている気がします。新しいチャレンジとなる担当プロダクトの「やってみた」系を書こうと思ったのですが、少しポエム的なエントリになりました。
11月に新しい環境でも登壇する機会を得ることができまして、「ZabbixとAnsibleを組み合わせるとこんな便利なことができるよ」という内容を話しました。
自ら手を挙げたものの、私過去を振り返っても「Ansibleと担当製品を使って、 更に こんなことができるようになります」といった発表が多く、Ansible自体の良さを伝えるという経験は実はあまりないなぁ、むしろ「うん、うん」と聞いている側だな。という事に途中で気付き、どういう話しをすればAnsibleの便利さをAnsibleをあまり知らない人に伝えられるかな、という事を改めて考える事がありました。

なのでその時どういう風に考えたのかを少し振り返ってみたいと思います。(当然担当製品の事もたくさん考えましたが、このエントリではその成分は控えめです)

自分は何を語れるか

便利を伝える時には当然比較をして、これまでは○○だけどAnsibleを使うと◻︎◻︎となる!という伝え方がいいのだろうと考えた訳ですが、何と比較をするのがいいのかとても悩みました。

  • 手動オペレーションと自動オペレーション

これはある意味鉄板というか冒頭にAnsibleとは、を語る部分で簡単に触れました。
でもこの「手動オペレーション」と「自動オペレーション」を比較していくって結構難しいなと思ったんですよね。自分のバックボーンは開発なので構築・運用という分野の経験が絶対的に少ない・浅いというのが根本にあるのですが、よく聞く「手動だとX人でY分掛かる作業がAnsibleを使うとなんとこんなに早く!簡単に!」みたいな説明の方がきっと聞いている方にはしっくりくるのだろうなー、と思ったのですが自分にはそれは語れませんでした。
登壇・講演、私好きな方ですけど心掛けている事としては背伸びをせず、自分の言葉で語れること、本当に思っている事をスライドにして話したいと思っています。
なので、どういう比較をするとわかりやすいか、そして自分の言葉で伝えられるのか、この部分はだいぶ悩みました。

  • 分野によって異なる比較

Ansibleを使う分野によってこの比較は異なると思うので、自分の経験した事からまずは考えてみました。
ネットワーク運用では主にネットワーク機器の設定変更が運用の作業となり、その為の手順書(これまではExcelとかテキストとか)があって、これをPlaybookに置き換えられます、と。
さらにPlaybookをGitで管理すればGitオペレーションドリブンな運用で世代とか変更理由も管理できます、となるので従来オペレーションと比較した時に、
「おっ、これいいじゃん!」
となるような気がします、自分も聞いていて絶対そう思うだろうなと。

サーバー運用もほぼ同じでしょうか、これまで手順書としてCLIコマンドを管理していたのがPlaybookに置き換わる、これもイケてる気がします。

  • Zabbix だとそれは何になるのか

という事で今回の題材となるZabbixですが、どういう比較をすると聴講する方に刺さるのか、結構悩みました。
Zabbix自体の構築とかバージョンアップを取り扱っても良かったのですが、なんせ構成要素と選択肢が多いので参考例としては非常に複雑になってしまう気がしました。
監視項目の設定変更は運用中に行うと思いますが、そうなるとGUIオペレーションとPlaybookの比較になってしまうなーと、、、悩みました。

  • APIとPlaybook

ZabbixはAPIを持っていて、APIを使ったスクリプト作成は業務でも行なっていました。聴講する方もAPIには興味があったりスクリプトは作った事がある方が多そうな雰囲気でしたので特定のオペレーションを行う際に、API(を使ったスクリプト)とPlaybookを比較するのがいいかな、という事でこの比較を講演資料では「Ansibleを使った時に便利と思ってもらえるようなポイント」としました。
自分が経験している事で、かつ 聴いている方もわかる事
この2つがたまたま合致したものが見つかって良かったのですが、他にどんな比較をしたらより便利さが伝わったかな、とまだ考えたりします。

API(を使ったスクリプト)とPlaybookの比較

ここからは実際に講演内容で書いた事になるのですが

PythonでZabbix用APIを使ったコマンド
同じ事をPlaybookで実現する場合

これを監視対象ホストの追加
という一番単純な作業で比較してかつAnsibleの特徴を語っていこう、という事で

  • Inventryに書き足すだけで簡単に複数ホストに同じオペレーションを実行できる
  • 特定の設定項目を簡単に変数として扱える
  • 設定が実際に投入できたのかを確認できる(冪等性の部分)
  • AnsibleモジュールがZabbixのバージョンアップに追従してくれるからメンテナンス製良いという話(APIに変更あった場合の話)

を語り、実際にこれをAPIで自分で書こうとすると大変ですよね?(特に冪等性の部分、コンフィグ投入前後の状態を保持して比較しないとできない、それってプログラムで実現しようとすると大変ですよね)
みたいな事を語りました。
実際大変ですもんね。

という事でできた資料

https://assets.zabbix.com/files/events/2024/conference_japan_2024/1121_1330_Zabbix.pdf

来年やりたいなと思っている事

community.zabbix , zabbix.zabbix

Zabbix用のAnsibleモジュールって世の中大半の方はcommunity.zabbixを使っていると思うのですが、Zabbix社製としてzabbix.zabbixでもモジュール公開しているんですよね。
来年はこの辺りを検証したいなって思っています。

community.zabbixのRole

community.zabbixのアップデート情報見ると、Roleのメンテナンスを凄いこまめに行なっているんですよね。このRoleにはZabbixの構築とかAgentのインストールとかバージョンアップもあるのでこれも検証したい!

モジュール開発

担当製品変われど経験は活かせるはず、という事でAnsibleモジュールのメンテナンスはチャレンジしたいと思っています。
今年のアドカレで参考になる情報いっぱいありますね👀👀

参考

本発表をした後に、素敵な出会いもあったりしました。
一歩踏み出して、手を挙げてみて、アウトプットしてみて、懇親会とかで繋がりが広がるっていつでも刺激的ですよね。 Zabbixは毎年グローバルカンファレンスが行われているのですが、今年はそこでcommunity.zabbixのメンテナーの方の発表があったようです。(その出会った方から教えてもらった)

内容見て
「あ、やっぱりZabbixの場合はAPIとPlaybookの比較になりますよねー」
「あ 確かにAPIだとid指定だけど、Ansibleモジュールだとname指定で動いたな(モジュール、ユーザーの利便性の為に凄く頑張ってるな、、言えば良かった)」
と、思いました。

最後に

本当はzabbix.zabbixの検証記事でも書こうかと思っていたのですが振り返りポエムのようなエントリになってしまいました。
来年も頑張っていきたいと思います。

ではでは
Happy Monitoring and Happy Automation♪

galaxy-importerについて

これは Ansible Advent Calendar 2023 の16日目の記事となります。
毎年この時期にしかブログ書いてないです、来年は沢山ポストしたいな。

はじめに

今年は夏位に2ヵ月程Ansibleの作業を行いまして、その際に galaxy-importer というツールを利用する機会がありました。当時(本記事作成している 2024/12月時点も)このツールの使い方は公式情報(GitHub)しかなくて色々と苦労したので使い方や用途を少し共有しようと思います。
AnsibleGalaxyやAutomationHubにモジュールをアップロードする方は覚えておくとよいツールだと思います。
※公式ドキュメントもそこまで詳細にないので、認識の誤りなどあったらごめんなさい。

galaxy-importer概要

  • AnsibleGalaxyやAutomationHubにモジュールをアップロードする際に内部で実行されるテストの実体
    • ansible-test sanity とか ansible-lint を実行
  • コマンド単体+コンテナ(podman, docker)環境で動かすことができる
  • コンフィグファイルに指定する事で、AutomatinHubにアップロードする際のテストと同等の内容も行う事が出来る

概要はこんな感じと理解しています。
モジュールを作成してAnsibleGalaxyにアップロードしたいけど、アップロード時に行われるテスト結果をまずは手元で確認したい。
という用途で使えるツールです。

普通に ansible-test などのコマンドを実行するより便利なところ

  • 後述のテストオプションや結果を見てわかる通り
    • 様々なPython環境でテストしてくれる
    • ansible-test , ansible-lint , ansible-doc など個別のコマンドをまとめて実行してくれる
    • 実施にAnsibleGalaxyやAutomationHubにアップロードする際のテストが行える

が非常に良い所だと思っています。

使い方

環境構築

  • venv環境で galaxy-importer を動かす環境を用意
   (py39_galaxy-importer) [nakayama@test]$ pip install galaxy-importer
  • テスト実行環境として、Docker or podman を用意する。

usage

  (py39_galaxy-importer) [nakayama@test]$ python -m galaxy_importer.main --help
  usage: main.py [-h] [--git-clone-path GIT_CLONE_PATH] [--output-path OUTPUT_PATH] [--print-result] [--legacy-role] [--namespace NAMESPACE] [file]

  Run importer on collection and save result to disk.

  positional arguments:
    file                  artifact to import

  optional arguments:
    -h, --help            show this help message and exit
    --git-clone-path GIT_CLONE_PATH
                          git directory with collection that will get built
    --output-path OUTPUT_PATH
                          path where built collection will be stored
    --print-result        print importer result to console
    --legacy-role         import a legacy role rather than collection
    --namespace NAMESPACE
                          namespace of the legacy role to import
  (py39_galaxy-importer) [nakayama@test]$ 

configファイル

  • 公式GitHubConfiguration 部分にも記載されていますが、GALAXY_IMPORTER_CONFIG環境変数でPATHを与える。
  export GALAXY_IMPORTER_CONFIG=/xxxx/xxx/xxxx//galaxy-importer.cfg
コンフィグ例
[galaxy-importer]
LOG_LEVEL_MAIN = INFO
RUN_ANSIBLE_TEST = True
ANSIBLE_TEST_LOCAL_IMAGE = True

default値

公式ドキュメントにもあるように、オプション未指定時はデフォルトで動く。
デフォルト値は こちらの、DEFAULTS = の部分

設定値 DEFAULT 内容 (分かるものだけ)
ansible_local_tmp ~/.ansible/tmp テスト実行時の一時ファイル置き場
ansible_test_local_image False
check_required_tags False
infra_osd False
local_image_docker False テスト環境のコンテナ指定
log_level_main INFO ログレベル指定
require_v1_or_greater False
run_ansible_doc True ansible-doc実行の有無
run_ansible_lint True ansible-lint実行の有無
offline_ansible_lint True
run_ansible_test False ansible-test sanity実行の有無(※)
run_flake8 False
tmp_root_dir None
  • run_ansible_test
    • デフォルト Falseになっている、GalaxyやAutomationHubにアップする際のテストを行う場合はここはTrue
    • Trueにすると、ansible-test sanity が実行されるので、Docker or Podman 環境が必要となる
  • local_image_docker
    • False(Default)
      • podman環境 ansible-test sanity を実行
    • True
      • docker環境で ansible-test sanity を実行

実行例(cisco.ios)

  (py39_galaxy-importer) [nakayama@test]$ python -m galaxy_importer.main  cisco-ios-5.0.0.tar.gz 
  Importing with galaxy-importer 0.4.13
  Getting doc strings via ansible-doc
  Finding content inside collection
  Loading module ios_service
  Loading module ios_l3_interfaces
  :
  (省略)
  :
  Collection loading complete
  Building ContainerFile
  Building image...
  Running image...
  Extracting archive...
  Running 'ansible --version'...
  ansible [core 2.15.0]
  config file = None
  configured module search path = ['/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.9/dist-packages/ansible
  ansible collection location = /.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/bin/ansible
  python version = 3.9.5 (default, Nov 23 2021, 15:27:38) [GCC 9.3.0] (/usr/bin/python3.9)
  jinja version = 3.1.2
  libyaml = True
  Running ansible-test sanity on cisco-ios-5.0.0 ...
  Running sanity test "action-plugin-docs"
  Running sanity test "changelog"
  Running sanity test "compile" on Python 2.7
  Running sanity test "compile" on Python 3.5
  Running sanity test "compile" on Python 3.6
  Running sanity test "compile" on Python 3.7
  Running sanity test "compile" on Python 3.8
  Running sanity test "compile" on Python 3.9
  Running sanity test "compile" on Python 3.10
  Running sanity test "compile" on Python 3.11
  Running sanity test "empty-init"
  Running sanity test "future-import-boilerplate"
  Running sanity test "ignores"
  Running sanity test "line-endings"
  Running sanity test "metaclass-boilerplate"
  Running sanity test "no-assert"
  Running sanity test "no-basestring"
  Running sanity test "no-dict-iteritems"
  Running sanity test "no-dict-iterkeys"
  Running sanity test "no-dict-itervalues"
  Running sanity test "no-get-exception"
  Running sanity test "no-illegal-filenames"
  Running sanity test "no-main-display"
  Running sanity test "no-smart-quotes"
  Running sanity test "no-unicode-literals"
  Running sanity test "pep8"
  Running sanity test "pylint"
  Running sanity test "replace-urlopen"
  Running sanity test "runtime-metadata"
  Running sanity test "shebang"
  Running sanity test "shellcheck"
  Running sanity test "symlinks"
  Running sanity test "use-argspec-type-path"
  Running sanity test "use-compat-six"
  Running sanity test "yamllint"
  ansible-test sanity complete.
  :
  (省略)
  :
  Importer processing completed successfully
  (py39_galaxy-importer) [nakayama@test]$ 

こんな感じですね。 AnsibleGalaxyサイトにモジュールアップロードした方だと、アップロード時に実行されるテストと同じだなーと思うかと思います。

  • podman images(テスト実行後)
    [nakayama@test]$ podman images
    REPOSITORY                                      TAG         IMAGE ID      CREATED         SIZE
    <none>                                          <none>      d5ddca2777a0  53 seconds ago  2.06 GB  ★テスト実行してるコンテナ(終わったら消える)
    quay.io/ansible/default-test-container          7.14.0      a47d0ef8edf2  7 months ago    1.6 GB
    quay.io/ansible/base-test-container             4.1.0       e0fc2e4eb2fd  8 months ago    1.29 GB
    quay.io/ansible/ansible-test-utility-container  2.0.0       846c88fea76d  12 months ago   7.7 MB
    [nakayama@test]$
  • podman ps(ansible-test 実行中)
  [nakayama@test]$ podman ps
  CONTAINER ID  IMAGE                                                             COMMAND               CREATED         STATUS         PORTS       NAMES
  b4b95f37c1fc  d5ddca2777a016ed1f5619e348b24f53c3bfbbf9d352908b13dbe6f025d8355d  LOCAL_IMAGE_RUNNE...  54 seconds ago  Up 54 seconds              focused_chebyshev
  [nakayama@test]$ podman ps

参考:CI環境(GitHubActions)

まとめ

AnsibleGalaxyやAutomationHubにモジュールをアップする際には是非お試し下さい。 あまり情報がない中試行錯誤した情報が多いので、誤っている部分などあったらご容赦を💦 今年はちゃんと技術ネタ書けて良かった。

ではでは

Happy Automation♪

AnsibleFest2022行ってきました

はじめに

本記事はAnsible Advent Calendar 2022 (Qiita/Adventar)の16日目のエントリとなります。

 

今年10月にAnsibleFest2022に現地参加してきました。 

初の海外出張だったのですが、Ansibleモジュールの開発時同様ユーザ会の皆さまが過去残してくれた情報には非常に助けられました。

本エントリでは、

  • 自分が出発前に参考にした過去のAnsibleFestのエントリ
  • 12/13に行われたAnsibleFest2022振り返りイベントでの発表で入りきらなかった内容

について少しまとめてみました。

 

最近Ansible全然触れておらず、テックな内容ではないのですが、、、

先日のユーザ会イベントでは「AnsibleFest2022」の振り返りもありつつ「プロダクト開発とユーザ会、テックイベント」のような側面もあった気がしています。
自分もかなり触発されたので、これからはもっと自分の担当プロダクトも露出させていかねば!と思いました。来年は色々と検証してエントリを公開できればと思っています。

 

 

過去の参加レポート

2018

Ansible Night in Tokyo 2018.12 - connpass

観測する限り日本のユーザ会でAnsibleFestの振り返りを行った最初のイベントでした。

Fest概要とテクニカル目線という2セッションが発表されていました。

この年はAustin開催

  • Certified Module の発表、それに伴うAnsibleGalaxyの拡張
  • ネットワーク自動化の強化

がトピックスとして取り扱われていたようです。

この頃は懐かしきAnsible2.5~2.7位の時期、自分はAnsible2.6から触り始めたような気がする。AWXもまだ羽のようなロゴだった。

2019

Ansible Night in Tokyo 2019.11 - connpass

2019年も同様に報告会イベントが開催されています。

この年は資料がたくさん残っていて非常に助かりました!
行く前は何回も読み返して現地イメージしていました。
2019はAtranta開催!

  • AnsibleCollection、Automation Hub の発表

IBMさんに買収されたのもこの年だったようです。

あと、2019年アドカレでも

あなたがAnsibleFest2020に行く理由&今から準備できること #ansiblejp - 赤帽エンジニアブログ
という会長のエントリがありまして、これも行く前何回も読みましたし、当時このエントリを読んでそのうち参加したいなぁ、と思っていたのを思い出しました。
ちなみに2022は約75万位旅費がかかりましたが、3年前は違ったんだなーと。(40~50万位)

2020

Ansible Night Online 2021.02 - connpass

コロナの影響でオンライン開催になった2020のAnsibleFest

AnsibleNightイベント内で「Ansible Fest2020 recap」セッションがあり、ここで技術トピックスの共有がありました。

  • Private Automathin Hub
  • Ansible Execution Environment/ Ansible Runner/Ansible Builder/Receptor

2021

AnsibleFest 2021 をみんなで観て語る会 - connpass

AnsibleFest 2021 をみんなで観て語る会 #2 - connpass

AnsibleFest 2021 をみんなで観て語る会 #3 - connpass

2021年もオンライン開催、ユーザ会イベントとしてはみんなで同じセッションを観て語る会を3回開催!それぞれ下記のセッションを観たようです。

  • ”Test Driven Development with Molecule”
  • ”Comprehensive Network Automation Testing with Molecule and Cisco CML” 
  • "Integrate ServiceNow & MS Teams in Teams in Ansible Workflows"

 

そして今年(2022)

2022.12.13

そして2022!

ユーザ会イベントは12/13に開催されました。

ansible-users.connpass.com

 

イベント概要紹介&現地レポートとして1セッションお話をさせて頂きました。

セッション内容としては、過去のイベントの様に自分も「来年行こうと考えている方に何か繋げられれば」という気持ちで

  • 自分自身のポジションで経験して思った事
    •  変にレポートちっくにしない
    •  楽しいイベントだったという事を伝えたい
  • 来年の自分だったらこうしたい、こういう準備をしたい
    • 英語の事もう少し話したかったけど、納まらなかった。
  • イベント全体の流れとか様子(過去情報であんまり無いような気がした)
  • 発表内容を変に「コミュニティ」に絞らない
    •  AnsibleFestイベントとしては「エンタープライズ」「コミュニティ」「ユーザ」「パートナー」「Redhatter」の境目なく、Ansibleを中心に最新動向を語り合おう!がテーマとしてあると思ったので、そのあたりをあまり意識せずに有用だと思われる情報は共有しよう、という気持ちで資料はまとめてみました。

という事で発表資料こちらです。

 

speakerdeck.com

 

動画も公開されていますので是非IBM様の2セッションも含めて聴講して頂けると嬉しいです。

 

AnsibleFest2022概要紹介&現地レポート
ちょっとだけ補足

あんまりないですが少しだけ

参加について

それなりにお金もかかるので会社としてどういう目的でイベントに参加するのか、というのやはり大事な気がしています。具体的な目的は必要となりますし、会社がどういう風にAnsibleと関わっているのかも要素として大きいかなと。(オンラインのセッション公開もあるので余計に)

ただ、海外の技術イベントに参加してその雰囲気を味わってくるだけでも凄い価値がある事だと思っています。

私の場合「エンジニアはどんどん海外行って刺激をもらってきてほしい」という上の方のありがたい方針もあって「成果を求められる」ような事はなく今回参加しました。とはいえ行きたい時に行けるようなイベントでもないかなと。

セッションでも少し触れましたが、現地でないと体感できない事は絶対にあると思います。その具体例を述べてみたつもりですが答えがある訳でもないのでこれからも現地に行ったメンバが「行って良かった事」を共有するようなユーザ会振り返りイベントは大事だなと思っています。

英語

2022年1月から1.5h/週で習っています(会社様ありがとうございます)

でもまだまだ、セッションで述べたような現状です。

ここは偉そうに述べる何かは何もないので現在使っている教材でも紹介。

Basic English Grammar 4th Edition | English language teaching

StartUp | English language teaching

もう1年延長する事になったので、来年は現地で少しでも会話できるようになりたいです。一朝一夕では身に付かない事が良く分かったので、毎日少しずつ継続していくしかなさそうです。

来年からはもう少し教材のレベルが上がるようで震えています。。。

 

写真は英語の先生からは現地で本を買ってくるように言われて購入した本

こんなドンピシャな本に出会う?と思って購入した英英辞書(15$位)英語で資料作る時に表現とか役立ちそうだなと思い購入
写真

振り返る時に結構必要でした。

そこそこ撮っていたつもりですが展示会場の様子が分かる、セッションの様子が分かる、イベントの様子が分かる

等々写真スキル結構大事だなと思いました。

あと自分が写っている写真もせっかくだから撮ればよかったなーって後悔しています。

会場ホテルの1F出たらシカゴ川

 

持ち物

フォーマルな格好:不要

最終日のPartyがどんなもんか分からずスーツではなくともちょっとしたジャケットとか靴とか持っていきましたが一切使わず!
ちなみに最終日のParty会場とかも当日メールが来てそこで初めて知りました。

イベント期間中は毎日朝メールが届いて、そこで「〇時にホテルロビー集合!〇〇に移動するよ!」的な

 

食事

外食は高い!高かった!

先輩と2人で食べたら普通に60$とか。
ただチップの支払い方とかも教えてもらいました。

 

ちなみに会場ホテルでも朝食(バイキング)ありましたが30$位かかると分かって利用は初日だけでした。(朝は適当に外に)

でもイベント参加者は多かったのでそういう所でも現地の出会いはある気がします。

実際、初日のレセプションでは「朝会ったよね?」みたいな感じで話してきてくれた方もいました。

シカゴピザ、最高だった。また食べたい。

シカゴピザめっちゃ美味しかった。

日本でも食べれるところ知りたい。

 

ホテル(会場ホテル)

イベントサイトから予約しました。

イベント登録後、ログインするとホテル予約用ページがあってそこから部屋を確保できます。(普通にホテルのサイトから予約するよりも安い)

ただ、こんな立派な部屋なのに冷蔵庫とか無かったですねー汗

あと気を使って頂いたのか一緒に行った先輩と隣の部屋でした。

立派なお部屋、一泊290$位

最後に

後半は駄文の垂れ流しでスイマセン。

過去イベントはFestの内容だけを拾おうとするとちょっとだけ面倒なのでお役に立ったら幸いです。

あと毎年のトピックスを知るとAnsibleプロダクトのパワーアップが知れてまとめていた楽しかったです。

 

来年行けるかはまだ分かりませんが、チャンスあれば行きたいです。

その為にも普段から最新情報のキャッチアップと技術検証等々、もっとAnsibleを触る時間を増やしていきたいと思っています。

あと英語。

 

箸休め的な記事になってしまったかと思いますが現地で書きかけていた内容を無事供養できました。

 

ではでは。

【参加レポート】Ansible Night Online 2021.02

はじめに

Ansible Night Online 2021.02
の参加レポートとなります。

Ansible Night Online 2021.02 - connpass

約半年ぶりに開催されたAnsibleコミュニティイベントでしたが、300人overの申し込みで2時間半の大ボリュームでした。
各セッションの概要・所感、資料内で紹介されていたLINKまとめなどを中心にまとめてみました。

公開資料&参加レポート

動画アーカイブ

www.youtube.com

冒頭

Ansibleコミュニティ、ユーザ会活動について

各イベントの詳細はこちらより

Ansible ユーザー会 - connpass

Ansible Night(3ヵ月に1回位)
今回は約半年ぶりの開催、本当は3ヵ月に1回位やりたいので講演したい方は #ansiblejp で!
・メインセッション+LT

Ansibleもくもく会(1ヵ月に1回程度開催)
・最近ネットワークのF5編や、Windows編も開催中♪

Ansible〇〇部
・Slackチャネルで色々と情報交換しながら、小規模イベントを開催予定♪

Ansibleユーザ会運営(ぽてる会)
・今後の運営やイベントについて議論する会です♪

Advent Calendar 2020 お疲れ様でした

Ansible Advent Calendar 2020 - Qiita

Ansible Advent Calendar 2020 - Adventar

セッション

『AnsibleFest2020 Recap』(0:18:55位~)

www.slideshare.net

<内容>
Ansibleコミュニティの最大イベントであるAnsibleFest2020紹介された情報のうち、技術系のセッションに特化して発表者の斎藤さんが『これからくるかもしれないであろうAnsibleの最新技術トピック』についてまとめ&検証頂いた内容についての発表でした。

■AnsibleFest2020 Virtual Experience
https://www.ansible.com/ansiblefest

今後Ansibleがフォーカスしていく新技術について、以下のDay2のキーノートセッション内で紹介されていたそうです。(22:27~)

https://www.youtube.com/watch?v=AP9OTB6eTJg

これから運用で使い可能性のある、以下2つの内容について解説、紹介して頂いていました。

<トピック1:Private Automation Hub>
現状、AnsibleのRoleやCollectionsを入手できる経路は3つあります。

■1つめ
Community Galaxy:https://galaxy.ansible.com/

■2つめ
Automation Hub:https://cloud.redhat.com/ansible/automation-hub
※カスタマーポータルサイトのアカウントが必要
Certifiedモジュール(Red Hatの公式サポート)が登録されている。

■3つめ
Galaxy NG(Private Automation Hub) 今回のトピックスとなっている、Private Automation Hubです。
ユーザのプライベートなコンテンツ(3種)を集約する事が可能となります、3つの内訳は
・Ansible Galaxy でコミュニティとして公開されているコンテンツ
・Automation Hub で公式サポートされているコンテンツ
・Publishedな内容で、非公開で組織内で使うようなコンテンツ
となっていて、各コンテンツをキャッシュでき、ユーザのプライベートなコンテンツを集約する事が可能となります。
(これは便利そう)


<トピック2:Playbook Runtime Environment(Ansible Runner / Ansible Builder / Receptor)>
■Ansible Runner
Ansibleの実行環境をコンテナ化する技術、従来もAnsible実行環境はchrootなどを使って安全に提供されていたが、v2.0からはコンテナベースの実行環境が提供されるようです。
※v2.0はまだpipでは引けないそうで、要build(現時点)
Day2の以下セッションで構築方法などが説明されていて必見との事
(Creating and using Ansible execution environments(Day2))※要レジスト
github.com

■Ansible Builder
Ansible Runner v2.0 が利用するPlaybookの実行環境イメージをビルドする為のプロダクト pipでも提供されているそうです。
github.com に関する内容でした。
Ansible Runnier と Ansible Builder については、ソフトウェアデザイン2021.2月号の『Ansible問題解決マップ』で取り上げられているので要チェック!

■Receptor
Ansible Tower のPlaybook実行環境を提供する仕組みで、以下3つの役割(サービス)がある。基本的にメッシュ構造との事
・コントーロールノード:Playbook実行を実際に命令する子
・リレーノード:Playbookの実行環境の中継をする子
・ワーカーノード:実際にPlaybookを実行する子
実際にデモ実演もして頂いてました!

receptorctl

というコマンド経由で色々と実行していました。

<所感>
AnsibleのCollectionは提供方法が増えた印象でしたが、そのあたりをユーザが管理しやすくする為の仕組みが、Private Automation Hubなのだな、と思いました。それぞれの役割と使い方を説明頂いたので非常に分かりやすかったです
ReceptorはAnsibleTowerをベースに、実行環境がk8sとかOpenShiftとかで分散されているような構成を考えた際に、必要となる技術なのかもしれませんね。
実行環境を意識しない為の仕組み、という気がしまして、大規模運用でAnsibleを使う場合にこれから必要となる技術な気がします。


『組織で自動化に着手する前に行うべきだと感じた3つの下拵え』(0:47:45位~)

www.slideshare.net

<内容・所感>
冒頭に『心理的安全性』の必要性という話から入り、それを前提に、3つの下ごしらえについて実体験をベースに具体的な情報共有をして頂きました。心理的安全性を確保した上で、はやっぱり大事ですよね。
1.上司に対しての下ごしらえ
2.自動化対象選定の下ごしらえ
3.チームでの自動化開発に向けた下ごしらえ
自分は今後、1,2,3のどの立場にもなりえるなと思って聞いていましたが、それぞれ具体的な分析手法であったり、考えるべきポイントについて説明頂いたので、ある意味自動化を進める上での手順書を共有頂いたな、と思いとても勉強になりました。
今後自分の組織で作業の手順化を進める際には、スモールスタートの原則に沿って、目に見える成果が出やすい所からはじめたいなと。また、 個人的には開発という立場なので セッション最後の『課題解決の為のコミュニケーションコストを下げる為の下準備をして、コードを書く為の開発に注力できる体制を作る』が非常に印象に残りました。


『極度自動化したいといわれて困った話 ~某自動化推進チームの場合~』(1:08:27位~)

drive.google.com

<内容・所感>
JIT様のセッションでもありましたが、サーバ群をあまり可愛がってはいけませんね。というマインドチェンジから入らないといけないなと思いました。いつも私はホスト名付けからワクワクして考えちゃっています(汗)
Ansible運用を個人からチーム、チームから組織に広げていく為に工夫する点や成功した際の背景分析など非常に勉強になりました。
ロゴを作ったり、Tシャツを作ったり、そういう所から入るのって組織での運用を広げる為にはとっても重要なんじゃないかな、って思います。私も多分そういうチームだとワクワクする気がします。

LTセッション

『チームでPlaybook開発する時の心構え/仕組みづくり』jiro01030 さん (1:30:46位~)

www.slideshare.net

<内容・所感>
チームでPlaybook作成する際に気を付ける点、それを技術的な改善点+マインド面やモチベーション含めて気を付けた点について共有頂きました。
人から指摘されるより機械に指摘してもらうようにして、メンバの精神的負荷を下げるっていうのはホントその通りですよね(仕組みで解決する、モチベーションの維持は大切)。チームでPlaybook開発が広がっていく際には最初から考えないといけないポイントだなと思いました。

『Ansible Towerをみんなで使うためにやったこと』hito58 さん (1:40:10位~)

speakerdeck.com

<内容・所感>
AnsibleTowerを運用で使うにあたって大切なポイント2つを共有頂きました。
①インベントリの共通化・・・Towerのライセンス費効率化の為だったが、メンテナンス性も良くなった
②Playbookを1つのリポジトリで管理・・・開発環境の移行もしやすくなった
自分はAWX/Towerの利用経験が浅いのですが、特に①の正規化/共通化で『hostsは最小単位で、その他はgroupsで管理』はすぐ実践できる内容ですね、非常に勉強となりました。
Ansible Towerも勉強しないと・・・

『MSP企業でAnsibleを浸透させる難しさ』10key3 さん (1:46:14位~)

docs.google.com

<内容・所感>
エンジニアとして『メリットどうこうよりもAnsible使ってみると楽しいから使って欲しい』
自分もAnsible使っていて楽しいです、本当は他の自動化ツールの選定とかも必要なんでしょうけど、『自分が使いたいから』というモチベーションを優先したりしています。組織で使う、本番環境含めて、だと色々とケアするポイントは増えるのかもしれませんが、推進する人間のモチベーションも同じくらい大事だな、と改めて思ったりします。


『モジュール開発と運用』naka-shin1 さん (1:51:40位~)

speakerdeck.com

<内容・所感>
モジュール開発している目線でAnsible運用というテーマでLTしてみました。
あまりAnsible運用の方の参考にはならなかったかもしれませんし、モジュール開発している方はかなり少数な気がしていますが、何か少しでも参考になれば幸いです。
カメラONし忘れてた。。。

『AnsibleとCloudFormationの組み合わせでトレーニング環境を運用している話』 mito さん (1:58:08位~)

speakerdeck.com

<内容・所感>
Ansibleのトレーニング環境をクラウドに構築して使ってもらう、という運用をしていくにあたり、便利な点、ハマって点などを共有頂きました。
この手順を定期的に作成、削除を繰り返すという作業を考えるだけで、自動化は必須ですね。最後のまとめで自動化したが故に見えにくくなってしまう部分についてのケアが必要、という話がありましたがその通りだなと思いました。
一番効果が出る部分ができたら運用し始めて、少しずつ改善してく、という進め方も非常に勉強になりました。

『自滅のAnsible』しゃうち さん (2:15:046~)

www.slideshare.net

<内容・所感>
イベント後のAnsible飯ではこのセッションの話題が多かった気がします。
「こういったLTがAnsibleでもついに出てきて嬉しい」「このLTが最後で良かった(インパクト強くて他のLTの存在感が・・・笑)」
開発者と運用者が協力して、あるべきアーキテクトを設計するという部分は非常にその通りだなと思って聞いていました。

QAタイム

(2:04:50位~)

クロージング (2:22:20位~)

各分科会の説明がありました!


Ansibleもくもく会、次回は 2/18(木)サーバ&NW編です

【リモート開催】Ansibleもくもく会 2021.02 - connpass



Katacoda

これ以上ないほど簡単にAnsibleを試すHow to #ansiblejp - 赤帽エンジニアブログ

ブラウザだけでAnsibleを一通り学べるコンテンツ♪
リリースして約1年で12,000回も実行されているようです、凄い!
メンテ、PRして頂ける方を募集中だそうです♪

ネットワーク部

・Ansibleでネットワーク機器の作業を自動化している or 興味ある人向け♪

Slackの #network に是非参加を!

Join ansiblejp on Slack | Slack



ディベロッパー部

モジュール開発、コードリーディング、テストなど♪
開発に関係する内容について♪
Slackの #developers に是非参加を!

Join ansiblejp on Slack | Slack



VMware

VMware基盤の自動化関連で、Ansible×VMwareの分科会!

Slackの #vmware に是非参加を!

Join ansiblejp on Slack | Slack



Ansible Trailmap

昨年公開された Mt. YAML に続いて、新たなる山が登場! Mt BUTTON(ボタン山)
Mt.YAMLは入門編、Mt.BUTTONは、作ったPlaybookをボタン化(サービス化)の入門
※サービス化→ボタン化→牡丹の花

www.redhat.com



■インフラエンジニアBooks
2/16(火)Ansible実践ガイド 第3版を語るイベントを開催!

インフラエンジニアBooks#6 北山晋吾氏・横地晃氏と読む「Ansible実践ガイド 第3版」 - connpass

https://www.youtube.com/watch?v=DyvVlRu0d34 既にYoutube公開されています!



所感

・素敵で大ボリュームなイベントだったので、頑張って出来る限りブログという形でも残してみました。
・今回は『運用』という興味がある人が非常に多いテーマだったと思います。
・運営の皆様、発表の皆様、ありがとうございます&お疲れ様でした!
・オンラインイベントという事で発表者の方を集めにくいという事が冒頭ありましたが、見ているのも楽しいですが発表側はもっと楽しいですよ!
・ブログ大変でした笑
・Happy Automation♪

Ansible Galaxy をローカルに構築してみる

はじめに

Ansible Collection用のモジュールを作成後、
・きちんとAnsible Galaxyのサイトにアップできるのかどうか
・アップしたファイルの内容を事前に確認したい

という目的で、社内環境にAnsible Galaxy を構築してみました。
参考にさせて頂いたサイトや構築時にハマった事などを共有したいと思います。

参考にさせて頂いた情報

ちょうど作業しているタイミングでRed Hat Tech Night というイベントがありまして、その中でAnsible Galaxy NGの構築手順のLTがあったので大変助かりました。

第4回 Red Hat Tech Night online 2021.1.14 - connpass

www2.slideshare.net

あとは、公式ドキュメント

https://www2.slideshare.net/h-saito/getting-started-ansible-galaxy-ng-241322669 galaxy.ansible.com

Qiitaに公開されている情報

qiita.com

です。

いずれも非常に助けられました。ありがとうございます!

内容

構築した環境

自宅ラボとかないので、社内環境に構築しました。 という事でProxy環境下での構築についてとなります。

OSはCentOS7です

CentOS Linux release 7.9.2009 (Core)

環境変数にProxyはきちんと設定している状態で、きちんと外に出られる状態です。

http_proxy=x.x.x.x:yy
https_proxy=x.x.x.x:yy
HTTP_PROXY=x.x.x.x:yy
HTTPS_PROXY=x.x.x.x:yy

/etc/profile でexportしてます。

Ansible Galaxy NG の構築

RHTNのLT資料を見ても、手順は非常に少なく感じました。
ただ最近は環境構築していると大体Proxy環境下という事でハマるのでそうならないといいなぁと思っていました。思っていました。

インストール環境の準備

ほぼ参考にさせて頂いた資料と同じなので恐縮ですが、、、

Ansibleのインストール

$ sudo yum install ansible
$ rpm -qa | grep ansible
ansible-2.9.16-1.el7.noarch
$ 

必要なコレクションのインストール

$ ansible-galaxy collection install pulp.pulp_installer
$ ansible-galaxy collection install ansible.galaxy_collection

インストール用Playbookの取得

$ git clone https://gist.github.com/629ba52d68301cc9798227b87704df84.git galaxy_ng

pulp_installerに必要なロールの取得

ansible-galaxy install -r ~/.ansible/collections/ansible_collections/pulp/pulp_installer/requirements.yml

インストールに必要なインベントリの作成

$ cat hosts
localhost       ansible_user=xxxx ansible_password=xxxx

[galaxyng]
localhost ansible_connection=local

[galaxyng:vars]
ansible_become=True
$ 

インストール

Ansibleでインストール

$ ansible-playbook enduser-install.yml -i hosts --extra-vars "@upstream-rpm-install-vars.yml" 

多分Proxy環境下でなければこれでインストール完了だと思います。

発生したエラーとその対処

その1

エラー内容

https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-7 にアクセスしようとしてタイムアウトになったようです。

"msg": "failed to fetch key at https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-7 , error was: Request failed: <urlopen error timed out>" 

エラー全文

TASK [pulp.pulp_installer.pulp_common : Import required EPEL RPM GPG keys] **************************************************************************************************************************
task path: /home/xxxx/.ansible/collections/ansible_collections/pulp/pulp_installer/roles/pulp_common/tasks/repos.yml:5
<localhost> ESTABLISH LOCAL CONNECTION FOR USER: xxxx
<localhost> EXEC /bin/sh -c 'echo ~xxxx && sleep 0'
<localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/xxxx/.ansible/tmp `"&& mkdir "` echo /home/xxxx/.ansible/tmp/ansible-tmp-1610628273.4-5587-188770266220500 `" && echo ansible-tmp-1610628273.4-5587-188770266220500="` echo /home/xxxx/.ansible/tmp/ansible-tmp-1610628273.4-5587-188770266220500 `" ) && sleep 0'
Using module file /usr/lib/python2.7/site-packages/ansible/modules/packaging/os/rpm_key.py
<localhost> PUT /home/xxxx/.ansible/tmp/ansible-local-48832fVMST/tmpywBx4d TO /home/xxxx/.ansible/tmp/ansible-tmp-1610628273.4-5587-188770266220500/AnsiballZ_rpm_key.py
<localhost> EXEC /bin/sh -c 'chmod u+x /home/xxxx/.ansible/tmp/ansible-tmp-1610628273.4-5587-188770266220500/ /home/xxxx/.ansible/tmp/ansible-tmp-1610628273.4-5587-188770266220500/AnsiballZ_rpm_key.py && sleep 0'
<localhost> EXEC /bin/sh -c 'sudo -H -S -n  -u root /bin/sh -c '"'"'echo BECOME-SUCCESS-iampiogeqfghcybbprtzzmacdrkcshcm ; DJANGO_SETTINGS_MODULE=pulpcore.app.settings /usr/bin/python /home/xxxx/.ansible/tmp/ansible-tmp-1610628273.4-5587-188770266220500/AnsiballZ_rpm_key.py'"'"' && sleep 0'
<localhost> EXEC /bin/sh -c 'rm -f -r /home/xxxx/.ansible/tmp/ansible-tmp-1610628273.4-5587-188770266220500/ > /dev/null 2>&1 && sleep 0'
fatal: [localhost]: FAILED! => {
    "changed": false, 
    "invocation": {
        "module_args": {
            "fingerprint": null, 
            "key": "https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-7", 
            "state": "present", 
            "validate_certs": true
        }
    }, 
    "msg": "failed to fetch key at https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-7 , error was: Request failed: <urlopen error timed out>" 
}

PLAY RECAP ****************************************************************************************************************************************
localhost                  : ok=39   changed=0    unreachable=0    failed=1    skipped=11   rescued=0    ignored=0   

$                : ok=39   changed=0    unreachable=0    failed=1    skipped=11   rescued=0    ignored=0   

対処

外部アクセス時のタイムアウトエラーは大体Proxyが原因という過去の経験より
対象のPlaybookに環境変数でProxyを追記しました。

--- repos.yml.bak       2021-01-14 21:57:41.320812541 +0900
+++ repos.yml   2021-01-14 21:59:39.139805575 +0900
@@ -3,6 +3,9 @@

 - name: Import required EPEL RPM GPG keys
+  environment:
+    http_proxy: x.x.x.x:yyyy
+    https_proxy: x.x.x.x:yyyy
   rpm_key:
     state: present
     key: https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-{{ ansible_facts.distribution_major_version }}

これで先に進みました。

その2

エラー内容
raise IDNAError('The label {0} is not a valid A-label'.format(label))\nidna.core.IDNAError: The label centos7_nedved is not a valid A-label\n", 
    "module_stdout": "", 
    "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", 
    "rc": 1

エラー全文

TASK [pulp.pulp_installer.pulp_webserver : Generate CA CSR] *******************************************************************************************************************************************************************************
task path: /home/xxxx/.ansible/collections/ansible_collections/pulp/pulp_installer/roles/pulp_webserver/tasks/generate_tls_certificates.yml:21
<localhost> ESTABLISH LOCAL CONNECTION FOR USER: xxxx
<localhost> EXEC /bin/sh -c 'echo ~xxxx && sleep 0'
<localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/xxxx/.ansible/tmp `"&& mkdir "` echo /home/xxxx/.ansible/tmp/ansible-tmp-1610629541.8-18196-180460235469601 `" && echo ansible-tmp-1610629541.8-18196-180460235469601="` echo /home/xxxx/.ansible/tmp/ansible-tmp-1610629541.8-18196-180460235469601 `" ) && sleep 0'
Using module file /usr/lib/python2.7/site-packages/ansible/modules/crypto/openssl_csr.py
<localhost> PUT /home/xxxx/.ansible/tmp/ansible-local-14498dKbVFf/tmp86hqnb TO /home/xxxx/.ansible/tmp/ansible-tmp-1610629541.8-18196-180460235469601/AnsiballZ_openssl_csr.py
<localhost> EXEC /bin/sh -c 'chmod u+x /home/xxxx/.ansible/tmp/ansible-tmp-1610629541.8-18196-180460235469601/ /home/xxxx/.ansible/tmp/ansible-tmp-1610629541.8-18196-180460235469601/AnsiballZ_openssl_csr.py && sleep 0'
<localhost> EXEC /bin/sh -c 'sudo -H -S -n  -u root /bin/sh -c '"'"'echo BECOME-SUCCESS-rxtnhhscpjnhifwlnurttrvekxivqilc ; DJANGO_SETTINGS_MODULE=pulpcore.app.settings /usr/bin/python /home/xxxx/.ansible/tmp/ansible-tmp-1610629541.8-18196-180460235469601/AnsiballZ_openssl_csr.py'"'"' && sleep 0'
<localhost> EXEC /bin/sh -c 'rm -f -r /home/xxxx/.ansible/tmp/ansible-tmp-1610629541.8-18196-180460235469601/ > /dev/null 2>&1 && sleep 0'
The full traceback is:
Traceback (most recent call last):
  File "/home/xxxx/.ansible/tmp/ansible-tmp-1610629541.8-18196-180460235469601/AnsiballZ_openssl_csr.py", line 102, in <module>
    _ansiballz_main()
  File "/home/xxxx/.ansible/tmp/ansible-tmp-1610629541.8-18196-180460235469601/AnsiballZ_openssl_csr.py", line 94, in _ansiballz_main
    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
  File "/home/xxxx/.ansible/tmp/ansible-tmp-1610629541.8-18196-180460235469601/AnsiballZ_openssl_csr.py", line 40, in invoke_module
    runpy.run_module(mod_name='ansible.modules.crypto.openssl_csr', init_globals=None, run_name='__main__', alter_sys=True)
  File "/usr/lib64/python2.7/runpy.py", line 176, in run_module
    fname, loader, pkg_name)
  File "/usr/lib64/python2.7/runpy.py", line 82, in _run_module_code
    mod_name, mod_fname, mod_loader, pkg_name)
  File "/usr/lib64/python2.7/runpy.py", line 72, in _run_code
    exec code in run_globals
  File "/tmp/ansible_openssl_csr_payload_XSwXCN/ansible_openssl_csr_payload.zip/ansible/modules/crypto/openssl_csr.py", line 1105, in <module>
  File "/tmp/ansible_openssl_csr_payload_XSwXCN/ansible_openssl_csr_payload.zip/ansible/modules/crypto/openssl_csr.py", line 1088, in main
  File "/tmp/ansible_openssl_csr_payload_XSwXCN/ansible_openssl_csr_payload.zip/ansible/modules/crypto/openssl_csr.py", line 541, in generate
  File "/tmp/ansible_openssl_csr_payload_XSwXCN/ansible_openssl_csr_payload.zip/ansible/modules/crypto/openssl_csr.py", line 834, in _generate_csr
  File "/usr/lib64/python2.7/site-packages/cryptography/x509/base.py", line 393, in sign
    return backend.create_x509_csr(self, private_key, algorithm)
  File "/usr/lib64/python2.7/site-packages/cryptography/hazmat/backends/multibackend.py", line 395, in create_x509_csr
    return b.create_x509_csr(builder, private_key, algorithm)
  File "/usr/lib64/python2.7/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 793, in create_x509_csr
    gc=False
  File "/usr/lib64/python2.7/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 1009, in _create_x509_extensions
    handlers, extension
  File "/usr/lib64/python2.7/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 1040, in _create_x509_extension
    ext_struct = encode(self, extension.value)
  File "/usr/lib64/python2.7/site-packages/cryptography/hazmat/backends/openssl/encode_asn1.py", line 359, in _encode_alt_name
    general_names = _encode_general_names(backend, san)
  File "/usr/lib64/python2.7/site-packages/cryptography/hazmat/backends/openssl/encode_asn1.py", line 351, in _encode_general_names
    gn = _encode_general_name(backend, name)
  File "/usr/lib64/python2.7/site-packages/cryptography/hazmat/backends/openssl/encode_asn1.py", line 387, in _encode_general_name
    value = _idna_encode(name.value)
  File "/usr/lib64/python2.7/site-packages/cryptography/hazmat/backends/openssl/encode_asn1.py", line 376, in _idna_encode
    return idna.encode(value)
  File "/usr/lib/python2.7/site-packages/idna/core.py", line 355, in encode
    result.append(alabel(label))
  File "/usr/lib/python2.7/site-packages/idna/core.py", line 265, in alabel
    raise IDNAError('The label {0} is not a valid A-label'.format(label))
idna.core.IDNAError: The label centos7_nedved is not a valid A-label
fatal: [localhost]: FAILED! => {
    "changed": false, 
    "module_stderr": "Traceback (most recent call last):\n  File \"/home/xxxx/.ansible/tmp/ansible-tmp-1610629541.8-18196-180460235469601/AnsiballZ_openssl_csr.py\", line 102, in <module>\n    _ansiballz_main()\n  File \"/home/xxxx/.ansible/tmp/ansible-tmp-1610629541.8-18196-180460235469601/AnsiballZ_openssl_csr.py\", line 94, in _ansiballz_main\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n  File \"/home/xxxx/.ansible/tmp/ansible-tmp-1610629541.8-18196-180460235469601/AnsiballZ_openssl_csr.py\", line 40, in invoke_module\n    runpy.run_module(mod_name='ansible.modules.crypto.openssl_csr', init_globals=None, run_name='__main__', alter_sys=True)\n  File \"/usr/lib64/python2.7/runpy.py\", line 176, in run_module\n    fname, loader, pkg_name)\n  File \"/usr/lib64/python2.7/runpy.py\", line 82, in _run_module_code\n    mod_name, mod_fname, mod_loader, pkg_name)\n  File \"/usr/lib64/python2.7/runpy.py\", line 72, in _run_code\n    exec code in run_globals\n  File \"/tmp/ansible_openssl_csr_payload_XSwXCN/ansible_openssl_csr_payload.zip/ansible/modules/crypto/openssl_csr.py\", line 1105, in <module>\n  File \"/tmp/ansible_openssl_csr_payload_XSwXCN/ansible_openssl_csr_payload.zip/ansible/modules/crypto/openssl_csr.py\", line 1088, in main\n  File \"/tmp/ansible_openssl_csr_payload_XSwXCN/ansible_openssl_csr_payload.zip/ansible/modules/crypto/openssl_csr.py\", line 541, in generate\n  File \"/tmp/ansible_openssl_csr_payload_XSwXCN/ansible_openssl_csr_payload.zip/ansible/modules/crypto/openssl_csr.py\", line 834, in _generate_csr\n  File \"/usr/lib64/python2.7/site-packages/cryptography/x509/base.py\", line 393, in sign\n    return backend.create_x509_csr(self, private_key, algorithm)\n  File \"/usr/lib64/python2.7/site-packages/cryptography/hazmat/backends/multibackend.py\", line 395, in create_x509_csr\n    return b.create_x509_csr(builder, private_key, algorithm)\n  File \"/usr/lib64/python2.7/site-packages/cryptography/hazmat/backends/openssl/backend.py\", line 793, in create_x509_csr\n    gc=False\n  File \"/usr/lib64/python2.7/site-packages/cryptography/hazmat/backends/openssl/backend.py\", line 1009, in _create_x509_extensions\n    handlers, extension\n  File \"/usr/lib64/python2.7/site-packages/cryptography/hazmat/backends/openssl/backend.py\", line 1040, in _create_x509_extension\n    ext_struct = encode(self, extension.value)\n  File \"/usr/lib64/python2.7/site-packages/cryptography/hazmat/backends/openssl/encode_asn1.py\", line 359, in _encode_alt_name\n    general_names = _encode_general_names(backend, san)\n  File \"/usr/lib64/python2.7/site-packages/cryptography/hazmat/backends/openssl/encode_asn1.py\", line 351, in _encode_general_names\n    gn = _encode_general_name(backend, name)\n  File \"/usr/lib64/python2.7/site-packages/cryptography/hazmat/backends/openssl/encode_asn1.py\", line 387, in _encode_general_name\n    value = _idna_encode(name.value)\n  File \"/usr/lib64/python2.7/site-packages/cryptography/hazmat/backends/openssl/encode_asn1.py\", line 376, in _idna_encode\n    return idna.encode(value)\n  File \"/usr/lib/python2.7/site-packages/idna/core.py\", line 355, in encode\n    result.append(alabel(label))\n  File \"/usr/lib/python2.7/site-packages/idna/core.py\", line 265, in alabel\n    raise IDNAError('The label {0} is not a valid A-label'.format(label))\nidna.core.IDNAError: The label centos7_nedved is not a valid A-label\n", 
    "module_stdout": "", 
    "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", 
    "rc": 1
}

PLAY RECAP ********************************************************************************************************************************************************************************************************************************
localhost                  : ok=96   changed=32   unreachable=0    failed=1    skipped=38   rescued=0    ignored=0   

$ 

対処

centos7_nedvedというホスト名つけていたのですが、これが怒られていたみたいです。
特に他と連携しているサーバでもないので 素直にホスト名変更nedvedにしましたらサクッといきました。
アンダーバーがいけなかったのかも。。。

という事で

2つの対処で無事Playbookが全て通りました!

PLAY RECAP *******************************************************************************************************
localhost                  : ok=131  changed=30   unreachable=0    failed=0    skipped=43   rescued=0    ignored=0   

$ 

残すは

パッチ

/usr/lib/python3.6/site-packages/pulp_ansible/app/tasks/collections.py

--- collections.py.bak  2021-01-14 22:35:39.746677840 +0900
+++ collections.py      2021-01-14 22:38:41.434667099 +0900
@@ -243,6 +243,9 @@
         collection_version.is_highest = True
         last_highest.save()
         collection_version.save()
+    elif collection_version.is_highest and collection_version.version != last_highest.version:
+        collection_version.is_highest = False
+        collection_versioon_version.save()

 class AnsibleDeclarativeVersion(DeclarativeVersion):
@@ -585,7 +588,9 @@
                 continue
             collection_version = d_content.content
             docs_blob = d_content.extra_data.get("docs_blob", {})
+            if docs_blob:
+                collection_version.docs_blob = docs_blob

             for d_artifact in d_content.d_artifacts:
                 artifact = d_artifact.artifact

設定変更

/etc/pulp/settings.py

--- settings.py.bak     2021-01-14 22:41:13.378658116 +0900
+++ settings.py 2021-01-14 22:42:58.241651916 +0900
@@ -3,9 +3,11 @@
 X_PULP_API_PREFIX = "pulp_ansible/galaxy/automation-hub/api" 
 X_PULP_API_HOST = "127.0.0.1" 
 GALAXY_REQUIRE_CONTENT_APPROVAL = False
-TOKEN_SERVER = "https://nedved/token" 
+TOKEN_SERVER = "https://x.x.x.x/galaxy/token" 
 X_PULP_API_PORT = 24817
-CONTENT_ORIGIN = "https://localhost" 
+CONTENT_ORIGIN = "https://x.x.x.x" 
 DATABASES = {"default": {"ENGINE": "django.db.backends.postgresql", "HOST": "localhost", "PASSWORD": "pulp", "NAME": "pulp", "USER": "pulp"}}
 PRIVATE_KEY_PATH = "/etc/pulp/certs/token_private_key.pem" 
 X_PULP_API_PASSWORD = "password" 

ホスト名はDNS設定している訳ではなかったのでIP直接に変更

サービスリスタート

# systemctl restart pulpcore-worker@1
# systemctl restart pulpcore-worker@2
# systemctl restart pulpcore-resource-manager
# systemctl restart pulpcore-content
# systemctl restart pulpcore-api

アクセス

https://x.x.x.x
IDパスワードは変更していなければ デフォルト値(admin/password)でアクセス

f:id:naka-shin1:20210115215231j:plain
Ansible Galaxy NG のログイン画面

お疲れ様でした。

おまけ

Ansible Private Galaxy(旧)の構築

これですね。

github.com

https://github.com/ansible/galaxy/blob/devel/CONTRIBUTING.rst

当初、さいとうさんの LT資料でいう Ansible Private Galaxy(旧)を構築していました。 ただ、コンテナなのでデータ部分をローカルに保存するように変更しないとなぁ、、、と思っていました。

こちらは Galaxy NG とは違って、Dockerコンテナで構築する手順となっています。

参考:構築手順

qiita.com

こちらでも大変お世話になりました。

エラー内容

Step 11/22 : RUN curl -sL -o '/tmp/nodesource-release-el7-1.noarch.rpm'         'https://rpm.nodesource.com/pub_8.x/el/7/x86_64/nodesource-release-el7-1.noarch.rpm'     && rpm -i --nosignature --force '/tmp/nodesource-release-el7-1.noarch.rpm'     && rm -f '/tmp/nodesource-release-el7-1.noarch.rpm'     && curl -sL -o '/etc/yum.repos.d/yarn.repo' 'https://dl.yarnpkg.com/rpm/yarn.repo'     && yum -y install nodejs yarn     && yum -y clean all     && rm -rf /var/cache/yum
 ---> Running in 8a7b06b0715f
The command '/bin/sh -c curl -sL -o '/tmp/nodesource-release-el7-1.noarch.rpm'         'https://rpm.nodesource.com/pub_8.x/el/7/x86_64/nodesource-release-el7-1.noarch.rpm'     && rpm -i --nosignature --force '/tmp/nodesource-release-el7-1.noarch.rpm'     && rm -f '/tmp/nodesource-release-el7-1.noarch.rpm'     && curl -sL -o '/etc/yum.repos.d/yarn.repo' 'https://dl.yarnpkg.com/rpm/yarn.repo'     && yum -y install nodejs yarn     && yum -y clean all     && rm -rf /var/cache/yum' returned a non-zero code: 6
make: *** [build/docker-dev] エラー 6

docker自体にProxy設定はしていたのですが、インストール時に構築されるcentos7のコンテナがcurlyumを実行する際にProxy設定が必要なのでエラーとなっているようです。

対処

galaxy/scripts/docker/dev/Dockerfile

に直接環境変数でプロキシ設定を埋め込みました

FROM centos:7

ENV HTTP_PROXY http://x.x.x.x:yyyy  <--- 追記
ENV HTTPS_PROXY http://x.x.x.x:yyyy <--- 追記
ENV http_proxy http://x.x.x.x:yyyy  <--- 追記
ENV https_proxy http://x.x.x.x:yyyy <--- 追記

ENV LANG en_US.UTF-8

これでうまくいきました。

おまけ2

久々にブログ書きました。
普段はRedmineに色々と情報を残しているのですが、今年は少しずつブログで公開してみたいと思います。
今週『アウトプットしないのは知的な便秘』ってTLにも流れていましたね。
何か書くきっかけが欲しかったのでツイッタで呟いてみるのは とっても大事ですね(爆)

ちなみに nedvedは好きなサッカー選手の名前です。

謝辞

@ussvgrさん、@saito_hidekiさん
非常に参考にさせて頂きました、ありがとうございました。

2019年の振返りと2020年の抱負

はじめに

もうお正月も三が日過ぎました、今更ですが明けましておめでとうございます。
案の定冬休みに入るとPCに向き合う時間はほとんどとれず(汗)
息子(3)、娘(1)と沢山遊べる貴重な時間を楽しんでしました。

昨年は刺激の強い1年でした、
ただ1年通じて課題と思う部分もたくさんありました。
せっかくブログも開設したのできちんと2020年 開始時点の今の気持ちを書き残しておこうと思います。
※仕事始まるとすぐ色々と追われるのでなんとか冬休み中に書けました。
※だらだらと思った事を垂れ流して書いています。

2019年の振返り

新しい事始めた

講演・登壇

勉強会などは2017年位から少しずつ参加し始めて2018年は本格的に勉強会参加し始めていた気がします。
ただそれはいつも「見ている側」であって、「前の人」はどこか憧れはあってもなかなか実際、、、という感じでした。

2019年5月に某社さんのパートナー向けイベントで登壇の機会を頂いて、これが生まれて初めての登壇となりました。
これまで「前の人」をやりたいと思っても難しいなと思っていた理由は「ベンダー製品の開発担当」という仕事柄、どうしても自社の宣伝色が出てしまう為、個人的にはそれが嫌だという思いもあって機会がありませんでした。
ただ頂いたお話が2017年、2018年と頑張ってきた仕事の成果をそのまま話せるような内容だったので本当に有難い機会でした。
初の講演がかなりお高い結婚式場の、とても広い会場だったもんで、前で話すというイベントの度胸はここで強制的レベルアップさせて頂きました。
多分これ以上の規模はこの先あるとしたらJANOGの本会議位かと思います。

その後同じような内容をINTEROPのホットステージで講演したり、他社様のブースでしたり、パートナー様の勉強会でしたり
本業の開発もしつつ、「講演・登壇」という人前で話すという活動を抵抗なくできるようになった事は自分にとって非常にプラスとなりました。

コミュニティイベントへの参加

自分はネットワーク機器の開発という仕事ですが、「実際の運用現場」は味わっていませんし、実は知らない事ばかりです。
少しでも勉強して製品に機能として反映させたいので、その手段として外部のコミュニティイベントに参加しています。
2019年に参加してイベントは10回位だったようです。

Ansible Night in Tokyo 2019.04
Red Hat Tech Night 2019.05
Ansible Night in Tokyo 2019.07 ssmjp 2019/08
ネットワークプログラマビリティ勉強会 #18
IIJ Technical NIGHT vol.8
CI/CD Test Night #5
Ansibleもくもく会 (サーバ編 & NW編)2019.11
第3回 Red Hat Tech Night 2019.11.15
Ansiblejpネットワーク部 2019.11
Ansible Night in Tokyo 2019.11 ※リモート参加含む

振返ってもやはりAnsible系が多いですね。

7月のAnsibleNightが Ansibleに関連するLT大会だったので初めてLT登壇しました。
最初に経験した登壇は個人的には仕事としての登壇だったので、それ以外にも自発的に発表をしたいという気持ちからでした。
LT自体は個人的には反省が残る内容でしたが、一歩踏み出せてよかったと思っています。

あとは12月のAnsible AdventCalenderに参加してみたり、2019年は発信する環境を整えたり、少なくとも一歩踏み出すことができたと思っています。
コミュニティイベントは頑張ったりやればやるほど周りの人の凄さが分かりますが、自身の業務をあまり圧迫しないようにいいバランスで、あまり背伸びをせずに継続していきたいと思っています。

SNSの利用

Twitter、ブログ、Qiitaなどの環境を整えてそれなりに使い始めました。
特にTwitterは2018年位から技術用でアカウントはあったのですが、イベントでハッシュタグを追うという使い方が主で他の方とどうこうというのは極めて限定的でした。
ですが2019年は少しだけうまく使えるようになった気がします。
- イベントで出会った方とのコミュニケーションツール
- 自分に興味がある技術情報をある程度自然に収集できる環境

として非常に大事なツールだと思っています。

新しい出会い

入社13年でこんなにも新しい出会いの多い1年はありませんでした。
一歩踏み出した先には素敵な出会いがあるんですね。

社内

弊社は定期的に任意参加の勉強会があります。
毎回3,40名位集まって4セッション位の発表を聞くのですが、とある会で自分の興味ある分野である「自動化」や「DevOps」という部分で意気投合する仲間に出会えました。
その方も部署内ではそういう分野の話をする方が少ないようで、働く場所も離れているのですがSlackでこまめに連絡をとるような感じにもなり非常に貴重な出会いでした。
ちょうど「カイゼンジャーニー」を読んだ後というのもあってなんだかとても嬉しい気持ちになったのを覚えていますし、今ではいい相談相手です。
その後少しずつ仲間も増え、部署を横断して何か会社でやりたい気持ちが強くなった2019年でした。

社外

2019年はAnsibleコミュニティに継続して参加していたので、そこで多数の方と出会いました。
もともと2018年に勉強会参加し始めた時に感じていた「懇親会で話す人いないなー」という状態は2019年脱する事ができたかなと(汗) これって結構自分の中では大きかった気がします。
懇親会で担当製品についての質問をパスして頂いた時などは本当に嬉しかったです。

課題

多分これは2020年もこの先もなんだと思うのですが、様々な事に手を出すとバランスが非常に難しいです。
それを痛いほど痛感した1年でした。

社内作業と社外作業

社内ではなんらか開発のPJに所属しています。その業務を行いつつ勉強会に参加したり、講演資料を準備したり、と欲張って活動した結果パンクしそうになった時期もありました。
このバランスはもう少し自分でシビアに制御しないといけないと感じた1年でした。

あと、自分はエンジニアとして頑張りたいと強く思った1年でした。
特に管理職になりたいと思ったこともないですが1年通じて色々と経験した結果、この先もエンジニアとして新しい技術に触れていたいと思っています。
今はやはり「運用自動化」という分野でしょうか、縁の下の力持ち的な分野が性格的に好きなんでしょうね。
主信号・主サービスを裏で支える技術側、この分野に強い自分になりたいと今は思っています。

インプットとアウトプット

2019年は個人的にはあまり新しいインプットはできず、2017,2018年にインプットした内容を製品化してただただアウトプットし続けた1年だった気がします。
もう少し新しいインプットをしたかったです。
インプットにははただ「知る」という事と、実際に手を動かしてハマって作業して、なんとなく「体感する」事と2種類あると思っています。
体感するインプットはほとんどできていない1年だったと思います。

エンジニアとパパ

昨年から今に至るまで現在進行形ですが、今ほど学習意欲が高い時期は自分の社会人歴の中でもありません。
ただ冒頭書いた2人の宝が一番手の掛かる時期なのでこのバランスがある意味1年通じて苦労しました。
先輩パパに相談すると、「子供の小さい時はできる限り一緒にいてあげた方がいい、すぐに手を離れるよー」と皆さま共通してアドバイスくれます。

今自分は36で、息子(3)、娘(1)という状況を考えると、40歳位まではこの葛藤に苦しみながら過ごすのだと思います。とはいえ結論としては家族第一と割り切っている自分がいます。ただしばらくは悩みながら過ごすのだろうと思います。

40歳で息子(7)、娘(5) かー。。。
想像すると楽しみだったりもしますね。

2020年の抱負

書きなぐってみました。
文は全然整理していませんが、吐き出してみると気持ちは少しだけ整理できたような気がします。
2020年の抱負としては

  • 「運用自動化」という分野で新しいインプットを体感する
  • Ansibleに1エンジニアとしてもう少し関わりが深くなれるようにする
  • 2019年の素敵な出会いをなんらか形としてアウトプットできるように頑張る
  • 月1度はブログアップできるように頑張ってみる
  • 本をちゃんと読む(積読しすぎない)
  • 土日、休みは家族優先、たくさん子供と遊ぶ
  • 健康第一(痩せたい)
  • ランニングイベントなんか1つ参加(10㎞かハーフ位)

といった所でしょうか。

いいエンジニアになれるように精進する1年にしたいです。

今年も頑張ろう!

f:id:naka-shin1:20200104014534j:plain
ふぅ(5歳)

続・Playbookで指定できる文字について の話

これは Ansible Advent Calendar 2019 の11日目の記事となります。

qiita.com

いつの間にかその2、その3もできてますね。

Ansible 2 Advent Calendar 2019 - Qiita

Ansible 3 Advent Calendar 2019 - Qiita

はじめに

今年の7月にAnsibleのコミュニティイベントでLT登壇の機会がありました。

speakerdeck.com

内容としては
・①network_cliプラグインの内部の動き
・②Playbookで指定できる文字についての話

と5分で2つの内容を取り扱ったのですが、やはり時間的に無理がありまして、どちらかの内容だけに特化すればよかったと後日反省しました。
network_cliプラグインについては自分としてはとっても好きな部分なので、この先またなんらかの形でアウトプットができればとも思うのですが、②についてはLTの内容があまりにも不完全燃焼だったので、この場を借りて本来もう少し親切に書きたかった部分についてまとめておこうと思います。

結論はLT内容と変わりません

事前準備の情報

モジュールオプションのlist型 について

今回「Playbookで指定できる文字」で触れる部分ですが、もっと具体的にいうと「list型」で指定できる文字種となります。
これは例えばネットワーク機器で状態取得系のコマンドを指定する ios_commandモジュールのcommandsオプションであったり、telnetモジュールのcommandオプションなどが使っている型となります。
ios_commandでは、 「List of commands to send to the remote ios device over~」
と説明もされていますね。
また、 ソース上ではtype='list'と指定している部分のオプションとなります。

    argument_spec = dict(
        commands=dict(type='list', required=True),

少し補足ですが、各モジュールが提供するオプションにはそれぞれ型があり、型によって指定できるパラメータが定義されます。
この部分は、int型choices型(選択式)bool型など色々とありますが、今回取り扱うlist型は複数のコマンドを指定する場合に使われる型なので、比較的馴染みがあるかと思います。
ちょっと癖のある、bool型などがYAMLフォーマット(Playbook)でどう扱われるか、についてはてくなべさんの記事でも取り上げられています。

tekunabe.hatenablog.jp ※上記エントリまとめ部分のYAMLフォーマットに対して指定した値がどう判断されるか

list型 をPlaybook内で指定する方法

話を戻して
今回取り扱うlist型をPlaybookに記載する方法についてですが、恐らく以下の3パターンかと思っています。

①そのまま記載

  - name: playbook pattern 1
    xxx_command:
      commands:
      - show version

②シングルコーテーション囲み

  - name: playbook pattern 2
    xxx_command:
      commands:
      - 'show version'

③ダブルコーテーション囲み

  - name: playbook pattern 3
    xxx_command:
      commands:
      - "show version"

本記事について

伝えたい内容

この3パターンについて、
・指定可能な文字種が異なり
・送信可能な場合においても微妙にエスケープ方法が異なります
というのが本記事で扱う内容となります。

普段あまり困らないかもしれませんが、複雑な表現(例えば正規表現など)をPlaybookで記載する時などにお役に立てば幸いかなと。

注意

Playbookで指定できる文字について、はansibleコマンドansible-playbookコマンドが実行できるまでの内容となります。
--syntax-checkを通すまでの部分
Playbookが正常に実行された後は、ターゲット(のシェル)がその文字を解釈できるのかという別の要素も絡んでくる為、本記事ではあくまで「Playbookで指定できる文字」についての内容となります。

f:id:naka-shin1:20191210201654p:plain

検証

検証環境

Ansible:2.9.0
Python :3.7.4
Module :ios_command

Playbook毎の使用文字種

それぞれの指定方法で、以下の文字列を指定して送信可能かどうかを確認しました
可視化文字列全てです。

!#"$%&'()*+,-./0123456789:;<=>?@A BCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghIjklmnopqrstuvwxyz{|}~

※大文字AとBの間に半角スペース含んでいます。

これをPlaybook化します。

①そのまま記載

    ios_command:
      commands:
        - !#"$%&'()*+,-./0123456789:;<=>?@A BCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghIjklmnopqrstuvwxyz{|}~

と、明らかにシンタックスハイライトの時点で通らなそうですよね --syntax-checkしても当然エラーとなります。

ERROR! Syntax Error while loading YAML.
  expected URI, but found '#'

The error appears to be in '/xxx/xxx/xxx/ios_command.yml': line 19, column 12, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

      commands:
        - !#"$%&'()*+,-./0123456789:;<=>?@A BCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghIjklmnopqrstuvwxyz{|}~
           ^ here

なんか#で怒られてますね。
前から順番に#を削っても"が怒られ、"を削っても&が怒られ、とこのパターンでは全ての文字種を送付するのは難しそうです。

②シングルコーテーション囲み

    ios_command:
      commands:
        - '!#"$%&'()*+,-./0123456789:;<=>?@A BCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghIjklmnopqrstuvwxyz{|}~'

これも、そのまま指定して実行するとエラーとなります。

The offending line appears to be:

      commands:
        - '!#"$%&'()*+,-./0123456789:;<=>?@A BCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghIjklmnopqrstuvwxyz{|}~'
                  ^ here

ですが、
シングルコーテーション'はシングルコーテーション'エスケープできるので、以下のように書くとシンタックスエラーを回避できます。
※分かりにくいかもしれませんが、7つ目に指定しているシングルコーテーションを2回書いています。
※ブログ上のシンタックスハイライトもエスケープ前と比較してそれらしくなっている気がします。

    ios_command:
      commands:
        - '!#"$%&''()*+,-./0123456789:;<=>?@A BCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghIjklmnopqrstuvwxyz{|}~'

③ダブルコーテーション囲み

    ios_command:
      commands:
        - "!#"$%&'()*+,-./0123456789:;<=>?@A BCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghIjklmnopqrstuvwxyz{|}~"

これもそのまま実行するエラーとなります。「②シングルコーテーション囲み」よりもエラーが激しく、きちんとエスケープしなさいと例まで出ています。

      commands:
        - "!#"$%&'()*+,-./0123456789:;<=>?@A BCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghIjklmnopqrstuvwxyz{|}~"
              ^ here
We could be wrong, but this one looks like it might be an issue with
unbalanced quotes. If starting a value with a quote, make sure the
line ends with the same set of quotes. For instance this arbitrary
example:

    foo: "bad" "wolf"

Could be written as:

    foo: '"bad" "wolf"'

ダブルコーテーションは、バックスラッシュ\でダブルコーテーション"とバックスラッシュ\エスケープできるので、以下のように書くとシンタックスエラーを回避できます。

    ios_command:
      commands:
        - "!#\"$%&'()*+,-./0123456789:;<=>?@A BCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghIjklmnopqrstuvwxyz{|}~"

まとめ

Playbookのlist型で指定できる文字種は以下の点に注意すれば可視化文字全部指定できます。

指定方法 ポイント
①そのまま指定 色々と送れない文字あり
②シングルコーテーション囲み シングルコーテーション'
シングルコーテーション'エスケープ
③ダブルコーテーション囲み ダブルコーテーション"とバックスラッシュ\
バックスラッシュ\エスケープ

シンタックスエラーではまってしまった時、私は、
「とりあえずシングルコーテーションで囲って、シングルコーテーションはシングルコーテーションでエスケープ」
する事で、多少複雑な指定をしてもPlaybook実行時やシンタックスチェックでハマらなくなりました。

という事で需要があるか分かりませんが、以上となります。