下記のような構成でAnsibleを使ってLaravelの開発環境を作りたいと思います。
- Ansibleサーバ1台
- 開発用WEBサーバ2台
- DBサーバサーバ1台
設定ファイルとか1,2箇所ぐらいなら置換処理で良いですが、設定ファイルまるっと渡してあげたほうが楽ちんなのですべてをコード化しない方が私は好みですね。
目次
Ansibleサーバ側
ホスト名の設定
1 |
# hostnamectl set-hostname ansible.example.net |
SELinuxの無効化
1 2 3 4 5 |
# vi /etc/sysconfig/selinux #SELINUX=enforcing SELINUX=disabled |
再起動にて反映しましょう!
1 |
# reboot now |
モジュールのインストール
1 2 3 4 5 |
# yum -y install epel-release # yum -y install ansible # yum -y install MySQL-python # yum -y install libselinux-python # yum -y install rsync |
ansibleはバージョンの違いが大きいので確認しましょうね。
1 2 3 4 5 6 7 8 |
# ansible --version ansible 2.7.7 config file = /etc/ansible/ansible.cfg configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules'] ansible python module location = /usr/lib/python2.7/site-packages/ansible executable location = /usr/bin/ansible python version = 2.7.5 (default, Apr 11 2018, 07:36:10) [GCC 4.8.5 20150623 (Red Hat 4.8.5-28)] |
外部のサーバを操作出来るようにしよう
秘密鍵の作成を行います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# ssh-keygen -t rsa -b 4096 Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa):空Enter Created directory '/root/.ssh'. Enter passphrase (empty for no passphrase):空Enter Enter same passphrase again:空Enter Your identification has been saved in /root/.ssh/id_rsa. Your public key has been saved in /root/.ssh/id_rsa.pub. The key fingerprint is: SHA256:9LhlM99R3AsM71hfoI0rRYAw00NKNw9F4HGoCagtqZY root@ansible The key's randomart image is: +---[RSA 4096]----+ | . =+B*=o. . | | . .. *=* .++ o.| | + ..oo.. +=. =| |+ . o. o .+.o.o| |... S B....o | |.E + = . . | |. . . . | | | | | +----[SHA256]-----+ |
下記の構成で作ります。
1 2 3 4 5 6 7 8 9 10 11 |
# vi .ssh/config Host staff1-web HostName 192.168.100.245 Host staff2-web HostName 192.168.100.246 host db HostName 192.168.100.247 |
Ansibleで外部サーバを操作できるように鍵を渡します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# ssh-copy-id staff1-web /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub" The authenticity of host '192.168.100.245 (192.168.100.245)' can't be established. ECDSA key fingerprint is SHA256:o+UwU12FvnJsA3hjwqSw9H/ZDbINPLnrsa72UZcZvx8. ECDSA key fingerprint is MD5:6e:d1:53:cf:1d:a2:e6:5e:4d:19:50:df:20:57:39:e2. Are you sure you want to continue connecting (yes/no)? yes /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys root@192.168.100.245's password: Number of key(s) added: 1 Now try logging into the machine, with: "ssh 'staff1-web'" and check to make sure that only the key(s) you wanted were added. |
1 2 |
# ssh-copy-id staff2-web # ssh-copy-id db |
Ansibleのホスト設定です。
1 2 3 4 5 6 7 8 9 |
# vi /etc/ansible/hosts [web] 192.168.100.245 192.168.100.246 [db] 192.168.100.247 |
疎通確認しましょうね
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# ansible all -i /etc/ansible/hosts -m ping 192.168.100.245 | SUCCESS => { "changed": false, "ping": "pong" } 192.168.100.246 | SUCCESS => { "changed": false, "ping": "pong" } 192.168.100.247 | SUCCESS => { "changed": false, "ping": "pong" } |
ディレクトリ作成
1 |
# mkdir -p /etc/ansible/cp.example.net/v1/{web,db} |
Nginxバーチャルホストファイル作成
1 |
# mkdir -p /etc/ansible/cp.example.net/v1/web/etc/nginx/conf.d |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# vi /etc/ansible/cp.example.net/v1/web/nginx/etc/conf.d/laravel.conf server { server_tokens off; root /var/www/vhosts/cp.example.net/httpdocs/laravel/public; listen 80 default_server; server_name _; location / { index index.php index.html; try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock; fastcgi_index index.php; include /etc/nginx/fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } } |
FTP設定
1 2 3 |
# mkdir -p /etc/ansible/cp.example.net/v1/web/etc/vsftpd/ # mkdir /etc/ansible/cp.example.net/v1/web/etc/vsftpd/user_conf # touch /etc/ansible/cp.example.net/v1/web/etc/vsftpd/chroot_list |
1 2 3 |
# vi /etc/ansible/cp.example.net/v1/web/etc/vsftpd/user_conf/webadmin local_root=/var/www/vhosts |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# vi /etc/ansible/cp.example.net/v1/web/etc/vsftpd/vsftpd.conf local_enable=YES write_enable=YES local_umask=022 dirmessage_enable=YES connect_from_port_20=YES xferlog_std_format=YES listen=YES listen_ipv6=NO pam_service_name=vsftpd userlist_enable=YES tcp_wrappers=YES anonymous_enable=NO ascii_upload_enable=YES ascii_download_enable=YES ftpd_banner=Welcome to blah FTP service. chroot_local_user=YES chroot_list_enable=YES chroot_list_file=/etc/vsftpd/chroot_list ls_recurse_enable=YES pam_service_name=vsftpd tcp_wrappers=YES userlist_deny=NO pasv_min_port=50000 pasv_max_port=50030 chroot_local_user=YES force_dot_files=YES xferlog_file=/var/log/vsftpd.log xferlog_std_format=NO log_ftp_protocol=YES #ssl_enable=YES #pasv_addr_resolve=YES pasv_address= #rsa_cert_file=/etc/pki/tls/certs/ftp.pem #require_ssl_reuse=NO #force_local_logins_ssl=NO #force_local_data_ssl=NO #port_enable=YES #allow_anon_ssl=NO use_localtime=YES allow_writeable_chroot=YES user_config_dir=/etc/vsftpd/user_conf #listen_port=21 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# vi /etc/ansible/cp.example.net/v1/web/etc/vsftpd/user_list # vsftpd userlist # If userlist_deny=NO, only allow users in this file # If userlist_deny=YES (default), never allow users in this file, and # do not even prompt for a password. # Note that the default vsftpd pam config also checks /etc/vsftpd/ftpusers # for users that are denied. root bin daemon adm lp sync shutdown halt mail news uucp operator games nobody webadmin |
変数ファイルの作成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# vi /etc/ansible/cp.example.net/v1/var_yml --- usergroup: user: name: webadmin group: nginx password: password app_path: "/var/www/vhosts/cp.example.net/httpdocs/laravel" mysql_root_password: rootpassword ssh_port: 22 mynetwork: 192.168.11.0/24 dbName: bizdb dbUser: bizdbuser dbPassword: bizdbpassword |
playbookの作成
サーバを構成するレシピのようなものです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 |
# vi /etc/ansible/cp.example.net/v1/playbook.yml --- - hosts: web become: yes vars_files: - var_yml tasks: - name: Firewalldの状態チェック command: systemctl is-active firewalld register: firewalld_result changed_when: False ignore_errors: True - name: Firewalldの起動, 自動起動設定 service: name=firewalld state=started enabled=yes - name: Firewalld設定 80許可 firewalld: permanent=True port=80/tcp state=enabled immediate=true - name: Firewalld設定 443許可 firewalld: permanent=True port=443/tcp state=enabled immediate=true - name: Firewalld設定 21許可 firewalld: permanent=True port=21/tcp state=enabled immediate=true - name: Firewalld設定 50000-50030許可 firewalld: permanent=True port=50000-50030/tcp state=enabled immediate=true - name: EPEL, remi リポジトリの追加 yum: name: "{{ package }}" state: latest vars: package: - epel-release - http://rpms.famillecollet.com/enterprise/remi-release-7.rpm - http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm - name: Basicツールのインストール yum: name: "{{ package }}" state: latest vars: package: - zip - unzip - git - name: Nginxのインストール yum: name: "{{ package }}" state: latest vars: package: - nginx - name: WEBユーザの作成.1 Salt作成 shell: "mktemp -u | awk '{print substr($0, length($0)-8+1)}'" register: salt - name: WEBユーザの作成.2 パスワード用ハッシュ作成 shell: python -c 'import crypt; print crypt.crypt("{{ usergroup.user.password }}", "$6${{ salt.stdout }}")' register: hash_password - name: WEBユーザの作成.3 ユーザ作成 user: name={{ usergroup.user.name }} password={{ hash_password.stdout }} groups={{usergroup.user.group}} - name: MariaDBクライアントインストール yum: name: "{{ package }}" state: latest vars: package: - MySQL-python - mariadb - name: PHPをインストール yum: name: "{{ package }}" state: latest enablerepo: remi-php71 vars: package: - php - php-mysql - php-mbstring - php-gd - php-devel - php-xml - php-pdo - php-fpm - php-mcrypt - php-zip - name: PHPのタイムゾーン設定 replace: dest: /etc/php.ini regexp: "{{ item.regexp }}" replace: "{{ item.replace }}" with_items: - { regexp: "^;date.timezone =", replace: "date.timezone = Asia/Tokyo" } - { regexp: "^expose_php = On", replace: "expose_php = Off" } - name: PHP 最大アップロード設定, メモリ設定 replace: dest: /etc/php.ini regexp: "{{ item.regexp }}" replace: "{{ item.replace }}" with_items: - { regexp: "^upload_max_filesize = .*$", replace: "upload_max_filesize = 256M" } - { regexp: "^memory_limit = .*$", replace: "memory_limit = 256M" } - name: PHP-FPM設定 replace: dest: /etc/php-fpm.d/www.conf regexp: "{{ item.regexp }}" replace: "{{ item.replace }}" with_items: - { regexp: "^user = apache", replace: "user = {{ usergroup.user.name }}" } - { regexp: "^group = apache", replace: "group = nginx" } - { regexp: "^listen = 127.0.0.1:9000", replace: "listen = /var/run/php-fpm/php-fpm.sock" } - { regexp: "^;listen.owner = nobody", replace: "listen.owner = {{ usergroup.user.name }}" } - { regexp: "^;listen.group = nobody", replace: "listen.group = nginx" } - name: PHP-FPMの起動 systemd: name: php-fpm.service state: restarted daemon_reload: yes enabled: yes - name: APPフォルダ作成 file: path="{{ app_path }}" state=directory owner=root group=root mode=0755 - name: Nginx設定 Ansibleサーバから設定ファイルを複製 copy: src: "{{ item }}" dest: /etc/nginx/conf.d/ owner: root group: root mode: 0644 with_fileglob: - "./web/etc/nginx/conf.d/*.conf" - name: Nginx設定 ユーザ指定 replace: dest: /etc/nginx/nginx.conf regexp: "{{ item.regexp }}" replace: "{{ item.replace }}" with_items: - { regexp: "^user nginx;", replace: "user = {{ usergroup.user.name }};" } - name: Nginxの起動 systemd: name: nginx.service state: restarted daemon_reload: yes enabled: yes - name: Composerのインストール command: "{{ item }}" with_items: - php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" - php composer-setup.php - php -r "unlink('composer-setup.php');" - mv composer.phar /usr/local/bin/composer - /usr/local/bin/composer global require laravel/installer - name: Laravelプロジェクトの作成 command: /usr/local/bin/composer create-project --prefer-dist laravel/laravel {{ app_path }} - name: バーチャルホストディレクトリの権限変更 file: path: /var/www/vhosts owner: "{{ usergroup.user.name }}" group: nginx recurse: yes - name: Laravelパーミッション設定1 file: path: "{{ app_path }}/{{ item }}" mode: 0755 recurse: yes with_items: - storage - bootstrap/cache - name: vsftpdインストール yum: name: "{{ package }}" state: latest vars: package: - vsftpd - name: vsftpd設定 Ansibleサーバから設定ファイルを複製 synchronize: src=./web/etc/vsftpd/ dest=/etc/vsftpd/ - name: vsftpd設定 replace: dest: /etc/vsftpd/vsftpd.conf regexp: "{{ item.regexp }}" replace: "{{ item.replace }}" with_items: - { regexp: "^pasv_address=", replace: "pasv_address={{ ansible_default_ipv4.address }}" } - name: vsftpd起動 systemd: name: vsftpd.service state: restarted daemon_reload: yes enabled: yes - hosts: db become: yes vars_files: - var_yml tasks: - name: EPELリポジトリの追加 yum: name: "{{ package }}" state: latest vars: package: - epel-release - name: MariaDB インストール yum: name: "{{ package }}" state: latest vars: package: - MySQL-python - mariadb - mariadb-libs - mariadb-server - mariadb-devel - name: MySQL起動, 自動起動 service: name=mariadb state=started enabled=yes - name: DBの作成 mysql_db: name={{ dbName }} state=present - name: DBユーザの作成 mysql_user: name={{ dbUser }} password={{ dbPassword }} priv={{ dbName }}.*:ALL state=present host={{item}} with_items: - '%' - 'localhost' - '127.0.0.1' - name: ローカル接続制限無効化 replace: > dest=/etc/my.cnf regexp='^bind-address' replace='#bind-address' - name: MySQL再起動, 自動起動 service: name=mariadb state=restarted enabled=yes - name: Apache, PHPインストール yum: name: "{{ package }}" state: latest vars: package: - httpd - php - php-mbstring - php-mysql - php-mcrypt - name: phpMyAdminインストール yum: name: "{{ package }}" state: latest vars: package: - phpMyAdmin - name: phpMyAdminアクセス権限の変更 ローカルネットワークのアクセス許可 replace: dest: /etc/httpd/conf.d/phpMyAdmin.conf regexp: "{{ item.regexp }}" replace: "{{ item.replace }}" with_items: - { regexp: "Require ip 127.0.0.1", replace: "Require ip 127.0.0.1 {{ mynetwork }}" } - name: PHP 最大アップロード設定 replace: dest: /etc/php.ini regexp: "{{ item.regexp }}" replace: "{{ item.replace }}" with_items: - { regexp: "^upload_max_filesize = .*$", replace: "upload_max_filesize = 256M" } - { regexp: "^memory_limit = .*$", replace: "memory_limit = 256M" } - name: Apache起動, 自動起動 service: name=httpd state=restarted enabled=yes - name: Firewalldの起動, 自動起動設定 service: name=firewalld state=started enabled=yes - name: Firewalld設定 3306許可 ローカルネットワークのみDBへの接続許可 firewalld: permanent=True port=3306/tcp source={{ mynetwork }} state=enabled immediate=true - name: Firewalld設定 80許可 phpMyAdmin用 firewalld: permanent=True port=80/tcp state=enabled immediate=true - name: Firewalldの再起動, 自動起動設定 service: name=firewalld state=restarted enabled=yes - hosts: all become: yes vars_files: - var_yml remote_user: root tasks: - name: yumアップデート yum: name=* state=latest - name: SELinux-1. SELinux用のPythonモジュールをインストール yum: name=libselinux-python state=installed - name: SELinux-2. SELinuxの無効化 selinux: state=disabled register: selinux - name: SELinux-3. サーバの再起動 shell: sleep 2 && shutdown -r now async: 1 poll: 0 become: true ignore_errors: true - name: SELinux-4. サーバの起動を待つ wait_for_connection: delay: 30 timeout: 300 - name: SELinux-5. 疎通確認 ping: |
チェックコマンド
1 2 3 4 5 |
構文チェック # ansible-playbook /etc/ansible/cp.example.net/v1/playbook.yml --syntax-check ドライラン # ansible-playbook /etc/ansible/cp.example.net/v1/playbook.yml --check |
どっかーん!サーバを一気に作っちゃお~。
ぽちっと実行
1 |
# ansible-playbook /etc/ansible/cp.example.net/v1/playbook.yml |
もりもりサーバが作られていきますね~!
サーバにアクセスしてみちゃおう!
OK…!
ムムッ!
これは・・・OK!
お疲れ様です。