tag:crieit.net,2005:https://crieit.net/tags/Ansible/feed 「Ansible」の記事 - Crieit Crieitでタグ「Ansible」に投稿された最近の記事 2021-05-04T11:10:50+09:00 https://crieit.net/tags/Ansible/feed tag:crieit.net,2005:PublicArticle/17055 2021-05-04T11:10:50+09:00 2021-05-04T11:10:50+09:00 https://crieit.net/posts/ssh-publickey-authentication-require-password-2-20210503 公開鍵認証でSSH接続しようとしたのにパスワードを求められた 2 <p><a target="_blank" rel="nofollow noopener" href="https://labor.ewigleere.net/2020/10/23/ssh_publickey_authentication_require_password/">以前も似たような現象に遭遇</a>しましたが、原因が少し異なっていたので書き留めておきます。</p> <h2 id="経緯・状況"><a href="#%E7%B5%8C%E7%B7%AF%E3%83%BB%E7%8A%B6%E6%B3%81">経緯・状況</a></h2> <p>前回の状況と同じ状況です。 Ansible でリモートサーバを操作しようとしましたが、公開鍵認証のはずなのにパスワードを求められてしまいました。</p> <h2 id="現象"><a href="#%E7%8F%BE%E8%B1%A1">現象</a></h2> <pre><code class="bash"># ansible-playbook -i /workspace/ansible/targets/hosts /workspace/ansible/main.yml -u REMOTE_USER --private-key=&quot;/root/.ssh/PRIVATE_KEY&quot; -K BECOME password: PLAY [Settings vsftpd and httpd] ********************************************************************************** TASK [Gathering Facts] ********************************************************************************************The authenticity of host 'ssh.example.com (ssh.example.com)' can't be established. ECDSA key fingerprint is SHA256:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. Are you sure you want to continue connecting (yes/no/[fingerprint])? yes fatal: [ssh.example.com]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: Warning: Permanently added 'ssh.example.com' (ECDSA) to the list of known hosts.\r\[email protected]: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).", "unreachable": true} PLAY RECAP ********************************************************************************************************ssh.example.com : ok=0 changed=0 unreachable=1 failed=0 skipped=0 rescued=0 ignored=0 </code></pre> <p>プレイブックを実行しようとすると <code>Permission denied</code> で怒られました。</p> <pre><code class="bash"># ssh -i ~/.ssh/PRIVATE_KEY [email protected] [email protected]'s password: Permission denied, please try again. [email protected]'s password: Activate the web console with: systemctl enable --now cockpit.socket Last login: DDD MMM dd hh:ii:ss yyyy from LOCAL_HOST [REMOTE_USER@ssh ~]$ </code></pre> <p>SSH接続 では公開鍵認証のはずなのにパスワードを求められます。</p> <h2 id="対処"><a href="#%E5%AF%BE%E5%87%A6">対処</a></h2> <p><code>/var/log/secure</code> を確認すると、 <code>Authentication refused: bad ownership or modes for directory /home/REMOTE_USER/.ssh</code> のエラーメッセージが記録されていました。</p> <ul> <li><a target="_blank" rel="nofollow noopener" href="http://shoyan.hatenablog.com/entry/20111117/1321546001">sshの公開鍵認証でServer refused our keyが出る問題について - Simple, Slowly</a></li> </ul> <p>調べてみると、 <code>.ssh</code>ディレクトリ の権限が誤った設定になっているとこのエラーが起きるとのこと。</p> <p><code>.ssh/authorized_keys</code> は <code>600</code> にしていましたが、ディレクトリの方は見落としていました。確認したところ、 <code>775</code> でした。</p> <p>これを <code>chmod 755 /home/REMOTE_USER/.ssh</code> で修正。</p> <p>結果、公開鍵認証が成功するようになり、 Ansible のプレイブックも正常に動作するようになりました。</p> <h2 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h2> <ul> <li><a target="_blank" rel="nofollow noopener" href="http://shoyan.hatenablog.com/entry/20111117/1321546001">sshの公開鍵認証でServer refused our keyが出る問題について - Simple, Slowly</a></li> </ul> arm-band tag:crieit.net,2005:PublicArticle/16416 2020-12-24T00:28:56+09:00 2020-12-24T00:29:36+09:00 https://crieit.net/posts/ansible-remove-user-and-settings-of-vsftpd-apache-20201224 vsftpd と Apache の設定を削除しLinuxユーザも削除する <p>以前取り上げた<a href="https://crieit.net/posts/ansible-settings-vsftpd-and-apache-20201202">Ansible を使って FTPユーザの作成と Apache の仮想サイトの設定をする</a>の逆方向バージョンです。</p> <p>つまり、</p> <ul> <li>Linuxユーザを削除</li> <li>上記ユーザを vsftpdユーザ からも削除</li> <li>Apache の仮想サイトの設定と該当ディレクトリのデータを全て削除</li> </ul> <p>を行うタスクを作ろう、と考えました。</p> <p>これは、上記のプレイブックを一時的なテスト環境として作った後、削除することも往々にしてあり、手動で削除するのが面倒になってきたからです。</p> <h2 id="前提"><a href="#%E5%89%8D%E6%8F%90">前提</a></h2> <p>テストに利用するサーバは前の記事と同じサーバで、該当プレイブックによって vsftpd や Apache が設定されている、という状況を想定しています。</p> <h2 id="設定"><a href="#%E8%A8%AD%E5%AE%9A">設定</a></h2> <h3 id="ディレクトリ階層"><a href="#%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E9%9A%8E%E5%B1%A4">ディレクトリ階層</a></h3> <pre><code class="bash">PROJECT_ROOT/ ├ workspace/ │ ├ entrypoint.sh │ └ ansible/ │ ├ (諸々元のプレイブックと同じ構造) │ ├ main.yml // Ansible の設定用 playbook │ └ resset.yml // 今回追加した削除用タスク │ ├ docker-compose.yml └ Dockerfile </code></pre> <p>ほぼ前の記事の通り、というか同じプロジェクトをそのまま流用しています。元々の意図が設定用プレイブックに対して設定を元に戻すためのものなので、同じ場所にあった方が都合は良いと考えました。</p> <p>ただ、リセットするためのタスクは設定用タスクほど複雑ではないのでタスクを分割せずに1つのファイルに既述することにしました。</p> <h3 id="ansible/vars/param_vars.yml"><a href="#ansible%2Fvars%2Fparam_vars.yml">ansible/vars/param_vars.yml</a></h3> <pre><code class="yml">username: USERNAME password: Password1234 rootdirectory: sample_site domain: www.sample.jp ipaddress: 192.0.2.1 portnum: 80 </code></pre> <p>上記ディレクトリ構造より、設定用のプレイブックに使用する変数ファイルがあるため、これをそのまま流用します。</p> <h3 id="ansible/resset.yml"><a href="#ansible%2Fresset.yml">ansible/resset.yml</a></h3> <pre><code class="yml">- name: Remove vsftpd and httpd settings become: yes become_user: ADMIN_USER become_method: su hosts: - add_vhost_servers vars_files: ./vars/param_vars.yml tasks: - name: Remove user user: name: "<span>{</span><span>{</span> username <span>}</span><span>}</span>" state: absent remove: yes - name: Remove user in vsftpd user_list blockinfile: path: /etc/vsftpd/user_list create: yes insertafter: EOF marker: "# {mark} ANSIBLE basic setup: <span>{</span><span>{</span> username <span>}</span><span>}</span>" block: "" - name: Remove user_conf file file: path: "/etc/vsftpd/user_conf/<span>{</span><span>{</span> username <span>}</span><span>}</span>" state: absent - name: Restart vsftpd systemd: name: vsftpd.service state: restarted daemon_reload: yes - name: Remove Apache virtual site data file: path: "/var/www/<span>{</span><span>{</span> rootdirectory <span>}</span><span>}</span>" state: absent - name: Remove Apache conffile file: path: "/etc/httpd/conf.d/<span>{</span><span>{</span> rootdirectory <span>}</span><span>}</span>.conf" state: absent - name: Restart httpd systemd: name: httpd.service state: reloaded daemon_reload: yes </code></pre> <p>今回のメイン。削除用のタスクです。</p> <p>やっていることは冒頭で記した通り。</p> <h2 id="動作確認"><a href="#%E5%8B%95%E4%BD%9C%E7%A2%BA%E8%AA%8D">動作確認</a></h2> <h3 id="削除用プレイブックを走らせる前"><a href="#%E5%89%8A%E9%99%A4%E7%94%A8%E3%83%97%E3%83%AC%E3%82%A4%E3%83%96%E3%83%83%E3%82%AF%E3%82%92%E8%B5%B0%E3%82%89%E3%81%9B%E3%82%8B%E5%89%8D">削除用プレイブックを走らせる前</a></h3> <pre><code class="bash"># less /etc/passwd ## 略 USERNAME:x: </code></pre> <p>設定用プレイブックで追加されたユーザがいることを確認。</p> <pre><code class="bash"># less /etc/vsftpd/user_list ## 略 # BEGIN ANSIBLE basic setup: USERNAME USERNAME # END ANSIBLE basic setup: USERNAME </code></pre> <p>ここにも。</p> <pre><code class="bash"># ls -al /etc/vsftpd/user_conf/ 合計 4 drwxrwxr-x 2 ADMIN_USER ADMIN_USER 23 MM月 DD hh:ii . drwxr-xr-x 3 ADMIN_USER ADMIN_USER 150 MM月 DD hh:ii .. -rw-rw-r-- 1 ADMIN_USER ADMIN_USER 107 MM月 DD hh:ii USERNAME # less /etc/vsftpd/user_conf/USERNAME # BEGIN ANSIBLE basic setup: USERNAME local_root=/var/www/sample_site # END ANSIBLE basic setup: USERNAME </code></pre> <p>ここにも。</p> <pre><code class="bash"># ls -al /var/www/ 合計 4 drwxr-xr-x 5 ADMIN_USER ADMIN_USER 51 MM月 DD hh:ii . drwxr-xr-x. 22 ADMIN_USER ADMIN_USER 4096 MM月 DD hh:ii .. drwxr-xr-x 2 ADMIN_USER ADMIN_USER 6 MM月 DD hh:ii cgi-bin drwxr-xr-x 3 ADMIN_USER ADMIN_USER 35 MM月 DD hh:ii html drwxr-xr-x 3 ADMIN_USER ADMIN_USER 17 MM月 DD hh:ii sample_site # ls -al /etc/httpd/conf.d/ 合計 36 drwxr-xr-x 2 ADMIN_USER ADMIN_USER 137 MM月 DD hh:ii . drwxr-xr-x 5 ADMIN_USER ADMIN_USER 92 MM月 DD hh:ii .. -rw-r--r-- 1 ADMIN_USER ADMIN_USER 366 MM月 DD hh:ii README -rw-r--r-- 1 ADMIN_USER ADMIN_USER 2926 MM月 DD hh:ii autoindex.conf -rw-r--r-- 1 ADMIN_USER ADMIN_USER 1252 MM月 DD hh:ii php.conf -rw-r--r-- 1 ADMIN_USER ADMIN_USER 9443 MM月 DD hh:ii ssl.conf -rw-r--r-- 1 ADMIN_USER ADMIN_USER 1252 MM月 DD hh:ii userdir.conf -rw-r--r-- 1 ADMIN_USER ADMIN_USER 824 MM月 DD hh:ii welcome.conf -rw-r--r-- 1 ADMIN_USER ADMIN_USER 439 MM月 DD hh:ii sample_site.conf # less /etc/httpd/conf.d/sample_site.conf <VirtualHost 192.0.2.1:80> DocumentRoot "/var/www/sample_site/web" ServerName www.sample_site.jp ServerAlias sample_site.jp ScriptAlias /cgi-bin/ /var/www/sample_site/web/cgi-bin/ RewriteEngine on RewriteCond %{HTTP_HOST} ^sample_site\.jp$ RewriteRule ^(.*)$ http://www.sample_site.jp$1 [R=301,L] <Directory "/var/www/sample_site/web"> allow from all AllowOverride All Options FollowSymLinks Require all granted </Directory> </VirtualHost> </code></pre> <p>Apache 側にも仮想サイトの設定があり、仮想サイト用のディレクトリが切られていることを確認。</p> <p>FTPでログインしたり、 <code>hosts</code> で名前解決して仮想サイトにアクセスできることを確認。</p> <p>一通りプレイブックの設定通りです。</p> <h3 id="削除用プレイブックを走らせる"><a href="#%E5%89%8A%E9%99%A4%E7%94%A8%E3%83%97%E3%83%AC%E3%82%A4%E3%83%96%E3%83%83%E3%82%AF%E3%82%92%E8%B5%B0%E3%82%89%E3%81%9B%E3%82%8B">削除用プレイブックを走らせる</a></h3> <h4 id="Dry run"><a href="#Dry+run">Dry run</a></h4> <pre><code class="bash"># ansible-playbook -i /workspace/ansible/targets/hosts /workspace/ansible/reset.yml -u SSH_REMOTEUSER --private-key=&quot;/root/.ssh/PRIVATE_KEY&quot; -K --check BECOME password: PLAY [Remove vsftpd and httpd settings] *************************************************************************** TASK [Gathering Facts] ********************************************************************************************ok: [192.0.2.1] TASK [Remove user] ************************************************************************************************changed: [192.0.2.1] TASK [Remove user in vsftpd user_list] ****************************************************************************changed: [192.0.2.1] TASK [Remove user_conf file] **************************************************************************************changed: [192.0.2.1] TASK [Restart vsftpd] *********************************************************************************************changed: [192.0.2.1] TASK [Remove Apache virtual site data] ****************************************************************************changed: [192.0.2.1] TASK [Remove Apache conffile] *************************************************************************************changed: [192.0.2.1] TASK [Restart httpd] **********************************************************************************************changed: [192.0.2.1] PLAY RECAP ********************************************************************************************************192.0.2.1 : ok=8 changed=7 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 </code></pre> <p>まずは Dry run でエラーが出ないことを確認。大丈夫そうです。</p> <h4 id="本番"><a href="#%E6%9C%AC%E7%95%AA">本番</a></h4> <pre><code class="bash"># ansible-playbook -i /workspace/ansible/targets/hosts /workspace/ansible/reset.yml -u SSH_REMOTEUSER --private-key=&quot;/root/.ssh/PRIVATE_KEY&quot; -K BECOME password: PLAY [Remove vsftpd and httpd settings] *************************************************************************** TASK [Gathering Facts] ********************************************************************************************ok: [192.0.2.1] TASK [Remove user] ************************************************************************************************changed: [192.0.2.1] TASK [Remove user in vsftpd user_list] ****************************************************************************changed: [192.0.2.1] TASK [Remove user_conf file] **************************************************************************************changed: [192.0.2.1] TASK [Restart vsftpd] *********************************************************************************************changed: [192.0.2.1] TASK [Remove Apache virtual site data] ****************************************************************************changed: [192.0.2.1] TASK [Remove Apache conffile] *************************************************************************************changed: [192.0.2.1] TASK [Restart httpd] **********************************************************************************************changed: [192.0.2.1] PLAY RECAP ********************************************************************************************************192.0.2.1 : ok=8 changed=7 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 </code></pre> <p>続いて本番実行。完了しました。</p> <h3 id="削除用プレイブックを走らせた後"><a href="#%E5%89%8A%E9%99%A4%E7%94%A8%E3%83%97%E3%83%AC%E3%82%A4%E3%83%96%E3%83%83%E3%82%AF%E3%82%92%E8%B5%B0%E3%82%89%E3%81%9B%E3%81%9F%E5%BE%8C">削除用プレイブックを走らせた後</a></h3> <p>それでは、念のため確認していきたいと思います。</p> <pre><code class="bash"># less /etc/passwd </code></pre> <p>設定したユーザが消えていることを確認。</p> <pre><code class="bash"># ls -al /etc/vsftpd/user_conf/ 合計 0 drwxrwxr-x 2 ADMIN_USER ADMIN_USER 6 MM月 DD hh:ii . drwxr-xr-x 3 ADMIN_USER ADMIN_USER 150 MM月 DD hh:ii .. # less /etc/vsftpd/user_list ## 略 nobody </code></pre> <p>vsftpd の設定も消えています。OK。</p> <pre><code class="bash"># ls -al /var/www/ 合計 4 drwxr-xr-x 4 ADMIN_USER ADMIN_USER 33 MM月 DD hh:ii . drwxr-xr-x. 22 ADMIN_USER ADMIN_USER 4096 MM月 DD hh:ii .. drwxr-xr-x 2 ADMIN_USER ADMIN_USER 6 MM月 DD hh:ii cgi-bin drwxr-xr-x 3 ADMIN_USER ADMIN_USER 35 MM月 DD hh:ii html # ls -al /etc/httpd/conf.d/ 合計 32 drwxr-xr-x 2 ADMIN_USER ADMIN_USER 114 MM月 DD hh:ii . drwxr-xr-x 5 ADMIN_USER ADMIN_USER 92 MM月 DD hh:ii .. -rw-r--r-- 1 ADMIN_USER ADMIN_USER 366 MM月 DD hh:ii README -rw-r--r-- 1 ADMIN_USER ADMIN_USER 2926 MM月 DD hh:ii autoindex.conf -rw-r--r-- 1 ADMIN_USER ADMIN_USER 1252 MM月 DD hh:ii php.conf -rw-r--r-- 1 ADMIN_USER ADMIN_USER 9443 MM月 DD hh:ii ssl.conf -rw-r--r-- 1 ADMIN_USER ADMIN_USER 1252 MM月 DD hh:ii userdir.conf -rw-r--r-- 1 ADMIN_USER ADMIN_USER 824 MM月 DD hh:ii welcome.conf </code></pre> <p>仮想サイトのディレクトリは丸ごと消えて、設定ファイルも消えました。OKです。</p> <p>当然、FTPでログインできなくなっていますし、ブラウザでアクセスすると仮想サイトが消えたので代理の仮想サイトが応答してきました。OKです。</p> <hr /> <p>以上より、一通り意図通りの動作になったことを確認できました。</p> <h2 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h2> <h3 id="Ansible"><a href="#Ansible">Ansible</a></h3> <h4 id="ユーザ削除"><a href="#%E3%83%A6%E3%83%BC%E3%82%B6%E5%89%8A%E9%99%A4">ユーザ削除</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/moiwa/items/bab0f4c8d0dbf361afa4">Ansible ~userモジュール~ - Qiita</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/KeijiYONEDA/items/011b78b12022202d4ea1">【Ansible】開発者ユーザー追加・削除のベスト・プラクティスを考える - Qiita</a></li> </ul> <h4 id="ファイル削除"><a href="#%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E5%89%8A%E9%99%A4">ファイル削除</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://tekunabe.hatenablog.jp/entry/2019/03/03/ansible_file_intro#-%E4%BE%8B2-%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%84%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E3%82%92%E5%89%8A%E9%99%A4%E3%81%99%E3%82%8B">[Ansible] file モジュールの基本的な使い方(ファイルやディレクトリの操作) - てくなべ (tekunabe)</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/waterada/items/4e64cc6f810a92001c95">ansible のモジュール(ファイル操作等)をまとめてみました - Qiita</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://www.greptips.com/posts/1269/">Ansibleのfileモジュールでディレクトリをabsentするのは危険 - grep Tips *</a></li> </ul> <h4 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://tech.smartcamp.co.jp/entry/2019/05/10/215035">Ansible Playbookでユーザ管理(登録・削除)をまるっとやる - SMARTCAMP Engineer Blog</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/volanja/items/54a7dbc75b909e89d8fc">Ansibleの新モジュール replace(置換)を使ってみた。 - Qiita</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://uuutee.net/ansible/howto-replacing-text-with-ansible/">Ansibleでテキスト置換を行ういくつかの方法 | uuutee.log</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://akishin.hatenablog.jp/entry/20130817/1376709924">Ansible で複数行の文字列置換 - akishin999の日記</a></li> </ul> <h3 id="Linuxコマンド"><a href="#Linux%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89">Linuxコマンド</a></h3> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://eng-entrance.com/linux-command-userdel">userdelコマンドについて詳しくまとめました 【Linuxコマンド集】</a></li> </ul> arm-band tag:crieit.net,2005:PublicArticle/16255 2020-12-04T00:13:51+09:00 2020-12-04T00:13:51+09:00 https://crieit.net/posts/ansible-settings-vsftpd-and-apache-20201202 Ansible を使って FTPユーザの作成と Apache の仮想サイトの設定をする <p>Ansible を使って設定を行う例として、 Linuxユーザを作成してFTPユーザとし、 Apache の仮想サイトを作成する部分をやってみたいと思います。</p> <h2 id="前提"><a href="#%E5%89%8D%E6%8F%90">前提</a></h2> <p>対象サーバの LAMP は<a target="_blank" rel="nofollow noopener" href="https://labor.ewigleere.net/2020/07/09/centos7-wordpress-move/">CentOS7.5 + Apache + PHP + MySQL サーバを構築し、WordPressサイトを引っ越す(2018/11/20)</a>のうち</p> <ul> <li>1.初期設定 ~ 4.リポジトリ追加</li> <li>5.vsftpd のうち <ul> <li>5.1.インストール, 5.2.設定</li> </ul></li> <li>6.Apache ~ 11.Webmin</li> <li>12.Apache仮想サイトのうち <ul> <li>12.1.ダミーサイトの作成</li> </ul></li> <li>16.SSH</li> </ul> <p>が既に設定済みの状態のサーバとします(13.Let’s Encrypt ~ 15.WP-CLI は対象外)。</p> <p>また、今回 Ansible で設定するのは</p> <ul> <li>5.vsftpd のうち <ul> <li>5.3.ユーザ設定</li> <li>5.4.ユーザ作成・設定</li> </ul></li> <li>12.Apache仮想サイトのうち <ul> <li>12.2. 仮想サイト作成</li> </ul></li> </ul> <p>の部分を想定しています。</p> <h2 id="設定"><a href="#%E8%A8%AD%E5%AE%9A">設定</a></h2> <h3 id="ディレクトリ階層"><a href="#%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E9%9A%8E%E5%B1%A4">ディレクトリ階層</a></h3> <pre><code class="bash">PROJECT_ROOT/ ├ workspace/ // データ永続化領域 │ ├ entrypoint.sh // Dockerコンテナ起動時に実行するシェルスクリプト │ └ ansible/ // Ansible 用ディレクトリ │ ├ targets/ // リモートホストの情報を収めるディレクトリ │ │ └ hosts // リモートサーバの一覧 (今回は1つのみ) │ │ │ ├ tasks/ // Ansible のタスクを収めるディレクトリ │ │ ├ add_user.yml // Linuxユーザの作成 │ │ ├ vsftpd_user_settings.yml // vsftpd の設定 │ │ └ apache_settings.yml // Apache 仮想サイトの設定 │ │ │ ├ templates/ // Apache 仮想サイト設定のテンプレートを収めるディレクトリ │ │ └ vhost.conf.j2 // Apache 仮想サイト設定のテンプレート │ │ │ ├ vars/ // 各種パラメータ変数の設定を収めるディレクトリ │ │ └ param_vars.yml // 各種パラメータ変数 │ │ │ └ main.yml // Ansible の playbook │ ├ docker-compose.yml // Docker Compose 設定ファイル └ Dockerfile // Dockerfile </code></pre> <p><a target="_blank" rel="nofollow noopener" href="https://labor.ewigleere.net/2020/10/22/build_docker_container_as_ansible_controller/">Ansibleコントロールノード を Dockerコンテナ でビルドし、リモートサーバに公開鍵認証でSSH接続してインストール済みのパッケージの一覧を取得するまで</a>や<a target="_blank" rel="nofollow noopener" href="https://labor.ewigleere.net/2020/11/06/ansible_execute_yum_update/">Ansible を使って yum update を実行する</a>の記事の構造をベースにカスタマイズ。</p> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://github.com/arm-band/philotic_moby_test/tree/yum_update">arm-band/philotic_moby_test at yum_update</a></li> </ul> <p>一揃いを Github に置きました。</p> <h3 id="Dockerfile, docker-compose.yml, entrypoint.sh. ansible/targets/hosts"><a href="#Dockerfile%2C+docker-compose.yml%2C+entrypoint.sh.+ansible%2Ftargets%2Fhosts">Dockerfile, docker-compose.yml, entrypoint.sh. ansible/targets/hosts</a></h3> <p>この辺りはそのまま。 <code>ansible/targets/hosts</code> はグループ名を変更していますが、対となる <code>ansible/main.yml</code> の <code>hosts</code> の指定を変えれば良いだけなので些事。</p> <h3 id="ansible/vars/param_vars.yml"><a href="#ansible%2Fvars%2Fparam_vars.yml">ansible/vars/param_vars.yml</a></h3> <pre><code class="yaml">username: USERNAME password: Password1234 rootdirectory: sample_site domain: www.sample.jp ipaddress: 192.0.2.1 portnum: 80 </code></pre> <p>まずは今回の新顔の変数から。当初は末尾の「備考1: コマンドライン引数を変数に代入する」のように引数でコマンドラインから直接渡すことを考えていましたが、上記の通り6つもあるとそれだけでコマンドが長くなってしまい可読性が下がるので最終的に止めました。</p> <p>代わりに変数を1つのファイルにまとめて、コマンド自体の長さは変わらないように調整しました。</p> <p>この場合、以下の <code>ansible/main.yml</code> で触れますが <code>vars_files: ./vars/param_vars.yml</code> という一行で変数ファイルの読み込みができ、かつそれ以降は <code>vars</code> キーで変数としてそのまま使用できるので導入はわりとすんなり行きました。</p> <h3 id="ansible/main.yml"><a href="#ansible%2Fmain.yml">ansible/main.yml</a></h3> <pre><code class="yaml">- name: Settings vsftpd and httpd become: yes become_user: ADMIN_USER become_method: su hosts: - add_vhost_servers vars_files: ./vars/param_vars.yml tasks: - name: Add Linux User include_tasks: ./tasks/add_user.yml vars: user: "<span>{</span><span>{</span> username <span>}</span><span>}</span>" passwd: "<span>{</span><span>{</span> password <span>}</span><span>}</span>" - name: Settings vsftpd user_list and user_conf include_tasks: ./tasks/vsftpd_user_settings.yml vars: user: "<span>{</span><span>{</span> username <span>}</span><span>}</span>" directory: "<span>{</span><span>{</span> rootdirectory <span>}</span><span>}</span>" - name: Setup Apache conffile include_tasks: ./tasks/apache_settings.yml vars: directory: "<span>{</span><span>{</span> rootdirectory <span>}</span><span>}</span>" url: "<span>{</span><span>{</span> domain <span>}</span><span>}</span>" ip: "<span>{</span><span>{</span> ipaddress <span>}</span><span>}</span>" portnumber: "<span>{</span><span>{</span> portnum <span>}</span><span>}</span>" </code></pre> <p>タスクのメイン部分。基本は前回と同様で、 <code>tasks</code> で指定する各種タスクが置き換わった形です。変数については上記の通り。</p> <h3 id="ansible/tasks/add_user.yml"><a href="#ansible%2Ftasks%2Fadd_user.yml">ansible/tasks/add_user.yml</a></h3> <pre><code class="yaml">- name: Add user, setting password and groups user: name: "<span>{</span><span>{</span> username <span>}</span><span>}</span>" password: "<span>{</span><span>{</span> password | password_hash('sha512') <span>}</span><span>}</span>" groups: apache append: yes </code></pre> <p><code>ansible/main.yml</code> から渡ってきた各変数が使用される(ここでは <code>username</code>, <code>password</code>)、という形です。</p> <p>一点注意なのはパスワードはそのままだと平文で保存されてしまいますが、実際に認証する際はハッシュ値に変換されるので不一致となってしまいます。そこで、<strong>保存時にハッシュ値に変換</strong>するように <code>password_hash('sha512')</code> を噛ませています。</p> <h3 id="ansible/tasks/vsftpd_user_settings.yml"><a href="#ansible%2Ftasks%2Fvsftpd_user_settings.yml">ansible/tasks/vsftpd_user_settings.yml</a></h3> <pre><code class="yaml">- name: Settings vsftpd user_list blockinfile: path: /etc/vsftpd/user_list create: yes insertafter: EOF marker: "# {mark} ANSIBLE basic setup: <span>{</span><span>{</span> username <span>}</span><span>}</span>" block: "<span>{</span><span>{</span> username <span>}</span><span>}</span>" - name: Settings vsftpd user_conf blockinfile: path: "/etc/vsftpd/user_conf/<span>{</span><span>{</span> username <span>}</span><span>}</span>" create: yes insertafter: EOF marker: "# {mark} ANSIBLE basic setup: <span>{</span><span>{</span> username <span>}</span><span>}</span>" block: "local_root=/var/www/<span>{</span><span>{</span> rootdirectory <span>}</span><span>}</span>" - name: Restart vsftpd systemd: name: vsftpd.service state: restarted daemon_reload: yes </code></pre> <p>次は vsftpd の設定。 <code>user_list</code> にユーザとして登録し、 <code>user_conf</code> ディレクトリの下にユーザ名のファイルを作成、そこに <code>local_root</code> の指定を記述する、という内容です。</p> <p>ここでも一点注意。</p> <p>設定ファイルへの書き込みとして <code>blockinfile</code> を使用しているのですが、 <strong><code>marker</code> の値がユニークでない</strong>と、 <code>loop</code> で繰り返し処理をしたり、今回のケースだと異なる仮想サイトの設定を行ったり(Ansible を2回実行する)した場合に<strong>後勝ちで上書きされてしまう</strong>こと。</p> <p>今回のケースでは <code>user_list</code> に2回目の変数のユーザしか残らなくなってしまいます。そのため、 <strong><code>marker</code> の最後にユーザ名を混ぜることでコメント文が実行の度にユニークとなる</strong>ようにしました。</p> <h3 id="ansible/tasks/apache_settings.yml"><a href="#ansible%2Ftasks%2Fapache_settings.yml">ansible/tasks/apache_settings.yml</a></h3> <pre><code class="yaml">- name: mkdir root file: path: "/var/www/<span>{</span><span>{</span> rootdirectory <span>}</span><span>}</span>" state: directory owner: ADMIN_USER group: ADMIN_USER mode: 0755 recurse: no - name: mkdir web file: path: "/var/www/<span>{</span><span>{</span> rootdirectory <span>}</span><span>}</span>/web" state: directory owner: apache group: apache mode: 0775 recurse: no - name: Setup Apache conffile template: src: ../templates/vhost.conf.j2 dest: "/etc/httpd/conf.d/<span>{</span><span>{</span> rootdirectory <span>}</span><span>}</span>.conf" mode: '0644' - name: Restart httpd systemd: name: httpd.service state: reloaded daemon_reload: yes </code></pre> <p>続いて Apache 仮想サイトの設定。ディレクトリを作ったり権限・所有者設定したり。</p> <p>最後の <code>Setup Apache conffile</code> の処理では jinja2 のテンプレートから仮想サイト用の conf ファイルを作成しています。</p> <h3 id="ansible/templates/vhost.conf.j2"><a href="#ansible%2Ftemplates%2Fvhost.conf.j2">ansible/templates/vhost.conf.j2</a></h3> <pre><code class="jinja2"><VirtualHost <span>{</span><span>{</span> ipaddress <span>}</span><span>}</span>:<span>{</span><span>{</span> portnum <span>}</span><span>}</span>> DocumentRoot "/var/www/<span>{</span><span>{</span> rootdirectory <span>}</span><span>}</span>/web" ServerName <span>{</span><span>{</span> domain <span>}</span><span>}</span> {% if domain | regex_search("^www\.", ignorecase=True) %} ServerAlias <span>{</span><span>{</span> domain | regex_replace("^www\.(.*)$", '\\1') <span>}</span><span>}</span> {% endif %} ScriptAlias /cgi-bin/ /var/www/<span>{</span><span>{</span> rootdirectory <span>}</span><span>}</span>/web/cgi-bin/ {% if domain | regex_search("^www\.", ignorecase=True) %} RewriteEngine on RewriteCond %{HTTP_HOST} <span>{</span><span>{</span> domain | regex_replace("^www\.(.*)$", '^\\1$') | regex_replace("\.", '\.') <span>}</span><span>}</span> RewriteRule ^(.*)$ http://<span>{</span><span>{</span> domain <span>}</span><span>}</span>$1 [R=301,L] {% endif %} <Directory "/var/www/<span>{</span><span>{</span> rootdirectory <span>}</span><span>}</span>/web"> allow from all AllowOverride All Options FollowSymLinks Require all granted </Directory> </VirtualHost> </code></pre> <p>大体設定ファイルの内容ですが、各種変数を使用しています。</p> <p>また、ドメイン(変数 <code>domain</code> )が <code>www.</code> 始まりの場合はサーバ名を <code>www.example.jp</code> のように <code>www.</code> 付きとし、同時に <code>ServerAlias</code> で <code>example.jp</code> と <code>www.</code> なしもフォローするような条件分岐(<code>if</code>, <code>regex_search</code>)を挟みました。</p> <p>併せて、 <code>www.</code> なしのURLにアクセスした場合に <code>www.</code> ありにリダイレクトする設定も、変数 <code>domain</code> を正規表現置換(<code>regex_replace</code>)で一括で入れるようにしました。</p> <p>例えば、 <code>domain: www.example.jp</code> とした場合は以下のような設定ファイルが作成されます。</p> <pre><code><VirtualHost 192.0.2.1:80> DocumentRoot "/var/www/example/web" ServerName www.example.jp ServerAlias example.jp ScriptAlias /cgi-bin/ /var/www/example/web/cgi-bin/ RewriteEngine on RewriteCond %{HTTP_HOST} ^example\.jp$ RewriteRule ^(.*)$ http://www.example.jp$1 [R=301,L] <Directory "/var/www/example/web"> allow from all AllowOverride All Options FollowSymLinks Require all granted </Directory> </VirtualHost> </code></pre> <p>一方、 <code>domain: form.example.jp</code> のようなケースだと以下。</p> <pre><code><VirtualHost 192.0.2.1:80> DocumentRoot "/var/www/form_example/web" ServerName form.example.jp ScriptAlias /cgi-bin/ /var/www/form_example/web/cgi-bin/ <Directory "/var/www/form_example/web"> allow from all AllowOverride All Options FollowSymLinks Require all granted </Directory> </VirtualHost> </code></pre> <p>上記の通り、 <code>ServerAlias</code> と <code>Rewrite</code> 系がありません。</p> <h2 id="動作確認"><a href="#%E5%8B%95%E4%BD%9C%E7%A2%BA%E8%AA%8D">動作確認</a></h2> <p>以上のような構成で動作検証。</p> <pre><code class="bash"># ansible-playbook -i /workspace/ansible/targets/hosts /workspace/ansible/main.yml -u SSH_REMOTEUSER --private-key=&quot;/root/.ssh/PRIVATE_KEY&quot; -K BECOME password: PLAY [Settings vsftpd and httpd] ********************************************************************************** TASK [Gathering Facts] ********************************************************************************************ok: [192.0.2.1] TASK [Add Linux User] *********************************************************************************************included: /workspace/ansible/tasks/add_user.yml for 192.0.2.1 TASK [Add user, setting password and groups] **********************************************************************changed: [192.0.2.1] TASK [Settings vsftpd user_list and user_conf] ********************************************************************included: /workspace/ansible/tasks/vsftpd_user_settings.yml for 192.0.2.1 TASK [Settings vsftpd user_list] **********************************************************************************changed: [192.0.2.1] TASK [Settings vsftpd user_conf] **********************************************************************************changed: [192.0.2.1] TASK [Restart vsftpd] *********************************************************************************************changed: [192.0.2.1] TASK [Setup Apache conffile] **************************************************************************************included: /workspace/ansible/tasks/apache_settings.yml for 192.0.2.1 TASK [mkdir root] *************************************************************************************************changed: [192.0.2.1] TASK [mkdir web] **************************************************************************************************changed: [192.0.2.1] TASK [Setup Apache conffile] **************************************************************************************changed: [192.0.2.1] TASK [Restart httpd] **********************************************************************************************changed: [192.0.2.1] PLAY RECAP ********************************************************************************************************192.0.2.1 : ok=12 changed=8 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 </code></pre> <p>OKです。</p> <p>仮想サイトにアクセスして Apache のデフォルトページが表示される、FTPでログインできる、ファイルアップロードなどの操作ができる、といった動作を一通りできることを確認できました。</p> <h3 id="備考1: コマンドライン引数を変数に代入する"><a href="#%E5%82%99%E8%80%831%3A+%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%83%A9%E3%82%A4%E3%83%B3%E5%BC%95%E6%95%B0%E3%82%92%E5%A4%89%E6%95%B0%E3%81%AB%E4%BB%A3%E5%85%A5%E3%81%99%E3%82%8B">備考1: コマンドライン引数を変数に代入する</a></h3> <p>例えば、以下のような <code>main.yml</code> を用意します。</p> <pre><code class="yaml">- name: Get packages from hosts and do yum update become: yes become_user: ADMIN_USER become_method: su hosts: - update_servers tasks: - name: Get packages from hosts before update include_tasks: ./tasks/get_packages.yml - name: Output packages from hosts before update include_tasks: ./tasks/output_packages.yml vars: flag: "<span>{</span><span>{</span> before <span>}</span><span>}</span>" - name: Do yum update include_tasks: ./tasks/yum_update.yml - name: Get packages from hosts after update include_tasks: ./tasks/get_packages.yml - name: Output packages from hosts after update include_tasks: ./tasks/output_packages.yml vars: flag: "<span>{</span><span>{</span> after <span>}</span><span>}</span>" </code></pre> <p><a target="_blank" rel="nofollow noopener" href="https://labor.ewigleere.net/2020/11/06/ansible_execute_yum_update/">Ansible を使って yum update を実行する</a> の <code>main.yml</code> のうち、 <code>vars</code> の部分を少し編集したものです。</p> <p>これで以下のように playbook を実行。</p> <pre><code class="bash"># ansible-playbook -i /workspace/ansible/targets/hosts /workspace/ansible/main.yml -u SSH_REMOTEUSER --private-key=&quot;/root/.ssh/PRIVATE_KEY&quot; -K -e &quot;before=before2 after=after22&quot; </code></pre> <p>すると、 <code>workspace/192.0.2.1_packages_before2</code> と <code>workspace/192.0.2.1_packages_after22</code> が生成され、コマンドラインの引数が変数として使用されたことが分かりました。</p> <p>当初はこれの延長線を考えていましたが、冒頭の通り6つも引数があると長くなってしまうので最終的には不採用としました。</p> <p>ただし、これはこれで引数の使い方として参考になりそうなのでメモとして残しておきます。</p> <h2 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h2> <h3 id="Ansible"><a href="#Ansible">Ansible</a></h3> <h4 id="引数、変数"><a href="#%E5%BC%95%E6%95%B0%E3%80%81%E5%A4%89%E6%95%B0">引数、変数</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/YumaInaura/items/6e05d87858bd647d11ab">ansible コマンドでモジュール引数 ( パラメータ ) を複数渡す方法 - Qiita</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://docs.ansible.com/ansible/2.9_ja/user_guide/modules_intro.html">モジュールの概要 - Ansible Documentation</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://docs.ansible.com/ansible/2.9_ja/user_guide/playbooks_variables.html">変数の使用 - Ansible Documentation</a></li> </ul> <h4 id="変数"><a href="#%E5%A4%89%E6%95%B0">変数</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/c_u/items/e91ca023fbb124fec34a">Ansible: vars_files を使用した loop処理 - Qiita</a></li> </ul> <p><code>vars_files</code> を採用。</p> <h4 id="ユーザ作成"><a href="#%E3%83%A6%E3%83%BC%E3%82%B6%E4%BD%9C%E6%88%90">ユーザ作成</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://www.netassist.ne.jp/blog/?p=156">Ansibleでユーザ追加 | Netassist Blog</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/moiwa/items/bab0f4c8d0dbf361afa4">Ansible ~userモジュール~ - Qiita</a></li> </ul> <h4 id="パスワード"><a href="#%E3%83%91%E3%82%B9%E3%83%AF%E3%83%BC%E3%83%89">パスワード</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://www.netassist.ne.jp/blog/?p=967">Ansibleでユーザパスワード設定 | Netassist Blog</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/sicksixrock66/items/474068167de9c8454319">適当にansibleでrootパスワードを変えようとしたらアクセスできなくなった件 - Qiita</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://teratail.com/questions/263760">Linux - Ansibleでパスワード変更の際に、パスワードポリシーを遵守させたい|teratail</a></li> </ul> <h4 id="Facts"><a href="#Facts">Facts</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://nwengblog.com/ansible-facts/">Ansible:Factsについて(Ansible 2.9.6) | matsublog</a></li> </ul> <h4 id="設定に追記"><a href="#%E8%A8%AD%E5%AE%9A%E3%81%AB%E8%BF%BD%E8%A8%98">設定に追記</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/YuukiMiyoshi/items/f1b773f65792ce0e9101">【Ansible】そのCopy、Blockinfileの方が良いかも? - Qiita</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/nakacya/items/a624f6710c3ca0edc8a9">Ansible Blockinfile の tips - Qiita</a></li> </ul> <h4 id="blockfile"><a href="#blockfile">blockfile</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://dekitakotono.blogspot.com/2019/05/blockinfile.html">blockinfile モジュール-φ(.. ) のメモ</a></li> </ul> <blockquote> <p>複数のテキストブロックを追加する場合、マーカーラインをユニークにしないとテキストブロックが上書きされる</p> </blockquote> <p><code>marker</code> の文字列はユニークになるようにすること。</p> <h4 id="systemd"><a href="#systemd">systemd</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://tnamao.hatenablog.com/entry/2016/12/03/014742">ansible で systemd 配下のサービスを扱う - 日記</a></li> <li><a target="_blank" rel="nofollow noopener" href="http://pj-doaa.hatenablog.com/entry/2017/09/05/120849">AnsibleのModule:systemd - ときどきAnsible日記</a></li> </ul> <h4 id="ディレクトリ作成"><a href="#%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E4%BD%9C%E6%88%90">ディレクトリ作成</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/hnakamur/items/b5a17d8cb289432014d5">[Ansible] ディレクトリが無かったら作成する - Qiita</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://blog.adachin.me/archives/2781">[ansible]ディレクトリ作成はfileモジュールで! ? ADACHIN SERVER LABO</a></li> </ul> <h4 id="httpd"><a href="#httpd">httpd</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://dev.classmethod.jp/articles/tutorial-ansible-with-role/">Role を使ったAnsibleのチュートリアル | Developers.IO</a></li> </ul> <h4 id="jinja2, if"><a href="#jinja2%2C+if">jinja2, if</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/yteraoka/items/7119d4e1e2f8faddfb64">Ansible の Template 機能の紹介 - Qiita</a></li> </ul> <h4 id="jinja2, regrex"><a href="#jinja2%2C+regrex">jinja2, regrex</a></h4> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html">Using filters to manipulate data - Ansible Documentation</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://stackoverflow.com/questions/30413616/using-regex-in-jinja-2-for-ansible-playbooks">python - using regex in jinja 2 for ansible playbooks - Stack Overflow</a></li> </ul> <h3 id="usermod"><a href="#usermod">usermod</a></h3> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://www.atmarkit.co.jp/ait/articles/1612/14/news022.html">【 usermod 】コマンド――ユーザーアカウントの情報を変更する:Linux基本コマンドTips(73) - @IT</a></li> </ul> arm-band tag:crieit.net,2005:PublicArticle/15523 2019-11-01T02:12:38+09:00 2019-11-01T20:22:07+09:00 https://crieit.net/posts/AWX-Server-Error AWX をインストールした後の Server Error を解決したかった話 <p>この記事は、 <a target="_blank" rel="nofollow noopener" href="https://github.com/ansible/awx">Ansible AWX</a> をインストールしたときに、 Server Error に <strong>なったりならなかったりする</strong> 問題に対処したときのポエムだ。</p> <p><a href="https://crieit.now.sh/upload_images/e835b521a9d07ba5a1f19762bb3928fe5dbb159674c75.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/e835b521a9d07ba5a1f19762bb3928fe5dbb159674c75.png?mw=700" alt="1921_ansible_awx_error_00.png" /></a></p> <p>はじめに断っておくが、最終的に AWX 8.0.0 で解消しているっぽいものの、 原因や正確な条件などは不明なままである。<br /> また後述するが、 (タイトルに反して)おそらく Ansible AWX の問題ではなく、 postgres:9.6 の docker イメージの問題ではないかと思われる。</p> <h2 id="発生した問題の状況"><a href="#%E7%99%BA%E7%94%9F%E3%81%97%E3%81%9F%E5%95%8F%E9%A1%8C%E3%81%AE%E7%8A%B6%E6%B3%81">発生した問題の状況</a></h2> <p>まず、 問題が起きている状況をまとめると、以下のような状況だ。</p> <ul> <li>AWX を <a target="_blank" rel="nofollow noopener" href="https://github.com/ansible/awx/blob/7.0.0/INSTALL.md#docker-compose">Docker-Compose</a> を使ってインストール</li> <li>AWX のバージョンは、 7.0.0 または 6.1.0 (どちらでも発生する)</li> <li>インストール先は CentOS 7.7 1908 の VirtualBox のゲストマシン</li> <li>どういうわけか、 <strong>問題が起きる場合と起きない場合がある</strong> <ul> <li>仮想ストレージが (SSD ではなく) HDD 上にあると発生しやすい気がする</li> <li>VM のホストが、 バックエンドで I/O をガリガリやっていると発生しやすい気がする</li> <li>VM のホストが、 (バッテリー駆動などで)で省電力モードになっていると発生しやすい気がする</li> </ul></li> <li>問題が発生するかどうかは、インストール後の最初の起動で決まる。 <ul> <li>最初の起動で問題が発生すれば、その後も発生し続ける。</li> <li>逆に、最初の起動で問題が発生しなければ、その後は発生しない。</li> </ul></li> </ul> <p>最後の2つが非常に厄介で、全て VirtualBox で同じリソースを割り当てた VM のゲストマシンに、 同じ設定で CentOS をインストールしているのにもかからず、問題が発生したりしなかったりする。<br /> 訳がわからない。</p> <p>VM のホストをいろいろ買えつつ試してみたところ、上記のような状態の時に問題が派生しやすい気がするが、ハッキリ「そうだ」と言えるほどの回数は試せていない。</p> <p>最初、 良くある SELinux 関係の問題かと思って SELinux を切って AWX のインストールをやり直してみたが、何も変わらなかった。</p> <h2 id="AWX エラーの内容"><a href="#AWX+%E3%82%A8%E3%83%A9%E3%83%BC%E3%81%AE%E5%86%85%E5%AE%B9">AWX エラーの内容</a></h2> <p>上記スクショの "Server Error" "A server error has occurred" のメッセージだけでは、どんな問題が発生しているのか全くわからないので、とりあえず各コンテナのログをみてみる。</p> <p>どうやら、 awx_postgres コンテナで、以下のようなエラーが発生しているようだ。</p> <pre><code>FATAL: no pg_hba.conf entry for host "172.18.0.2", user "awx", database "awx", SSL off </code></pre> <p>問題が起きていない環境と、起きている環境で pg_hba.conf (※) を比べると、<br /> 問題が起きていない環境では、このファイルの末尾に</p> <pre><code>host all all all md5 </code></pre> <p>が追記されているという違いがある。</p> <p>(※: pg_hba.conf は awx_postgres コンテナの <code>/var/lib/postgresql/data/pgdata/pg_hba.conf</code> にあるほか、 docker ホスト側でも <code>/tmp/pgdocker/pgdata/pg_hba.conf</code> として永続化されている。 (postgres_data_dir 変数が初期値の場合。))</p> <p>この行がないため、 WEB サービスを走らせているコンテナから PostgreSQL を動かしているコンテナへのアクセスが拒否されているようだ。</p> <p>しかし、問題となっている環境で pg_hba.conf を書き換えても、別のエラーが発生して Server Error が表示される問題は解決しない。</p> <p>問題が起きる環境と起きない環境を更に詳しく比べると、 PostgreSQL の DB が作成すらされていないことがわかった。<br /> 本来なら、 awx_postgres コンテナ内に awx ユーザで DB が作成されている筈なのにもかかわらず、以下のように コンテナに入って psql の --list オプションを実行すると、エラーになってしまう。</p> <pre><code class="bash">$ sudo docker exec -it awx_postgres /bin/bash root@xxxxxxxxxxxx:/# psql --list -U awx psql: FATAL: database "postgres" does not exist </code></pre> <p>以上のことから、 pg_hba.conf の書き換えや、 PostgreSQL DB の初期化といった、 初期化プロセスが実行されずに「初期化済み」扱いされているのが原因ではないかと、予想がつく。</p> <p>awx リポジトリ内で同様の不具合が挙がっていないか確認してみたが、 <a target="_blank" rel="nofollow noopener" href="https://github.com/ansible/awx/issues/4736">似たような問題は挙がっている</a> ものの、それそのものズバリの回答は見つからなかった。</p> <h2 id="pg_hba.conf を書き換えているのは誰だ"><a href="#pg_hba.conf+%E3%82%92%E6%9B%B8%E3%81%8D%E6%8F%9B%E3%81%88%E3%81%A6%E3%81%84%E3%82%8B%E3%81%AE%E3%81%AF%E8%AA%B0%E3%81%A0">pg_hba.conf を書き換えているのは誰だ</a></h2> <p>audit などを使って pg_hba.conf に関するシステムコールを監視して、 何が host all all all md5 と追記しているのかを確認してみる。</p> <p>その結果、書き換えを行っているのは</p> <pre><code class="bash">bash /usr/local/bin/docker-entrypoint.sh postgres </code></pre> <p>のプロセスだとわかった。</p> <p>AWX 7.0.0 インストール時の <a target="_blank" rel="nofollow noopener" href="https://github.com/ansible/awx/blob/7.0.0/installer/roles/local_docker/templates/docker-compose.yml.j2#L131">docker-compose.yml</a> も、 AWX 6.1.0 インストール時の <a target="_blank" rel="nofollow noopener" href="https://github.com/ansible/awx/blob/7.0.0/installer/roles/local_docker/templates/docker-compose.yml.j2#L131">docker-compose.yml</a> も、 postgres:9.6 の docker イメージを使っていることがわかる。<br /> このため、 上記の pg_hba.conf の書き換えを行っている docker-entrypoint.sh は、 postgres:9.6 イメージの Dockerfile のエントリーポイントである <a target="_blank" rel="nofollow noopener" href="https://github.com/docker-library/postgres/blob/3610f1e45365fb09c0fea29fa387b35f0efdb3a1/9.6/docker-entrypoint.sh#L119-L122">この docker-entrypoint.sh</a> だろう。</p> <p>前後の PostgreSQL の初期化プロセスも働いていないことを考えると、</p> <pre><code class="bash"> # look specifically for PG_VERSION, as it is expected in the DB dir if [ ! -s "$PGDATA/PG_VERSION" ]; then # "initdb" is particular about the current user existing in "/etc/passwd", so we use "nss_wrapper" to fake that if necessary # see https://github.com/docker-library/postgres/pull/253, https://github.com/docker-library/postgres/issues/359, https://cwrap.org/nss_wrapper.html </code></pre> <p>この条件分岐の部分が、意図通り働かないことがあるのではないかと思う。</p> <p>しかし、私は docker に関してはほとんどシロウトなので、ここから docker イメージの定義ファイルを辿って、どこがおかしいのかを調査するのはちょっと難しい。。。</p> <h2 id="AWX 8.0.0 がリリースされたら解決してた"><a href="#AWX+8.0.0+%E3%81%8C%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9%E3%81%95%E3%82%8C%E3%81%9F%E3%82%89%E8%A7%A3%E6%B1%BA%E3%81%97%E3%81%A6%E3%81%9F">AWX 8.0.0 がリリースされたら解決してた</a></h2> <p>…とかなんとかやってるうちに、 <a target="_blank" rel="nofollow noopener" href="https://github.com/ansible/awx/releases/tag/8.0.0">AWX 8.0.0 がリリース</a> されてしまった。</p> <p>8.0.0 で AWX のインストールを試してみると、ぱったりと問題が発生しなくなった。</p> <p>awx_postgres コンテナを作成する docker イメージが、 <a target="_blank" rel="nofollow noopener" href="https://github.com/ansible/awx/blob/8.0.0/installer/roles/local_docker/templates/docker-compose.yml.j2#L131">postgres:9.6 から postgres:10 に変更</a> になったからではないかと考えているが、具体的にどう変わったかは正直わからない。</p> <p>ひょんなことから、原因は不明ながら問題が解決してしまったので、これ以上調査する気力も失せて、私は考えるのをやめた。</p> <p><strong>追記:</strong> そして、記事を書いた直後に <a target="_blank" rel="nofollow noopener" href="https://github.com/ansible/awx/releases/tag/9.0.0">AWX 9.0.0 がリリース</a> された。ちょっとペース早すぎない!?</p> advanceboy tag:crieit.net,2005:PublicArticle/15179 2019-06-30T21:16:15+09:00 2019-06-30T21:16:15+09:00 https://crieit.net/posts/Ansible-VPS-2 AnsibleでVPSをセットアップする【その2】 <p><a href="https://crieit.net/posts/VPS-Ansible">VPSをAnsibleを使ってセットアップする</a>の後日譚的なものです。</p> <h1 id="docker/docker-composeのインストール"><a href="#docker%2Fdocker-compose%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB">docker/docker-composeのインストール</a></h1> <pre><code class="yml">- name: Add Docker GPG key apt_key: url=https://download.docker.com/linux/ubuntu/gpg </code></pre> <h2 id="apt-get updateでロックがかかってしまう問題"><a href="#apt-get+update%E3%81%A7%E3%83%AD%E3%83%83%E3%82%AF%E3%81%8C%E3%81%8B%E3%81%8B%E3%81%A3%E3%81%A6%E3%81%97%E3%81%BE%E3%81%86%E5%95%8F%E9%A1%8C">apt-get updateでロックがかかってしまう問題</a></h2> <h3 id="pathで指定したファイルを削除"><a href="#path%E3%81%A7%E6%8C%87%E5%AE%9A%E3%81%97%E3%81%9F%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E5%89%8A%E9%99%A4">pathで指定したファイルを削除</a></h3> <p>state "absent"に変える。absent(欠席の意=つまりない状態)<br /> 対義語は<strong>present</strong></p> <pre><code class="yml">- name: remove lock file file: path: /var/lib/apt/lists/lock state: absent </code></pre> <p><a target="_blank" rel="nofollow noopener" href="https://qiita.com/makaaso/items/432274ac18fe5bd254e3">エラー「E: Could not get lock /var/lib/apt/lists/lock - open (11: Resource temporarily unavailable)」</a></p> <h1 id="NodeJS/npmのインストール"><a href="#NodeJS%2Fnpm%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB">NodeJS/npmのインストール</a></h1> <p>後でgit pullしてnpm installするのですが、インストールされてないことに気づいたのでここでインストールしてしまいます。</p> <pre><code class="yml"> - name: Install basic list of packages apt: name: ['apt-transport-https','ca-certificates','curl','gnupg2','software-properties-common','npm','nodejs'] state: present update_cache: yes </code></pre> <pre><code class="yml"> - name: Add Docker APT repository apt_repository: repo: deb [arch=amd64] https://download.docker.com/linux/<span>{</span><span>{</span>ansible_distribution|lower<span>}</span><span>}</span> <span>{</span><span>{</span>ansible_distribution_release<span>}</span><span>}</span> stable - name: Install Docker packages apt: name: ['docker-ce','docker-ce-cli','containerd.io'] state: present - name: Install Docker-compose shell: curl -L "https://github.com/docker/compose/releases/download/1.24.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose - name: command: chmod +x /usr/local/bin/docker-compose </code></pre> <h1 id="プライベートリポジトリをgit clone"><a href="#%E3%83%97%E3%83%A9%E3%82%A4%E3%83%99%E3%83%BC%E3%83%88%E3%83%AA%E3%83%9D%E3%82%B8%E3%83%88%E3%83%AA%E3%82%92git+clone">プライベートリポジトリをgit clone</a></h1> <p>まだメインのスクリプトと統合してない状態です。<br /> githubからpersonal tokenを発行して使います。</p> <pre><code class="yml">- hosts: all user: "<span>{</span><span>{</span> user_name <span>}</span><span>}</span>" #become: yes tasks: - name: git pull git: repo: "https://<span>{</span><span>{</span>account_name<span>}</span><span>}</span>:<span>{</span><span>{</span> personal_token <span>}</span><span>}</span>@github.com/<span>{</span><span>{</span>account_name<span>}</span><span>}</span>/<span>{</span><span>{</span> repo_name <span>}</span><span>}</span>.git" dest: "~/<span>{</span><span>{</span> target_dir <span>}</span><span>}</span>" accept_hostkey: yes </code></pre> <h1 id="課題点"><a href="#%E8%AA%B2%E9%A1%8C%E7%82%B9">課題点</a></h1> <h2 id="docker-composeがパーミッションエラーで起動できない"><a href="#docker-compose%E3%81%8C%E3%83%91%E3%83%BC%E3%83%9F%E3%83%83%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%A8%E3%83%A9%E3%83%BC%E3%81%A7%E8%B5%B7%E5%8B%95%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84">docker-composeがパーミッションエラーで起動できない</a></h2> <p>ユーザをsudoできる権限を持ったグループに追加しないといけないみたいです。</p> <p><a target="_blank" rel="nofollow noopener" href="https://github.com/docker/compose/issues/4181">ERROR: Couldn't connect to Docker daemon at http+docker://localunixsocket - is it running?</a></p> ckoshien tag:crieit.net,2005:PublicArticle/15050 2019-06-01T23:26:13+09:00 2019-06-02T20:14:05+09:00 https://crieit.net/posts/VPS-Ansible VPSをAnsibleを使ってセットアップする <p>一念発起してVPSを借りたのですが、サーバの初期設定の操作で色々詰まってサーバ削除・新規作成を繰り返していたので、手順を残すこともできるAnsibleを使い始めました。</p> <h1 id="Ansibleって?"><a href="#Ansible%E3%81%A3%E3%81%A6%EF%BC%9F">Ansibleって?</a></h1> <p>RedHatが提供している、サーバの設定自動構成ツール。<br /> クライアントからサーバへSSHで接続してリモートでコマンドを実行できます。</p> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://docs.ansible.com/ansible/latest/index.html">Ansible Documentation</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://ja.wikipedia.org/wiki/Ansible_%28ソフトウェア%29">Ansible(ソフトウェア)</a></li> </ul> <h2 id="動作条件"><a href="#%E5%8B%95%E4%BD%9C%E6%9D%A1%E4%BB%B6">動作条件</a></h2> <ul> <li>クライアント: ansibleがインストールされていること</li> <li>サーバ: SSHで接続できること。python(2系でも3系でも可)がインストールされていること。</li> </ul> <h1 id="まずクライアント(mac)にansibleをインストール"><a href="#%E3%81%BE%E3%81%9A%E3%82%AF%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%88%28mac%29%E3%81%ABansible%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB">まずクライアント(mac)にansibleをインストール</a></h1> <pre><code>$ brew install ansible </code></pre> <h1 id="playbookを作る"><a href="#playbook%E3%82%92%E4%BD%9C%E3%82%8B">playbookを作る</a></h1> <p>playbookと呼ばれる、実行したいスクリプトをyamlで記述します。<br /> 以下がplaybookの設定例です。</p> <h2 id="サーバにログインする"><a href="#%E3%82%B5%E3%83%BC%E3%83%90%E3%81%AB%E3%83%AD%E3%82%B0%E3%82%A4%E3%83%B3%E3%81%99%E3%82%8B">サーバにログインする</a></h2> <p>hostsファイルで設定したallというグループに属するサーバにアクセスします。<br /> サーバ作成直後でroot以外のユーザがいない状況を想定しているのでrootでログインします。</p> <pre><code class="yml">- hosts: all user: root </code></pre> <h2 id="一般ユーザを新規作成する"><a href="#%E4%B8%80%E8%88%AC%E3%83%A6%E3%83%BC%E3%82%B6%E3%82%92%E6%96%B0%E8%A6%8F%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B">一般ユーザを新規作成する</a></h2> <p><strong>ubuntuはsudo権限を持ったグループ名がsudo</strong></p> <pre><code class="yml"> - name : add user user: name: "<span>{</span><span>{</span> user_name <span>}</span><span>}</span>" state: present password: "<span>{</span><span>{</span> password <span>}</span><span>}</span>" groups: sudo </code></pre> <h2 id=".sshディレクトリを作成する"><a href="#.ssh%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B">.sshディレクトリを作成する</a></h2> <p><strong>パーミッションは700ではなく0700</strong></p> <pre><code class="yml">- name: mkdir .ssh file: path: "~<span>{</span><span>{</span> user_name <span>}</span><span>}</span>/.ssh" state: directory owner: "<span>{</span><span>{</span> user_name <span>}</span><span>}</span>" group: "<span>{</span><span>{</span> user_name <span>}</span><span>}</span>" mode: 0700 </code></pre> <h2 id="公開鍵を一般ユーザのホームディレクトリに配置する"><a href="#%E5%85%AC%E9%96%8B%E9%8D%B5%E3%82%92%E4%B8%80%E8%88%AC%E3%83%A6%E3%83%BC%E3%82%B6%E3%81%AE%E3%83%9B%E3%83%BC%E3%83%A0%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E3%81%AB%E9%85%8D%E7%BD%AE%E3%81%99%E3%82%8B">公開鍵を一般ユーザのホームディレクトリに配置する</a></h2> <p><strong>パーミッションは600ではなく0600</strong></p> <pre><code class="yml">- name: private key for slave server copy: dest: "~<span>{</span><span>{</span> user_name <span>}</span><span>}</span>/.ssh/authorized_keys" content: "<span>{</span><span>{</span> lookup('file', '~/.ssh/public_openSSH') <span>}</span><span>}</span>" mode: 0600 owner: "<span>{</span><span>{</span> user_name <span>}</span><span>}</span>" group: "<span>{</span><span>{</span> user_name <span>}</span><span>}</span>" </code></pre> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://dev.classmethod.jp/server-side/ansible/deploy-private-key-using-ansible-lookup/">Ansibleのlookupを使って秘密鍵を配備する</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://www.netassist.ne.jp/blog/?p=1970">Ansibleで複数ユーザ追加と鍵作成</a></li> </ul> <h2 id="セキュリティ設定変更"><a href="#%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3%E8%A8%AD%E5%AE%9A%E5%A4%89%E6%9B%B4">セキュリティ設定変更</a></h2> <h3 id="ポート番号変更"><a href="#%E3%83%9D%E3%83%BC%E3%83%88%E7%95%AA%E5%8F%B7%E5%A4%89%E6%9B%B4">ポート番号変更</a></h3> <pre><code class="yml"> - name: "待受ポートを <span>{</span><span>{</span> sshd_port <span>}</span><span>}</span> に変更" lineinfile: dest: /etc/ssh/sshd_config regexp: "^Port" insertafter: "^#Port" line: "Port <span>{</span><span>{</span> sshd_port <span>}</span><span>}</span>" </code></pre> <ul> <li>iptablesで変更後のSSHポートを許可</li> </ul> <pre><code class="yml"> - name: Allow new incoming SYN packets. iptables: chain: INPUT protocol: tcp destination_port: "<span>{</span><span>{</span> sshd_port <span>}</span><span>}</span>" ctstate: NEW syn: match jump: ACCEPT comment: Accept new SSH connections. </code></pre> <ul> <li>ufw(ubuntuのファイアウォール)で変更後のSSHポートを許可</li> </ul> <h3 id="パスワードログイン禁止"><a href="#%E3%83%91%E3%82%B9%E3%83%AF%E3%83%BC%E3%83%89%E3%83%AD%E3%82%B0%E3%82%A4%E3%83%B3%E7%A6%81%E6%AD%A2">パスワードログイン禁止</a></h3> <pre><code class="yml">- name: パスワード認証の無効化 lineinfile: dest: /etc/ssh/sshd_config regexp: "^PasswordAuthentication" insertafter: "^#PasswordAuthentication" line: "PasswordAuthentication no" </code></pre> <h3 id="rootログイン禁止"><a href="#root%E3%83%AD%E3%82%B0%E3%82%A4%E3%83%B3%E7%A6%81%E6%AD%A2">rootログイン禁止</a></h3> <p><a target="_blank" rel="nofollow noopener" href="https://blog.apar.jp/linux/5299/">Ansible でSSHのセキュリティ設定</a></p> <h2 id="rootユーザからログアウト"><a href="#root%E3%83%A6%E3%83%BC%E3%82%B6%E3%81%8B%E3%82%89%E3%83%AD%E3%82%B0%E3%82%A2%E3%82%A6%E3%83%88">rootユーザからログアウト</a></h2> <p>これ以降は作成した一般ユーザでスクリプトを実行した方がよいのでユーザ切り替えのためにログアウト。</p> <pre><code class="yml">- name: logout meta: reset_connection </code></pre> <h1 id="playbookを実行する"><a href="#playbook%E3%82%92%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B">playbookを実行する</a></h1> <p><strong>server_setup.yml</strong>というplaybookを、<strong>hosts</strong>というファイルで設定したサーバに対して実行します。公開鍵認証をする場合は<strong>private-key</strong>オプションでopenSSH形式の秘密鍵を指定します。</p> <pre><code>$ ansible-playbook server_setup.yml -i hosts --private-key ~/.ssh/private_openSSH.ppk </code></pre> <h1 id="参考リンク"><a href="#%E5%8F%82%E8%80%83%E3%83%AA%E3%83%B3%E3%82%AF">参考リンク</a></h1> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/okatai/items/ad02dbbcbe710ba56589">Ansibleでユーザ追加とグループ作成方法</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/rch1223/items/e698036e52661c333f4c">ubuntuサーバをansible制御下に置くための準備</a></li> </ul> ckoshien