Ansible Galaxyを使用してLEMP Ubuntu 18サーバーを準備

今回のブログ記事では、パラメータ化と**Ansible Galaxy**を使った自動化によるサーバー設定について解説します。

*本ブログは英語版からの翻訳です。オリジナルは[こちら](https://www.alibabacloud.com/blog/preparing-a-lemp-ubuntu-18-server-with-wordpress-using-ansible_594655)からご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。*

[ Alibaba Cloud Tech Share ](https://www.alibabacloud.com/campaign/techshare?spm=a2c65.11461447.0.0.bd4e709aj0TCSK)執筆者、Ankit Mehta。[Tech Share](https://www.alibabacloud.com/campaign/techshare?spm=a2c65.11461447.0.0.bd4e709aj0TCSK)は、クラウドコミュニティ内で技術的な知識やベストプラクティスを共有することを奨励するAlibaba Cloudのインセンティブプログラムです。

Ansibleに初めて触れる方は、[以前のブログ記事](https://www.alibabacloud.com/blog/getting-started-with-configuration-management-and-ansible_594653?spm=a2c65.11461447.0.0.bd4e709aj0TCSK)でAnsibleの仕組みといくつかの基本的な設定を読んでみてください。

パラメータ化は自動化の最も重要なセグメントの1つです。パラメータ化を行うことで、完全なソリューションを再度書き換えることなくスクリプトやファイルを再利用することができます。

「VPS を 1 台しか持っていないのですが、Ansible を使用して何かメリットはありますか」とよく聞かれますが、1 台の VPS であっても複数の VPS サーバであっても、答えはイエスです。Ansibleスクリプトを使用して、すべてのサーバーを管理することができます。これは、設定を保持するだけでなく、SSLに変更を適用して、新しいサーバーを設定するのに役立ちますし、新しいクラウドホスティングプロバイダ上のWebサイトを設定して展開するのにも役立ちます。

このブログ記事では、我々はAnsibleで次のソリューションを実装します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/a5df474e-ec25-5551-dada-5ba19cf0a6d4.png)


1、ウェブサイトのドメインはCloudflareのDNSサービスを使用しています。
2、ウェブサイトは、Alibaba Cloud [Elastic Compute Service](https://www.alibabacloud.com/product/ecs?spm=a2c65.11461447.0.0.bd4e709aj0TCSK) (ECS)上でホストされています。
3、ウェブサーバは以下のように設定されています。
　　　1、カスタムSSHポート1992
　　　2、PHP バージョン 7.2
　　　3、MySQL
　　　4、Fail2Ban
　　　5、Swap size 1 GB
　　　6、NginX ウェブサーバー
　　　7、root用のSSHのブロック
　　　8、ファイアウォールは、SSHのみを許可 , HTTPとHTTPS
　　　9、CloudFlareからのSSL

上記を達成するために、ブログは2つのセグメントに分かれています。

1、Ubuntu 18.04でLEMPサーバーを準備する（Linux、Nginx、MySQL、PHP)
2、Cloudflare SSLで1ドメイン分のサーバーを準備する

#その1. Ubuntu 18.04でのLEMPサーバーの準備
###前提条件
サーバの準備ができて、Ansible ホストからアクセスできるようになっていることを確認します。Ansible ホストを設定するには、Ansible Basics のブログ記事を参照してください。

###NGINXのインストール
NGINXをインストールするためのAnsible Galaxyスクリプトは複数用意されています。しかし、私自身の経験からすると、NginxのインストールにはAPTを使った方が良いと思います。Ansible Galaxy の完全なリストは [https://galaxy.ansible.com/](https://galaxy.ansible.com/?spm=a2c65.11461447.0.0.bd4e709aj0TCSK) にあります。

次のブロックでは、NGINXをサーバーにインストールし、サービスが有効になっていることを確認します。

```
---
- hosts: all
  tasks:
    - name: ensure nginx is at the latest version
      apt: name=nginx state=latest
      become: yes

    - name: start nginx
      service:
          name: nginx
          state: started
      become: yes
```

上記ブロックをinstall-nginx.ymlとして保存し、以下のコマンドで実行します。

```
ansible-playbook -i hosts.yml install-nginx.yml -b -v 
```

###PHPをインストール
異なるUbuntuのバージョンは、異なるPHPバージョンのサポートが付属しています。PHPバージョン7.2

Ansible galaxyは、必要な依存関係を迅速にインストールするタスクの削減に役立ちます。Ansible Galaxyとは、ユーザーがロールを共有できるGalaxyのWebサイトや、ロールのインストール、作成、管理を行うコマンドラインツールのことを指します。

PHPをインストールするには、2つのansible galaxyのロールが必要です。PHPバージョンとPHP（インストール順序は任意の順序で構いません）です。

PHP版をインストールするには、以下のコマンドを入力します。

```
ansible-galaxy install geerlingguy.php-versions 
```

PHPのバージョンをインストールするには、次のコマンドを入力します。

```
ansible-galaxy install geerlingguy.php 
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/379a00b7-59c6-7ccf-8edf-4b05f5b6a62e.png)

Ansible Galaxyのロールをインストールしたら、インストール用のyamlファイルを用意します。Ansibleロールには変数ファイルが必要です。デモのため、変数ファイルはvars/main.ymlファイルに格納します。今回は、varsファイルにPHPのバージョン、PHPの設定（php.iniファイルの設定）、必要なPHPの拡張子を追加しました。

main.ymlファイルの内容は以下の通りです。

```
#PHP version
php_version: '7.2'
php_enable_webserver: true
php_webserver_daemon: "nginx"
php_packages_state: "present"
php_install_recommends: true
php_executable: "php"
php_enable_php_fpm: true
php_fpm_listen: "127.0.0.1:9000"
php_fpm_listen_allowed_clients: "127.0.0.1"
php_fpm_pm_max_children: 50
php_fpm_pm_start_servers: 5
php_fpm_pm_min_spare_servers: 5
php_fpm_pm_max_spare_servers: 5
php_use_managed_ini: true
php_fpm_pool_user: "www-data" # default varies by OS
php_fpm_pool_group: "www-data" # default varies by OS
php_memory_limit: "256M"
php_max_execution_time: "60"
php_max_input_time: "60"
php_max_input_vars: "1000"
php_realpath_cache_size: "32K"
php_file_uploads: "On"
php_upload_max_filesize: "64M"
php_max_file_uploads: "20"
php_post_max_size: "32M"
php_date_timezone: "Asia/Bangkok"
php_allow_url_fopen: "On"
php_sendmail_path: "/usr/sbin/sendmail -t -i"
php_output_buffering: "4096"
php_short_open_tag: false
php_error_reporting: "E_ALL & ~E_DEPRECATED & ~E_STRICT"
php_display_errors: "Off"
php_display_startup_errors: "On"
php_expose_php: "Off"
php_session_cookie_lifetime: 0
php_session_gc_probability: 1
php_session_gc_divisor: 1000
php_session_gc_maxlifetime: 1440
php_session_save_handler: files
php_opcache_zend_extension: "opcache.so"
php_opcache_enable: "1"
php_opcache_enable_cli: "0"
php_opcache_memory_consumption: "96"
php_opcache_interned_strings_buffer: "16"
php_opcache_max_accelerated_files: "4096"
php_opcache_max_wasted_percentage: "5"
php_opcache_validate_timestamps: "1"
php_opcache_revalidate_path: "0"
php_opcache_revalidate_freq: "2"
php_opcache_max_file_size: "0"
php_memory_limit: "128M"
php_max_execution_time: "90"
php_upload_max_filesize: "256M"
php_packages:
  - php
  - php-cli
  - php-common
  - php-devel
  - php-gd
  - php-mbstring
  - php-pdo
  - php-pecl-apcu
  - php-xml
  - php-fpm
```

以下のコードスニペットはインストール用のyamlファイル(php-install.yml)です。

```
- hosts: all
  vars_files:
    - vars/main.yml
  roles:
    - geerlingguy.php-versions
    - geerlingguy.php
```

phpをインストールするには、以下のコマンドを入力する必要があります。

```
ansible-playbook -i hosts.yml php-install.yml -b -v
```


###MariaDBのインストール
同様に、MySQL/MariaDBをインストールするための多くのパッケージが用意されています。しかし、最良の選択肢は、直接インストールパッケージを使用することです。MariaDB / MySQLは、サーバー上にPython-pyのMySQLを必要とします。以下のインストールブロックは、依存関係とMySQLをインストールします。

```
---
  - hosts: all
    tasks:
      - name: "Install Python MySQL Dependency"
        apt:
          name: ['python-mysqldb',
            'python3-pip',
            'python3-dev',
            'libmysqlclient-dev',
            'mysql-server',
            'php7.2-mysql']

      - name: select default locale
        debconf:
          name: locales
          question: locales/default_environment_locale
          value: en_US.UTF-8
          vtype: select

      - name: set timezone to Asia/Bangkok
        timezone:
          name: Asia/Bangkok

      - name: "Install Python MySQL Module"
        pip:
          name: mysqlclient
          extra_args: -i https://pypi.python.org/pypi/
          executable: pip3
```

上記ブロックをmysql-install.ymlとして保存し、以下のコマンドを実行してインストールします。

```
ansible-playbook -i hosts.yml mysql-install.yml -b -v
```

###スワップの設定
Linux は、ホストで利用可能な仮想メモリの量を増やすためにスワップスペースを使用します。1 つ以上の専用のスワップパーティションを使用したり、通常のファイルシステムや論理ボリューム上のスワップファイルを使用することができます。Ansibleの銀河の役割は、簡単にスワップスペースを構成するのに役立ちます。

次のコマンドでswap ansible roleをインストールします。

```
ansible-galaxy install geerlingguy.swap
```

vars/main.yml で期待されるスワップスペースと圧力の詳細を設定します。

```
swap_file_path: /swapfile
swap_file_size: '1024'
swap_swappiness: 60
swap_file_state: present
swap_file_create_command: "dd if=/dev/zero of={{ swap_file_path }} bs=1M count={{ swap_file_size }}”
```

次のコードブロックを swap-install.yml として保存します。


```
- hosts: all
  vars_files:
    - vars/main.yml
  roles:
    - geerlingguy.swap
```

スワップをインストールするには、次のコマンドを実行します。

```
ansible-playbook -i hosts.yml swap-install.yml -b -v
```

より多くのスワップファイルサイズが必要な場合は、swap_file_sizeパラメータを更新してください。現在の設定では、1GBのスワップファイルパーティションを作成します。

###セキュリティの設定
ウェブサーバのセキュリティは、どのサーバ（ECS）の設定においても最も重要な部分です。セキュリティを向上させるには、ルートログインの無効化、パスワードログインの無効化、SSH ポートの変更、fail2ban の有効化を推奨します。(Linux サーバのセキュリティを向上させるためには、他にも多くの機能やサービスがあることに注意してください)

Linux セキュリティ ansible ロールをインストールするには、以下のコマンドを実行してください。

```
ansible-galaxy install geerlingguy.security
```

vars/main.ymlに以下の変数を追加します。

```
# Security Settings
security_ssh_port: 65239
security_ssh_password_authentication: "no"
security_ssh_permit_root_login: "no"
security_ssh_usedns: "no"
security_autoupdate_enabled: true
security_fail2ban_enabled: true
```

次のコードブロックを install-security.yml として保存します。

```
- hosts: all
  vars_files:
    - vars/main.yml
  roles:
    - geerlingguy.security
```

セキュリティランをインストールするには、以下のようにします。

```
ansible-galaxy -i hosts.yml install-security.yml -b -v
```

上記の例では、テストの実行が成功した後、SSHのポートが65239に変更されます。

###ファイアウォールの設定
ファイアウォールの設定を適用することで、サーバは既知のネットワーク攻撃から防ぐことができます。アプリケーションはHTTP、HTTPS、SSHのポートを使用しようとしているので、それ以外のポートへのアクセスをブロックすることをお勧めします。ファイアウォールのAnsible galaxyロールをインストールするには、以下のコマンドを実行します。

```
ansible-galaxy install geerlingguy.firewall
```

vars/main.yml ファイルにポートの詳細を提供します。

```
#Firewall Settings
firewall_state: started
firewall_enabled_at_boot: true
firewall_allowed_tcp_ports:
  - "443"
  - "65239"
  - “80"
```

次のコードブロックを install-firewall.yml として保存します。

```
- hosts: all
  vars_files:
    - vars/main.yml
  roles:
    - geerlingguy.firewall
```

ファイアウォールの変更を適用するには、次のコマンドを実行します。

```
ansible-playbook -i hosts.yml install-firewall.yml -b -v
```

注：ECS インスタンスにもファイアウォールの変更を適用してください。変更を適用するには、ECS > セキュリティグループ > ルールの追加 に移動します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/c0eb4e1b-530f-8780-6099-b27220229bbc.png)

サンプルLEMPインストールスクリプトは [https://github.com/ankyit/ansible-lemp-wordpress/tree/master/LEMP](https://github.com/ankyit/ansible-lemp-wordpress/tree/master/LEMP?spm=a2c65.11461447.0.0.bd4e709aj0TCSK) にあります。

- [Prepare-client.sh](https://github.com/ankyit/ansible-lemp-wordpress/blob/master/LEMP/prepare-client.sh?spm=a2c65.11461447.0.0.bd4e709aj0TCSK&file=prepare-client.sh) ファイルには、すべての依存関係と必要なロールを含む ansible システムを準備するための基本的なインストールスクリプトが含まれています。
- hosts.yml ([https://github.com/ankyit/ansible-lemp-wordpress/blob/master/LEMP/hosts.yml](https://github.com/ankyit/ansible-lemp-wordpress/blob/master/LEMP/hosts.yml?spm=a2c65.11461447.0.0.bd4e709aj0TCSK&file=hosts.yml) ) のサーバIPとansible_userを更新します。
- LEMP のインストールには、prepare-lemp.yml ([https://github.com/ankyit/ansible-lemp-wordpress/blob/master/LEMP/prepare-lemp.yml](https://github.com/ankyit/ansible-lemp-wordpress/blob/master/LEMP/prepare-lemp.yml?spm=a2c65.11461447.0.0.bd4e709aj0TCSK&file=prepare-lemp.yml) ) ファイルを使用してください。
- vars/main.yml ([https://github.com/ankyit/ansible-lemp-wordpress/blob/master/LEMP/vars/main.yml ](https://github.com/ankyit/ansible-lemp-wordpress/blob/master/LEMP/vars/main.yml?spm=a2c65.11461447.0.0.bd4e709aj0TCSK&file=main.yml)) ファイルで必要なパラメータを更新します。

#その２：Cloudflare SSLでドメイン用にサーバーを準備する
###前提条件
1、LEMPサーバー
2、CloudflareでDNSを使用したドメイン名
3、SSL証明書
4、データベース付きウェブサイト（今回はWordPressデモウェブの場合

上記のセグメントでは、LEMPサーバーの準備について詳しく説明しました。このセグメントでは、Ansibleを利用してWordPressサイトを導入する際の参考にしていただきたいと思います。

以下は、サイト展開の設定のための高レベルの構造です。フォーマットは必要に応じて定義し、設定することができます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/9f9bd25f-54d9-cd8b-d58f-032e9d1855ef.png)


ここでは、certsディレクトリにSSL証明書とKeyファイルが格納されます。sites-configフォルダには、NGINXの設定が格納されます。sitesには、ウェブサイトのファイルとフォルダ構造が格納されます。varsフォルダにはサイト変数が格納されます。

hosts.ymlファイルには、ホスト情報が含まれ、deploy-site.ymlには、サイトの展開のための手順/タスクが含まれます。

deploy-site.yml ファイルは、ブログの記事でカバーされている機能を拡張します。

deploy-site.yml からのタスク

次のブロックでは、証明書と鍵ファイルを certs フォルダから /etc/nginx/ssl フォルダにコピーします。ここで{{site_url}}は動的パラメータであり、その値はvars/main.ymlからその場で置き換えられます。

```
### {{site_url}} SSL Copy
    - name: copy {{site_url}} SSL files
      copy:
        src: ./certs/{{site_url}}.csr
        dest: /etc/nginx/ssl/{{site_url}}.csr
      become: yes

    - name: copy {{site_url}} SSL key files
      copy:
        src: ./certs/{{site_url}}.key
        dest: /etc/nginx/ssl/{{site_url}}.key
      become: yes
```

次のコードブロックは、ウェブサイトのNGINX設定ファイルをコピーし、/etc/nginx/sites-availableに格納します。

```
### {{site_url}} Nginx configuration
    - name: copy the nginx config file
      copy:
        src: ./site-config/{{site_url}}.cfg
        dest: /etc/nginx/sites-available/{{site_url}}.cfg
      become: yes
```

以下のコードブロックは、 sites-available から sites-enabled への URL のシンボリックリンクを作成します。

```
    - name: create symlink
      file:
        src: /etc/nginx/sites-available/{{site_url}}.cfg
        dest: /etc/nginx/sites-enabled/{{site_url}}.cfg
        state: link
      become: yes
```

次のコードブロックは、/var/www/の場所にウェブサイトのフォルダを作成します。

```
###  Create a directory for the website
    - file:
        path: /var/www/{{site_url}}
        state: directory
        mode: 0755
```


次のコードブロックは、rsyncを使ってサイトフォルダから/var/www/にファイルをコピーします。ここで delete yes は、コピー元の場所からファイルが削除された場合、コピー先の場所にあるファイルを削除します。

```
##{{site_url}} Website Copy
    - name: copy the content of the website
      synchronize:
        src: ./sites/
        dest: /var/www/{{site_url}}
        delete: yes
```

以下のコードブロックでデータベースを作成します。

```
###{{site_url}} Database Creation
    - name: Create a {{site_url}} database
      mysql_db:
        name: "{{site_db}}"
        state: present
```


以下のコードブロックでは、ユーザーを作成し、DBの権限を割り当てます。

```
    - name: "Create a new user for {{site_url}}"
      mysql_user:
        name: "{{site_db_user}}"
        password: "{{site_db_password}}"
        priv: '{{site_db}}.*:ALL'
        state: present
```

次のコードブロックは、データベースをインポートします。

```
# ###Import database
    - name: import the database
      mysql_db:
        name: "{{site_db}}"
        state: import
        target: /var/www/{{site_url}}/{{db_file}}
        login_user: "{{site_db_user}}"
        login_password: "{{site_db_password}}”
```

以下のコードブロックは、ディレクトリのパーミッションを設定し、0755の権限でwww-dataに設定します。

```
###Set Directory permissions
    - name: Set Directory permissions
      file: path=/var/www/ owner=www-data group=www-data mode=0755 state=directory recurse=yes
```

次のコードブロックはNGINXとPHP-FPMを再起動します。


```
## Restart NginX and PHP-fpm
    - name: restart nginx
      service:
        name: nginx
        state: restarted
      become: yes

    - name: restart PHP FPM
      service:
        name: php7.2-fpm
        state: restarted
      become: yes
```


![スクリーンショット 2020-12-17 13.06.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/5c8c9831-809c-4142-91bd-8402d432b228.png)

注意: ここで説明するすべてのスクリプトは [https://github.com/ankyit/ansible-lemp-wordpress](https://github.com/ankyit/ansible-lemp-wordpress?spm=a2c65.11461447.0.0.bd4e709aj0TCSK) からアクセスできます。


*アリババクラウドは日本に２つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
[アリババクラウドジャパン公式ページ](https://www.alibabacloud.com/ja)*