Ansbile Automation PlatformでのYAMLの書き方

SIOS Blog

Ansible Automation Platformでは
1つの巨大なYAMLで複雑に分岐させたり、
ラベルで挙動を制御する可読性の悪くなりやすいAnsibleの書き方ではなく、
1つ1つは小さいYAMLをワークフローで分岐させて
YAMLを再利用しやすくなるようにして再利用性を高めております。

そのため例えばWordpressにおいては
Nginxインストール、Nginxの設定、PHPインストール、ドメイン設定、Wordpressダウンロードと分けていきます。
データストアであるMySQLないしはMariaDBのインストールとアップデートは厳密には冪等性が担保しきれないので今回は除外します。

Nginxインストール

$ mkdir nginx
$ cd nginx
$ ansible-galaxy init nginx
$ cat nginx/tasks/main.yml
---
# tasks file for nginx
- name: nginx
  dnf:
    name: nginx
    state: present
  notify:
    - restart nginx

- name: /var/www make
  file:
    path: "/var/www"
    state: directory
    owner: "nginx"
    group: "nginx"
    mode: "775"

$ cat nginx/handlers/main.yml
---
# handlers file for nginx
- name: restart nginx
  service:
    name=nginx
    state=restarted
    enabled=yes

$ cat nginx/nginx.yml
---
- name: nginx
  hosts: RHEL8
  #user: "{{ ssh_user }}"
  become: yes
  gather_facts: false

  roles:
  - name: nginx

プロジェクトを登録して、ジョブの登録に進みます。

PHPインストール

Nginxですのでphp-fpmを選びます。あまりこのymlは良くないかもしれません。

$ mkdir php
$ cd php
$ ansible-galaxy init php
$ cat php/tasks/main.yml
---
# tasks file for php
- name: php
  dnf:
    name:
    - php
    - php-mysqlnd
    - php-mbstring
    - php-pecl-zip
    - php-json
    - php-pear
    - php-gd
    state: present

- name: php is configured
  notify:
    - restart php
  lineinfile: dest="/etc/php.ini" state=present regexp="^\;date.timezone =$" line="date.timezone = Asia/Tokyo" backrefs=yes

- name: php-fpm is configured
  notify:
    - restart php
  lineinfile: >-
    dest='/etc/php-fpm.d/www.conf'
    state=present
    backrefs=yes
    regexp='{{ item.regexp }}'
    line='{{ item.line }}'
  with_items:
  - regexp: '^listen = /run/php-fpm/www.sock$'
    line: ';listen = /run/php-fpm/www.sock\n
         listen = 127.0.0.1:9000'

$ cat php/handlers/main.yml
---
# handlers file for php
- name: restart php
  service:
    name: "{{ item }}"
    state: restarted
    enabled: yes
  with_items:
    - nginx
    - php-fpm

$ cat php.yml
---
- name: php
  hosts: RHEL8
  #user: "{{ ssh_user }}"
  become: yes
  gather_facts: false

  roles:
  - name: php

プロジェクトを登録して、ジョブの登録に進みます。

ドメインの設定

PHP用のNginxファイルを設定します。
ドメインの数だけ必要になることを考えると
PHPとは別に切り出したほうが良さそうです。

$ mkdir php-url
$ cd php-url
$ ansible-galaxy init php-url
$ cat php-url/tasks/main.yml
---
# tasks file for php-url
- name: Set up wp-config
  template:
    src: "files/url.j2"
    dest: "/etc/nginx/conf.d/{{ URL | default('all') }}.conf"
  notify:
    - restart nginx

- name: delete php-fpm.conf
  file: path="{{ item }}"
        state=absent
  with_items:
    - "/etc/nginx/default.d/php.conf"
    - "/etc/nginx/conf.d/php-fpm.conf"
  notify:
    - restart nginx

$ cat php-url/files/url.j2
upstream php {
        server 127.0.0.1:9000;
}

server {
        ## Your website name goes here.
        server_name {{ URL | default('_') }};
        ## Your only path reference.
        root /var/www/{{ URL | default('all') }}/wordpress;
        ## This should be in your http block and if it is, it's not needed here.
        index index.php;

        location = /favicon.ico {
                log_not_found off;
                access_log off;
        }

        location = /robots.txt {
                allow all;
                log_not_found off;
                access_log off;
        }

        location / {
                # This is cool because no php is touched for static content.
                # include the "?$args" part so non-default permalinks doesn't break when using query string
                try_files $uri $uri/ /index.php?$args;
        }

        location ~ \.php$ {
                #NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
                include fastcgi.conf;
                fastcgi_intercept_errors on;
                fastcgi_pass php;
        }

        location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
                expires max;
                log_not_found off;
        }
}

$ cat php-url.yml
---
- name: php-url
  hosts: RHEL8
  #user: "{{ ssh_user }}"
  become: yes
  gather_facts: false

  roles:
  - name: php-url

プロジェクトを登録して、ジョブの登録に進みます。

WordPressダウンロード

今の最新バージョンからファイルを取り込む処理はないので
アップデートはもう少し作りこむ必要があります。

$ mkdir wordpress
$ cd wordpress
$ ansible-galaxy init wordpress
$ cat wordpress/tasks/main.yml
---
# tasks file for wordpress
- name: Download wordPress
  get_url:
    url: "https://ja.wordpress.org/wordpress-{{ WP_VER }}-ja.tar.gz"
    dest: /tmp
- name: Unzip wordPress
  unarchive:
    src: "/tmp/wordpress-{{ WP_VER }}-ja.tar.gz"
    dest: "/var/www/{{ URL | default(omit) }}"
    remote_src: yes
- name: chown -R apache:apache /var/www/wordpress
  file:
    path: "/var/www/{{ URL | default(omit) }}/wordpress"
    state: directory
    owner: nginx
    group: nginx
    recurse: yes

- name: Set up wp-config
  template:
    src: "files/wp-config.php.j2"
    dest: "/var/www/{{ URL | default(omit) }}/wordpress/wp-config.php"

$ cat wordpress/files/wp-config.php.j2
<?php
/**
 * The base configuration for WordPress
 *
 * The wp-config.php creation script uses this file during the
 * installation. You don't have to use the web site, you can
 * copy this file to "wp-config.php" and fill in the values.
 *
 * This file contains the following configurations:
 *
 * * MySQL settings
 * * Secret keys
 * * Database table prefix
 * * ABSPATH
 *
 * @link https://codex.wordpress.org/Editing_wp-config.php
 *
 * @package WordPress
 */

// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define( 'DB_NAME', '{{ MYSQL_USER_DB }}' );

/** MySQL database username */
define( 'DB_USER', '{{ MYSQL_USER_NAME }}' );

/** MySQL database password */
define( 'DB_PASSWORD', '{{ MYSQL_USER_PASS }}' );

/** MySQL hostname */
define( 'DB_HOST', 'MYSQL_WP_HOST' );

/** Database Charset to use in creating database tables. */
define( 'DB_CHARSET', 'utf8mb4' );

/** The Database Collate type. Don't change this if in doubt. */
define( 'DB_COLLATE', '' );

/** Filesystem access **/
define('FS_METHOD', 'direct');

/**#@+
 * Authentication Unique Keys and Salts.
 *
 * Change these to different unique phrases!
 * You can generate these using the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service}
 * You can change these at any point in time to invalidate all existing cookies. This will force all users to have to log in again.
 *
 * @since 2.6.0
 */
define( 'AUTH_KEY',         '{{ lookup('password', '/dev/null chars=ascii_letters length=64') }}' );
define( 'SECURE_AUTH_KEY',  '{{ lookup('password', '/dev/null chars=ascii_letters length=64') }}' );
define( 'LOGGED_IN_KEY',    '{{ lookup('password', '/dev/null chars=ascii_letters length=64') }}' );
define( 'NONCE_KEY',        '{{ lookup('password', '/dev/null chars=ascii_letters length=64') }}' );
define( 'AUTH_SALT',        '{{ lookup('password', '/dev/null chars=ascii_letters length=64') }}' );
define( 'SECURE_AUTH_SALT', '{{ lookup('password', '/dev/null chars=ascii_letters length=64') }}' );
define( 'LOGGED_IN_SALT',   '{{ lookup('password', '/dev/null chars=ascii_letters length=64') }}' );
define( 'NONCE_SALT',       '{{ lookup('password', '/dev/null chars=ascii_letters length=64') }}' );

/**#@-*/

/**
 * WordPress Database Table prefix.
 *
 * You can have multiple installations in one database if you give each
 * a unique prefix. Only numbers, letters, and underscores please!
 */
$table_prefix = 'wp_';

/**
 * For developers: WordPress debugging mode.
 *
 * Change this to true to enable the display of notices during development.
 * It is strongly recommended that plugin and theme developers use WP_DEBUG
 * in their development environments.
 *
 * For information on other constants that can be used for debugging,
 * visit the Codex.
 *
 * @link https://codex.wordpress.org/Debugging_in_WordPress
 */
define( 'WP_DEBUG', false );

/* That's all, stop editing! Happy publishing. */

/** Absolute path to the WordPress directory. */
if ( ! defined( 'ABSPATH' ) ) {
define( 'ABSPATH', dirname( __FILE__ ) . '/' );
}

/** Sets up WordPress vars and included files. */
require_once( ABSPATH . 'wp-settings.php' );

$ cat wordpress.yml
---
- name: nginx
  hosts: RHEL8
  #user: "{{ ssh_user }}"
  become: yes
  gather_facts: false

  roles:
  - name: wordpress

プロジェクトを登録して、ジョブの登録に進みます。

ワークフローテンプレートの作成

phpの設定以降は依存関係がないので並列実行させていきます。
各ジョブで変数を指定していて不思議に思われた方もいるかと存じますが
きちんと各ジョブが実行できるようになりましたら
各ジョブの変数をワークフローに以降するように私はしております。