Qiang Blog

Just another zhangjingqiang's blog.

How to bulk set multiple servers use different colors with ansible?

2017年1月Gitlab的数据库误删除事件使全世界对服务器的安全重视起来,把不同的服务器设置成不同的颜色背景是一个较有效的方法。下面使用 Ansible 设置 Tmux 的 powerline 区分不同环境的服务器。

Directory

.
├── README.md
└── provisioning
    ├── files
    │   └── .zshrc.yml
    ├── inventory
    ├── playbook.yml
    ├── tasks
    │   ├── tmux.yml
    │   └── zsh.yml
    └── templates
        └── .tmux.conf.j2

How to use?

$ cd provisioning
$ ansible-playbook playbook.yml -i inventory

Source

provisioning/files/.zshrc

if [ "$TMUX" = ""   ]; then tmux; fi

provisioning/templates/.tmux.conf.j2

source-file "/home/{{username}}/.tmux-themepack/powerline/block/{{color}}.tmuxtheme"

provisioning/tasks/tmux.yml

---
- name: Install the latest version of Tmux
  yum: name=tmux state=latest

- name: Install tmux-thmepack
  git: repo=https://github.com/jimeh/tmux-themepack
       dest=/home/{{username}}/.tmux-themepack

- name: Copy .tmux.conf file to servers
  template:
    src: templates/.tmux.conf.j2
    dest: /home/{{username}}/.tmux.conf

provisioning/tasks/zsh.yml

---
- name: Install the latest version of Zsh
  yum: name=zsh state=latest

- name: Copy .zshrc file to servers
  copy:
    src: files/.zshrc
    dest: /home/{{username}}/.zshrc

- name: Start zsh shell
  user: name={{username}} shell=/bin/zsh

provisioning/playbook.yml

---
- hosts: all
  become: yes
  vars_prompt:
    name: "username"
    prompt: "Enter username"
    private: no

  tasks:
    - include: tasks/tmux.yml
    - include: tasks/zsh.yml

provisioning/inventory

[server1]
app1.server1
app2.server1

[server1:vars]
color=blue

[server2]
app1.server2
app2.server2

[server2:vars]
color=orange

[server3]
app1.server3
app2.server3

[server3:vars]
color=red

[servers:children]
server1
server2
server3

ansible tmux zsh

How to setup Local Infrastructure Development with Ansible and Vagrant by Ad-Hoc Commands

Make work directory

$ mkdir work && cd work

Make Vagrantfile

# -*- mode: ruby -*-
# vi: set ft=ruby :

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.ssh.insert_key = false
    config.vm.provider :virtualbox do |vb|
    vb.customize ["modifyvm", :id, "--memory", "256"]
  end

  # Application server 1.
  config.vm.define "app1" do |app|
    app.vm.hostname = "orc-app1.dev"
    app.vm.box = "geerlingguy/centos7"
    app.vm.network :private_network, ip: "192.168.60.4"
  end

  # Application server 2.
  config.vm.define "app2" do |app|
    app.vm.hostname = "orc-app2.dev"
    app.vm.box = "geerlingguy/centos7"
    app.vm.network :private_network, ip: "192.168.60.5"
  end

  # Database server.
  config.vm.define "db" do |db|
    db.vm.hostname = "orc-db.dev"
    db.vm.box = "geerlingguy/centos7"
    db.vm.network :private_network, ip: "192.168.60.6"
  end
end

Run vagrant

$ vagrant up

Edit /etc/ansible/hosts

# Lines beginning with a # are comments, and are only included for
# illustration. These comments are overkill for most inventory files.

# Application servers
[app]
192.168.60.4
192.168.60.5

# Database server
[db]
192.168.60.6

# Group 'multi' with all servers
[multi:children]
app
db

# Variables that will be applied to all servers
[multi:vars]
ansible_ssh_user=vagrant
ansible_ssh_private_key_file=~/.vagrant.d/insecure_private_key

Setup

$ ansible multi -a "hostname"
$ ansible multi -a "hostname" -f 1
$ ansible multi -a "df -h"
$ ansible multi -a "free -m"
$ ansible multi -a "date"
$ ansible multi -s -m yum -a "name=ntp state=present"
$ ansible multi -s -m service -a "name=ntpd state=started enabled=yes"
$ ansible multi -s -a "service ntpd stop"
$ ansible multi -s -a "ntpdate -q 0.rhel.pool.ntp.org"
$ ansible multi -s -a "service ntpd start"
$ ansible app -s -m yum -a "name=MySQL-python state=present"
$ ansible app -s -m yum -a "name=python-setuptools state=present"
$ ansible app -s -m easy_install -a "name=django"
$ ansible app -a "python -c 'import django; print django.get_version()'"
$ ansible db -s -m yum -a "name=mariadb-server state=present"
$ ansible db -s -m service -a "name=mariadb state=started enabled=yes"
$ ansible db -s -a "iptables -F"
$ ansible db -s -a "iptables -A INPUT -s 192.168.60.0/24 -p tcp -m tcp --dport 3306 -j ACCEPT"
$ ansible db -s -m yum -a "name=MySQL-python state=present"
$ ansible db -s -m mysql_user -a "name=django host=% password=12345 priv=*.*:ALL state=present"
$ ansible app -s -a "service ntpd status"
$ ansible app -s -a "service ntpd restart" --limit "192.168.60.4"
$ ansible app -s -a "service ntpd restart" --limit "*.4"
$ ansible app -s -a "service ntpd restart" --limit ~".*\.4"
$ ansible app -s -m group -a "name=admin state=present"
$ ansible app -s -m user -a "name=johndoe group=admin createhome=yes"
$ ansible app -s -m user -a "name=johndoe state=absent remove=yes"
$ ansible multi -m stat -a "path=/etc/environment"
$ ansible multi -m copy -a "src=/etc/hosts dest=/tmp/hosts"
$ ansible multi -s -m fetch -a "src=/etc/hosts dest=/tmp"
$ ansible multi -m file -a "dest=/tmp/test mode=644 state=directory"
$ ansible multi -m file -a "src=/src/symlink dest=/dest/symlink owner=root group=root state=link"
$ ansible multi -m file -a "dest=/tmp/test state=absent"
$ ansible multi -s -B 3600 -a "yum -y update"
$ ansible multi -s -m async_status -a "jid=763350539037"
$ ansible multi -B 3600 -P 0 -a "/path/to/fire-and-forget-script.sh"
$ ansible multi -s -a "tail /var/log/messages"
$ ansible multi -s -m shell -a "tail /var/log/messages | grep ansible-command | wc -l"
$ ansible multi -s -m cron -a "name='daily-cron-all-servers' hour=4 job='/path/to/daily-script.sh'"
$ ansible multi -s -m cron -a "name='daily-cron-all-servers' state=absent"
$ ansible app -s -m git -a "repo=git://example.com/path/to/repo.git dest=/opt/myapp update=yes version=1.2.4"
$ ansible app -s -a "/opt/myapp/update.sh"

Reference

Ansible for DevOps(Chapter 3)

ansible vagrant