ときどきAnsible日記

主にITインフラ基盤の自動化に関する事を書いているブログです

DevOpsについて~現場で起こっている問題~

お疲れ様です。伊藤です。

この度グループ会社内で、Ansible関連の説明会を行うことになりました。で、うちのグループなんですが基本的にシステム開発者メインで、インフラ技術者があまりいらっしゃいませんのでシステム開発者にも興味のある内容を、ということでDevOpsに絡めて説明を行います。

というわけでこちらでもちょっとDevOpsについてまとめておこうと思います。
そもそもDevOpsとは?というところからですが、ウィキペディアによると以下の通りになります。

DevOps(デブオプス)は、ソフトウェア開発手法の一つ。開発 (Development) と運用 (Operations) を組み合わせたかばん語であり、開発担当者と運用担当者が連携して協力する(さらに両担当者の境目もあいまいにする)開発手法をさす。厳密な定義は存在しておらず、抽象的な概念に留まっている。ソフトウェアのビルド、テスト、そしてリリースの文化と環境を以前よりも迅速に、頻繁に、確実に発生する確立を目指している。 また、DevOpsにビジネス部門を追加したBizDevOpsというワードも広がりつつある。

あまり明確な定義はなさそうですが、「システム開発者とインフラ技術者の垣根をなくす」という意味だと認識しております。もうちょっと具体的に言うと、開発者がシステムの設定変更(ユーザ追加したり、環境変数変えたり)なんかも行う、という感じかと思います。
(インフラ技術者は環境の構築やその後の保守運用を行いますが、Operationとは保守運用部分のことを言っています)

今までのシステム開発の現場によくある構図は下記のような形だと思います。まあいろいろな理由があって大体仲が悪いです(笑)
f:id:pj_doaa:20180131125122p:plain

DevOpsだとこうなる!
f:id:pj_doaa:20180131125206p:plain

ではなぜそんなことが謡われているか、というところになるかと思います。そのあたりを私の主観満載で今までの経験をもとに感じたことをまとめておきます。

基本的にシステムの開発環境はテスト環境、本番環境に分かれます。まあ、現場によってはステージング環境とか検証環境とか色々ありますが、通常の現場で行くとテストと本番は必ず分かれてるかなと。
で、これも現場によって違うのですが、大体はテスト環境はインフラ技術者が初期構築を行った後は、開発者側で設定変更を行うことが多いです。なぜなら開発の段階で追加の環境変数が必要だったり、テストを行うためにユーザを増やしたり、ということをいちいちインフラチームにお願いしていたら開発も遅れるし、双方の手間になるので。
f:id:pj_doaa:20180131123035p:plain

ところが本番環境の構築時には設定変更は大体が、インフラ技術者が行うことになります。そうするとテスト環境で行った設定変更が漏れる、ということが発生します。
f:id:pj_doaa:20180115101807p:plain


こういった問題(もちろんこれだけではないですが)をなくすために、システム開発者が本番環境の設定変更やその後の環境管理も行う、というのがDevOpsが求められている理由だと思っています。それを実現するためにAnsibleやDockerの技術が利用できますが、そちらについてはまた別の記事で記述したいと思います。

それではお疲れ様でした。

AnsibleのModule:win_lineinfile

お疲れ様です。伊藤です。

すっかり年の瀬も近づき、師走の騒がしさも増してきた今日この頃。皆様いかがお過ごしでしょうか。
緩い内容をやるといった舌の根も乾かないうちですが、Moduleの記事を載せます。


基本的にAnsibleのModueは頭にwin_がついているものはWindows専用です。Windows以外のOS(と言ってもほとんどLinuxですが)では管理対象側で実行されるスクリプトpythonですが、Windowsの場合はPowerShellになります。なので、動くものは完全別物です。現在Moduleは1137本ほどありますが(2017/6/5時点)その中でWindowsの対象のものは56本しかありません。つまりLinuxでできることのホンの一部しかWindowsでできることはない、とご認識ください。

その中でもlineinfileはテキストの編集ができるModueですので、汎用性も高く比較的使う機会も多いかと思いますのでこちらに乗せたいと思います。


まずはModuleの解説です。
このモジュールは、ファイルを検索して、行が存在するかどうかを確認します。
これは、ファイル内の1行だけを変更したい場合に、主に有効です。

とのこと。つまりは1コマンドで編集できるのは1行のみ。複数行編集はできませんよと言っていますね。また、該当する行が存在する前提で話が進んでいます。これは以前記述したlineinfileと同じ問題(Ansibleでファイル編集を行いたい~そして見つかる致命的な弱点とは~ - ときどきAnsible日記)が発生する事を表しています。


とはいえ、今のところはこのModuleを使うほかはありません。というわけで引数は下記になります。

パラメータ 必須 デフォルト 選択肢 備考
backrefs no no yes or no state = presentとともに使用されます。 設定されている場合、行には、正規表現が一致した場合に読み込まれるバックリファレンス(定位置と名前付きの両方)を含めることができます。 このフラグは、モジュールの動作をわずかに変更します。 insertbeforeとinsertafterは無視され、regexpがファイル内のどこにも一致しない場合、ファイルは変更されません。正規表現が一致すると、最後に一致した行は、展開された行パラメータに置き換えられます。
backup no no yes or no タイムスタンプ情報を含むバックアップファイルを作成して、何らかの形で誤って元のファイルを戻すことができます。
create no no yes or no state = present で使用されます。 指定した場合、ファイルはまだ作成されていない場合に作成されます。 デフォルトでは、ファイルが見つからない場合は失敗します。
encoding no auto 操作するソーステキストファイルのエンコーディングを指定します。 デフォルトのautoを指定すると、モジュールはソースファイルのエンコードを自動検出し、変更されたファイルが同じエンコードで書き込まれるようにします。明示的なエンコーディングは、.NET FrameworkのSystem.Text.Encoding.GetEncoding()メソッドに渡す有効な値である文字列として渡すことができます。https://msdn.microsoft.com/en-us/library/systemを参照してください。これは、特定のエンコーディングで新しいファイルを作成する場合は、create = yesを使用すると最も便利です。 特定のエンコーディングを指定せずにcreate = yesを指定すると、デフォルトエンコーディングUTF-8、BOMなし)が使用されます。
insertafter no EOF EOF or *regex* state = presentとともに使用されます。 指定すると、指定された正規表現の最後の一致の後に行が挿入されます。 特別な値があります。 ファイルの最後に行を挿入するためのEOF。指定された正規表現にマッチがない場合は、代わりにEOFが使用されます。 バックファイルでは使用できません。
insertbefore no BOF or *regex* state = presentとともに使用されます。 指定すると、指定された正規表現の最後の一致の前に行が挿入されます。 値は利用可能です。 ファイルの先頭に行を挿入するためのBOF。指定された正規表現にマッチがない場合、その行はファイルの最後に挿入されます。 バックファイルでは使用できません。
line no state = present に必須です。 ファイルに挿入/置換する行。 backrefs が設定されている場合、正規表現が一致すると regexp キャプチャグループで展開される後方参照を含むことがあります。
newline no windows windows or unix 変更されたファイルに使用する行区切りスタイルを指定します。 これは、デフォルトではWindowsの行区切り文字(\ r \ n)になります。 指定された行区切り記号は、入力ファイルに表示される元の行区切り記号に関係なく、ファイル出力に使用されることに注意してください。
path yes 変更するファイルのパス。行の二重引用符を使用する場合は、Windowsパス区切り文字\を\\としてエスケープする必要があります。2.3以前では、このオプションはdest、destfile、およびnameとしてしか使用できませんでした。
regexp no ファイルのすべての行を検索する正規表現。 state = presentの場合、見つかった場合に置換するパターン。 見つかった最後の行だけが置換されます。 state = absentの場合、削除する行のパターン。 .NET互換の正規表現を使用します。 https://msdn.microsoft.com/en-us/library/hs600312%28v=vs.110%29.aspxを参照してください。
state no present present or absent 行が存在するかどうか。
validate no None 場所にコピーする前に実行する検証。 現在のファイルを確認するには、コマンドで%sを使用します。コマンドは安全に渡され、拡張やパイプなどのシェル機能は動作しません。

ほとんどlineinfileと同じですが、encoding辺りがWindowsだとキモになってきそうです。例によって行数指定などはできずに、検索した文字の前後に1行追加する、という形になります。

続いて記載例です。

# 2.3より前には、 'path'の代わりに 'dest'、 'destfile'または 'name'オプションを使用しました。
- win_lineinfile:
    path: C:\temp\example.conf
    regexp: '^name='
    line: 'name=JohnDoe'

- win_lineinfile:
    path: C:\temp\example.conf
    regexp: '^name='
    state: absent

- win_lineinfile:
    path: C:\temp\example.conf
    regexp: '^127\.0\.0\.1'
    line: '127.0.0.1 localhost'

- win_lineinfile:
    path: C:\temp\httpd.conf
    regexp: '^Listen '
    insertafter: '^#Listen '
    line: Listen 8080

- win_lineinfile:
    path: C:\temp\services
    regexp: '^# port for http'
    insertbefore: '^www.*80/tcp'
    line: '# port for http by default'

# 特定のエンコーディングで存在しない場合はファイルを作成する
- win_lineinfile:
    path: C:\temp\utf16.txt
    create: yes
    encoding: utf-16
    line: This is a utf-16 encoded file

# ファイルに行を追加し、結果のファイルがunix行区切り文字を使用していることを確認する
- win_lineinfile:
    path: C:\temp\testfile.txt
    line: Line added to file
    newline: unix

# backrefsを使用して行を更新する
- win_lineinfile:
    path: C:\temp\example.conf
    backrefs: yes
    regexp: '(^name=)'
    line: '$1JohnDoe'
Notes

以上です。本年のブログ更新はこれで終了となります。
半年間ブログを見てくださいました皆様、誠にありがとうございます。アクセス数をみてモチベーションを維持させていただいておりました。来年からも細々とですが記事は上げていきますので皆さま引き続き温かい目で見ていただけると幸いです。

それでは皆様よいお年を。