【Ansible】Ansible と expect で MySQL 導入を自動化する【IaC】

こんにちは。
MySQL の導入が面倒だったので Ansible と expect で自動化にチャレンジします。

mysql_secure_installation の自動化

expect と awk でシェルスクリプトを作成します。

#!/bin/bash


# 初期パスワードを取得
IntPasswd=$(grep "A temporary password is generated for root@localhost:" /var/log/mysqld.log | awk '{ print $13}')

# パスワード指定
MysqlRootPasswd="{{ db_passwd }}"

expect -c '
    set timeout 10;
    spawn mysql_secure_installation;
    expect "Enter password for user root:";
    send -- "'"${IntPasswd}"'\n";
    expect "New password:";
    send -- "'"${MysqlRootPasswd}"'\n";
    expect "Re-enter new password:";
    send -- "'"${MysqlRootPasswd}"'\n";
    expect "Change the password for root ?";
    send "n\n";
    expect "Remove anonymous users?";
    send "y\n";
    expect "Disallow root login remotely?";
    send "y\n";
    expect "Remove test database and access to it?";
    send "y\n";
    expect "Reload privilege tables now?";
    send "y\n";
    interact;'

awk で初期パスワードを取得し、対話処理は expect で処理します。

Playbook

Ansible の playbook で処理します。

---
# tasks file for mysql-server80
- name: install mysql80 repository
  yum:
    name: https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
    state: present

- name: install mysql
  yum:
    name:
      - mysql-server
      - expect
    state: present

- name: put my.cnf
  template:
    src: ../templates/my.cnf.j2
    dest: /etc/my.cnf
    owner: root
    group: root
    mode: 0644
    backup: yes

- name: mkdir /var/log/mysql/
  file:
    path: /var/log/mysql
    state: directory
    owner: mysql
    group: mysql
    mode: 0755

- name: start mysql
  systemd:
    name: mysqld
    state: started
    enabled: yes

- name: confirm check_file
  stat: path=/usr/local/etc/mysql_stat.txt
  register: result_mysql_exit

- name: put mysql_secure_installation_script
  template:
    src: ../templates/mysql_secure_installation_script
    dest: /tmp/mysql_secure_installation_script
    owner: root
    group: root
    mode: 0755

- name: exec mysql_secure_installation_script
  shell: "/tmp/mysql_secure_installation_script"
  when: not result_mysql_exit.stat.exists

- name: create check_file
  file:
    path: /usr/local/etc/mysql_stat.txt
    state: touch
    mode: "u=rw,g=r,o=r"

- name: change error-log location
  lineinfile:
    dest: /etc/my.cnf
    state: present
    backrefs: yes
    regexp: '^log-error = /var/log/mysqld.log'
    line: 'log-error = /var/log/mysql/mysqld.log'
  notify: mysqld_restart

おまけ

こちらに CentOS7用の playbook を纏めていますので宜しければ。
https://github.com/keisukesanuki/default-CentOS7

【監視設定】Zabbix Proxy の設定【踏み台経由】

設定ですごく嵌ったんですね。
踏み台サーバ経由で監視設定をいれる方法です。

zabbix-proxy 導入

各種パッケージのインストール

※ CentOS6

rpm -ivh http://repo.zabbix.com/zabbix/3.4/rhel/6/x86_64/zabbix-release-3.4-1.el6.noarch.rpm

yum install zabbix-proxy zabbix-proxy-sqlite3 zabbix-agent

※ CentOS7
rpm -ivh http://repo.zabbix.com/zabbix/3.4/rhel/7/x86_64/zabbix-release-3.4-2.el7.noarch.rpm

yum install zabbix-proxy zabbix-proxy-sqlite3 zabbix-agent

sqlite 設定

mkdir /var/lib/sqlite3
chown -R zabbix:zabbix /var/lib/sqlite3
cd /var/lib/sqlite3
zcat /usr/share/doc/zabbix-proxy-sqlite3-3.4.15/schema.sql.gz | sqlite3 zabbix.db
chown zabbix:zabbix zabbix.db

zabbix-proxy 設定

sed -i -e "s/^Server=.*\$/Server=xxx.xxx.xxx.xxx/g" /etc/zabbix/zabbix_proxy.conf
sed -i -e "s/^Hostname=.*\$/Hostname=${HOSTNAME}/g" /etc/zabbix/zabbix_proxy.conf
sed -i -e "s/^DBName=.*\$/DBName=\/var\/lib\/sqlite3\/zabbix.db/g" /etc/zabbix/zabbix_proxy.conf

※ xxx.xxx.xxx.xxx は Zabbix サーバの IP

zabbix-agent 設定

sed -i -e "s/^Hostname=.*\$/Hostname=${HOSTNAME}/g" /etc/zabbix/zabbix_agentd.conf

zabbix-proxy 起動

/etc/init.d/zabbix-proxy start
chkconfig zabbix-proxy on
/etc/init.d/zabbix-agent start
chkconfig zabbix-agent on

zabbix-agent 導入

各種パッケージのインストール

※ CentOS6

rpm -ivh http://repo.zabbix.com/zabbix/3.4/rhel/6/x86_64/zabbix-release-3.4-1.el6.noarch.rpm

yum install zabbix-agent

※ CentOS7
rpm -ivh http://repo.zabbix.com/zabbix/3.4/rhel/7/x86_64/zabbix-release-3.4-2.el7.noarch.rpm

yum install zabbix-agent

zabbix-agent 設定

sed -i -e "s/^ServerActive/ServerActive=xxx.xxx.xxx.xxx/g" /etc/zabbix/zabbix_agentd.conf
sed -i -e "s/^Hostname=.*\$/Hostname=${HOSTNAME}/g" /etc/zabbix/zabbix_agentd.conf
sed -i -e "s/^Server=.*\$/Server=xxx.xxx.xxx.xxx/g" /etc/zabbix/zabbix_agentd.conf

※ xxx.xxx.xxx.xxx は踏み台( proxy )サーバの IP

zabbix-agent 起動

/etc/init.d/zabbix-agent start
chkconfig zabbix-agent on

【サーバ移設】踏み台サーバを経由してrsyncする方法【rsync】

こんにちは。
先日にサーバ移設案件に携わる機会があって、踏み台サーバを経由して、目的のサーバにデータを同期する必要がありました。
その際に先輩に教えてもらった方法をメモレベルで残しておこうと思います。

rsync 用ユーザ作成

useradd rsync
su rsync
cd ~
mkdir .ssh
chmod 700 .ssh

SSH 設定

vi /home/rsync/.ssh/config
===============================================
Host step-new
    HostName      111.111.111.111
    User          step-new-user
    IdentityFile  ~/.ssh/id_rsa_step-new.pem
Host step-old
    ProxyCommand  ssh -W %h:%p step-new
    HostName      222.222.222.222
    User          step-old-user
    IdentityFile  ~/.ssh/id_rsa_step-old.pem
Host target-server
    ProxyCommand  ssh -W %h:%p step-old
    HostName      333.333.333.333
    User          target-server-user
    IdentityFile  ~/.ssh/id_rsa_target.pem
===============================================

vi ~/.ssh/id_rsa_step-new.pem
vi ~/.ssh/id_rsa_step-old.pem
vi ~/.ssh/id_rsa_target.pem

chmod 600 ~/.ssh/id_rsa_step-new.pem
chmod 600 ~/.ssh/id_rsa_step-old.pem
chmod 600 ~/.ssh/id_rsa_target.pem

データ同期

mkdir -p /var/tmp/rsync_results/test1
nohup time rsync -avzrn --rsync-path="sudo rsync" target-server:/home/target-server-user/ /home/purpose/ 1>/var/tmp/rsync_results/test1/result_$(date +"%Y%m%d").log 2>/var/tmp/rsync_results/test1/error_$(date +"%Y%m%d").log &
nohup time rsync -avzr --rsync-path="sudo rsync" target-server:/home/target-server-user/ /home/purpose/ 1>/var/tmp/rsync_results/test1/result_$(date +"%Y%m%d").log 2>/var/tmp/rsync_results/test1/error_$(date +"%Y%m%d").log &

補足

・.ssh/ 以下に config ファイルを作成することで、踏み台サーバを経由して接続が出来る。
・秘密鍵は事前に配置しておく必要がある。

【ファイル共有】nfsサーバの構築手順【構築手順】

こんにちは。
移設案件でnfsサーバを構築したので、
備忘録として手順を残しておきます。

サーバ

nfs用のディレクトリの準備

mkfs -t xfs /dev/xvdf
mkdir /mnt/nfsserv/
chmod 777 /mnt/nfsserv/
mount -t xfs -o nouuid /dev/xvdf /mnt/nfsserv/

fstabの編集

vi /etc/fstab
===================================================================
/dev/xvdf /mnt/nfsserv             xfs     defaults        0 0
===================================================================

nfsパッケージの導入

yum install nfs-utils
systemctl start rpcbind
systemctl start nfs-server
systemctl enable rpcbind
systemctl enable nfs-server

nfs設定ファイルの編集

vi /etc/exports
=================================================================
/mnt/nfsserv/   10.204.68.0/255.255.255.0(rw,sync,no_root_squash)
=================================================================

systemctl restart rpcbind
systemctl restart nfs-server

クライアント

nfsパッケージの導入

yum install nfs-utils
systemctl start rpcbind
systemctl enable rpcbind

マウント

mkdir /data
mount -t nfs 10.204.68.32:/mnt/nfsserv /data

fstabの編集

vi /etc/fstab
======================================================================
10.204.68.32:/mnt/nfsserv /data    nfs     defaults,_netdev        0 0
======================================================================

【シェルスクリプト】apacheのrotatelogsとシェルスクリプトでログ管理をする【運用】

お疲れ様です。
rotatelogsでapacheのログを出力している環境でログを管理する必要があったので、忘備録として残しておきます。

背景

CustomLog "|/usr/local/apache2/bin/rotatelogs /usr/local/apache2/logs/access_log.%Y%m%d%H 14400 540" combined  env=!no_log
ErrorLog "|/usr/local/apache2/bin/rotatelogs /usr/local/apache2/logs/error_log.%Y%m%d 86400 540"

apacheに標準でついてくるrotatelogsでログが世代管理されている前提でですね、
2週間経過したログは削除、1日経過したログは圧縮するスクリプトを作ってcronに登録してみます。

スクリプトの作成

vi /usr/local/bin/apache_accesslog_compress.sh
====================================================================
#!/bin/sh
#ディレクトリを移動する
cd /usr/local/apache2/logs
#14日経過したログを削除する
find ./ -name 'access_log.*' -mtime +13 -daystart -exec rm {} \;
#1日経過したログを圧縮する
find ./ -name 'access_log.*' -mtime +0 -daystart  -exec gzip {} \;
====================================================================

findコマンドの-daystartは
コマンドを実行した日の00:00を-mtimeの基準とするオプションです。

cronへの登録

crontab -e
=======================================================
00 04 * * * /usr/local/bin/apache_accesslog_compress.sh
=======================================================

古い MySQL インストール方法

こんにちは。
古いバージョンの MySQL をインストールする際に少し躓いたので備忘録を残しておきます。

手順

wget https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.24-1.el7.x86_64.rpm-bundle.tar
tar -xvf mysql-5.7.24-1.el7.x86_64.rpm-bundle.tar

yum localinstall mysql-community-server-5.7.24-1.el7.x86_64.rpm \
mysql-community-client-5.7.24-1.el7.x86_64.rpm \
mysql-community-common-5.7.24-1.el7.x86_64.rpm \
mysql-community-devel-5.7.24-1.el7.x86_64.rpm \
mysql-community-libs-5.7.24-1.el7.x86_64.rpm \
mysql-community-libs-compat-5.7.24-1.el7.x86_64.rpm

【tips】コメントアウトを省いて設定ファイルを確認する方法

お疲れ様です。
最近サーバの構築チームに移動になりました。
表題の通りです。

コメントアウトを省いて設定ファイルを確認する

grep -v -e '^\s*#' -e '^\s*$' 【設定ファイル】

例題

↓こんな感じです。

[root@ansible-dev etc]# grep -v -e '^\s*#' -e '^\s*$' /etc/ansible/ansible.cfg
[defaults]
roles_path    = /etc/ansible/roles:/usr/share/ansible/roles
[inventory]
[privilege_escalation]
[paramiko_connection]
[ssh_connection]
[persistent_connection]
[accelerate]
[selinux]
[colors]
[diff]

MySQL が停止して困った話

こんにちは。
メモリが枯渇して MySQL が起動しなくなったので、SWAP を追加したお話です。

背景

最近、メモリ不足で MySQL が勝手に停止する事象が発生してました。
取り急ぎ、下記のようなスクリプトを cron に登録してたのですが、さらに SWAP 領域を作成しておきます。

#!/bin/bash
ProcessName=mysqld
count=`ps aux | grep $ProcessName | grep -v grep | wc -l`
if [ $count = 0 ]; then
sudo systemctl restart $ProcessName
echo "$(date)_$ProcessName is dead" >> /var/log/mysqld/statu_log.txt
else
echo "$(date)_$ProcessName is alive" >> /var/log/mysqld/statu_log.txt
fi

dd if=/dev/zero of=/swap.img bs=1M count=500
chmod 600 /swap.img
mkswap /swap.img
swapon /swap.img
cp -p /etc/fstab /etc/fstab_20181118
vim /etc/fstab
================================
/swap.img swap swap defaults 0 0
================================
systemctl status mysqld

Let’s Encrypt で証明書を取得する

こんにちは。
急に寒くなってきましたね。
ところで Let’s Encrypt でサイトを SSL化しました。
その際の備忘録になります。

certbotのインストール

epel から certbot のパッケージを落とします。

yum install epel-release
yum install certbot

証明書の取得

certbot certonly --webroot \
-w 【ドキュメントルート】 \
-d 【ドメイン名】 \
-m 【メールアドレス】 \
--agree-tos -n

※ 下記ディレクトリに証明書が生成されます。

# サーバ証明書
/etc/letsencrypt/live/【ドメイン名】/cert.pem
# 秘密鍵
/etc/letsencrypt/live/【ドメイン名】/privkey.pem
# 中間証明書
/etc/letsencrypt/live/【ドメイン名】/chain.pem

あとは、WEBサーバに設定すればOK

<VirtualHost *:443>
   ServerAdmin n41210guitar@gmail.com
   ServerName fingerease.work
   DocumentRoot "/var/www/vhosts/fingerease.work/public_html"
   DirectoryIndex wordpress index.php index.html index.xml
   <Directory /var/www/vhosts/fingerease.work/public_html>
           Options FollowSymLinks
           AllowOverride all
   </Directory>
   
   SSLEngine on
   SSLProtocol             all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
   SSLCipherSuite          ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
   SSLHonorCipherOrder     off

   SSLCertificateFile /etc/letsencrypt/live/fingerease.work/cert.pem
   SSLCertificateKeyFile /etc/letsencrypt/live/fingerease.work/privkey.pem
   SSLCertificateChainFile /etc/letsencrypt/live/fingerease.work/chain.pem

   CustomLog "/var/log/httpd/fingerease.work-ssl-access_log" combined
   ErrorLog  "/var/log/httpd/fingerease.work-ssl-error_log"
</VirtualHost>