VPSのセットアップ(userの作成, ssh, firewall設定など)をAnsibleでやってみます。
rootで行うか、作成した管理用userで実行するかの切り分けが難しいですが、以下のような流れにします。
- rootでinit.ymlを実行
- userの作成
- sshの設定
- firewallの設定
- 管理用userでbootstrap.ymlを実行
- zsh, git, nginx, dockerをインストール
Vagrantで立てたVM(192.168.33.12)をテスト用に使い、うまくいったら実際のVPSに適用します。
下記のサイトをかなり参考にさせていただきました。
Ansible でさくらのVPS の環境構築を自動化 ~ハマりポイントとともに~
AnsibleでVPS初期設定
ファイル構成
├── bootstrap.yml
├── group_vars
│ ├── production
│ └── test
├── hosts
├── init.yml
├── roles
│ ├── docker
│ │ └── tasks
│ │ └── main.yml
│ ├── git
│ │ └── tasks
│ │ └── main.yml
│ ├── nginx
│ │ └── tasks
│ │ └── main.yml
│ ├── yum
│ │ └── tasks
│ │ └── main.yml
│ └── zsh
│ ├── files
│ │ └── zsh
│ │ └── completion
│ │ ├── _git
│ │ └── git-completion.bash
│ ├── tasks
│ │ └── main.yml
│ └── templates
│ └── zshrc
└── templates
└── iptables.j2
インベントリ関連
[production]
# VPSのIPアドレス
[test]
192.168.33.12
# 初期設定後に使う接続情報
ansible_ssh_user: admin
ansible_ssh_port: 10022
ansible_ssh_private_key_file: keys/id_rsa-test # init.ymlを実行することで、このファイルが生成される
# 初期設定用の変数
ssh_user: admin
ssh_port: 10022
ssh_user_password: **** # 次のコマンドにて生成 $ openssl passwd -salt <salt> -1 <password>
ssh_private_key_file: id_rsa-test # このファイル名で、管理用userの秘密鍵を取得する
ansible_ssh_user: admin
ansible_ssh_port: 10022
ansible_ssh_private_key_file: keys/id_rsa-production
ssh_user: admin
ssh_port: 10022
ssh_user_password: ****
ssh_private_key_file: id_rsa-production
初期設定
---
- hosts: test
tasks:
- name : add user
user :
name : "{{ ssh_user }}"
groups : wheel
password : "{{ ssh_user_password }}"
generate_ssh_key : yes
ssh_key_bits : 2048
- name : register public key
command : /bin/cp /home/{{ ssh_user }}/.ssh/id_rsa.pub /home/{{ ssh_user }}/.ssh/authorized_keys
- name : change permission
file :
path : /home/{{ ssh_user }}/.ssh/authorized_keys
owner : "{{ ssh_user }}"
group : "{{ ssh_user }}"
mode : 0600
- name : allow wheel group to sudo
lineinfile :
dest : /etc/sudoers
state : present
regexp : "^#\\s*(%wheel\\s+ALL=\\(ALL\\)\\s+NOPASSWD{{':'}}\\s+ALL)"
line : "\\1"
backrefs : yes
validate : "visudo -cf %s"
backup : yes
- name : forbid ssh password login
lineinfile :
dest : /etc/ssh/sshd_config
state : present
regexp : "^PasswordAuthentication yes"
line : "PasswordAuthentication no"
backrefs : yes
backup : yes
- name : permit specific user to ssh login
lineinfile :
dest : /etc/ssh/sshd_config
state : present
regexp : "^AllowUsers"
line : "AllowUsers {{ ssh_user }}"
backup : yes
- name : change ssh port
lineinfile :
dest : /etc/ssh/sshd_config
state : present
regexp : "#^Port"
line : "Port {{ ssh_port }}"
backup : yes
- name : fetch private key
fetch :
src : /home/{{ ssh_user }}/.ssh/id_rsa
dest : keys/{{ ssh_private_key_file }}
validate_md5 : yes
fail_on_missing : yes
flat : yes
- name : update firewall setting
template :
src : templates/iptables.j2
dest : /etc/sysconfig/iptables
- name : restart services
command : service sshd restart && service iptables restart
sshd, iptablesの再起動にserviceモジュールを使わないのは、別taskだとssh connectionも別になり、閉め出されてしまうためです。
Firewallは、sshポートと80番だけ開けるようにします。
# Firewall configuration written by system-config-firewall
# Manual customization of this file is not recommended.
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport {{ ssh_port }} -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
COMMIT
管理用userで実行する部分
---
- hosts : test
sudo : yes
roles :
- yum
- zsh
- git
- nginx
- docker
---
- name : add epel repository
yum :
name : http://ftp.riken.jp/Linux/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm
- name : update
yum :
name : "*"
state : latest
---
- name : install zsh
yum :
name : zsh
state : present
- name : change default shell
user :
name : "{{ ansible_ssh_user }}"
shell: /bin/zsh
state : present
- name : update zshrc
template:
src: zshrc
dest: /home/{{ ansible_ssh_user }}/.zshrc
- name : setup git completion files
copy :
src : zsh
dest : /home/{{ ansible_ssh_user }}/.zsh
- name : rebuild zcompdump
command: "rm -f ~/.zcompdump; compinit"
templateモジュールはロール名/templates
ディレクトリの中、
copyモジュールはロール名/files
ディレクトリの中を見に行くので、zsh(ディレクトリ)はfilesに置いています。
---
- name : install git
yum :
name : git
state : present
---
- name: add nginx rpm
yum:
name: http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm
state: present
- name: install nginx
yum:
name: nginx
state: present
- name: activate service
service:
name: nginx
state: restarted
enabled: yes
---
- name: install docker
yum:
name: docker-io
state: present
- name: activate service
service:
name: docker
state: started
enabled: yes
実行手順
初期設定
使っているVPSなど環境によって違いますが、22番+パスワードでログインする場合、以下のようなコマンドを叩きます。
$ ansible-playbook init.yml -i hosts -k -c paramiko -e ansible_ssh_port=22 -e ansible_ssh_user=root
-kは--ask-pass、-cはssh接続に使用するconnectionの種類です。
defaultのconnectionでは、パスワード認証が許可されないため、paramiko(pythonライブラリ)を指定します。
-eは--extra-varsで、変数を上書きするために使用します。
初期設定後
初期設定によって秘密鍵が取得できたので、以降はこれでOKです。
$ ansible-playbook bootstrap.yml -i hosts
注意点
VPSに適用した際、AllowUsers {{ ssh_user }}
が/etc/ssh/sshd_config
のMatchブロックの中に挿入されたため、sshdが起動できなくなりました。
VPSの管理コンソールで入って難を逃れましたが、正規表現で置換する系のタスクは、まず初期状態を確認するか、templateモジュールにしたほうがよいかもしれません。
まとめ
- roleを分けたが、各タスクで大したことしてないので、あまり意味はなかった。
- テスト用VMは実際のVPSと同じ環境を用意するべき(当たり前か)
- 冪等性を保証するのが難しい。