2016年2月27日土曜日

[SOS JobScheduler] Ansible で Windowsのジョブを実行する


SOS JobScheduler のエージェントが有償ライセンスになったらしい。
でも、有償でなくても、同時に1タスクまでだったら起動できるみたい。

Unix系OSのジョブは、SSHで実行できるので、Windowsのジョブが実行できれば、エージェントがなくても、そんなに困らないと思う。
(エージェントを使いたい状況が、Windowsのジョブ実行以外で、思いつかない。。。)

そこで、JobSchedulerのエージェントを使わずに、Windowsのジョブを実行する方法を考えてみました。

Windowsに OpenSSHサービスを入れる方法もありますが、今回は、最近使い始めた Ansible を利用してWindowsのジョブを実行できるか試してみます。

AnsibleはWindowsに対してWindows Remote Management(WinRM)というものを使用して操作を行います。

Ansible で Windows を操作する環境をセットアップする方法は、下記URLが詳しいです。


Ansible + Windowsの準備


今回は、Windows2012を使用します。
AnsibleでWindowsを使用する手順は上記で紹介したページのとおり。

Windows2012では、PowerShell で以下のようにコマンドを実行しました。
Windows PowerShell
Copyright (C) 2012 Microsoft Corporation. All rights reserved.

PS C:\Users\Administrator> Get-NetConnectionProfile -IPv4Connectivity Internet


Name             : ネットワーク
InterfaceAlias   : イーサネット
InterfaceIndex   : 12
NetworkCategory  : Public
IPv4Connectivity : Internet
IPv6Connectivity : NoTraffic



PS C:\Users\Administrator> Set-NetConnectionProfile -InterfaceAlias (Get-NetConnectionProfile -IPv4Connectivity Internet).InterfaceAlias -NetworkCategory Private
PS C:\Users\Administrator> Get-NetConnectionProfile -IPv4Connectivity Internet


Name             : ネットワーク
InterfaceAlias   : イーサネット
InterfaceIndex   : 12
NetworkCategory  : Private
IPv4Connectivity : Internet
IPv6Connectivity : NoTraffic



PS C:\Users\Administrator> mkdir C:\work


    ディレクトリ: C:\


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d----        2016/02/27      5:06            work


PS C:\Users\Administrator> cd C:\work
PS C:\work> Invoke-WebRequest -Uri https://raw.githubusercontent.com/ansible/ansible/devel/examples/scripts/ConfigureRemotingForAnsible.ps1 -OutFile ConfigureRemotingForAnsible.ps1
PS C:\work> ls


    ディレクトリ: C:\work


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---        2016/02/27      5:08       6239 ConfigureRemotingForAnsible.ps1


PS C:\work> powershell -ExecutionPolicy RemoteSigned .\ConfigureRemotingForAnsible.ps1


wxf                 : http://schemas.xmlsoap.org/ws/2004/09/transfer
a                   : http://schemas.xmlsoap.org/ws/2004/08/addressing
w                   : http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd
lang                : ja-JP
Address             : http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
ReferenceParameters : ReferenceParameters

OK



PS C:\work>

Windows側の準備は以上です。

こんどは、JobScheduler をインストールしたマシン(CentOS6)に、Ansible をインストールします。
[root@centos6 ansible]# yum install ansible python-pip
[root@centos6 ansible]# pip install pywinrm

イベントリファイル(hosts)を作成してCentOS6からWindows への疎通確認をします。
[root@centos6 ansible]# cat hosts
[windows]
10.1.0.114

[windows:vars]
ansible_ssh_user=administrator
ansible_ssh_pass=p@ssw0rd
ansible_ssh_port=5986
ansible_connection=winrm
[root@centos6 ansible]# ansible windows -i hosts -m win_ping
10.1.0.114 | success >> {
    "changed": false,
    "ping": "pong"
}

実行結果に success と表示されたら Ansible でWindowsを操作可能です。


テスト用バッチ処理の準備


テスト用に、Windows側に以下のような内容でバッチファイル(c:\work\test.bat)を用意します。
hostname
exit 0

CentOS6から Ansible でリモート実行して動作確認します。
[root@centos6 ansible]# ansible windows -i hosts -m raw -a "c:\work\test.bat"
10.1.0.114 | success | rc=0 >>

C:\Users\Administrator>hostname
WIN-F7P411FIOMA

C:\Users\Administrator>exit 0


[root@centos6 ansible]# echo $?
0


ジョブの登録と実行


JobScheduler 用にスタンドアローン・ジョブを作成します。
<job>
    <script  language="shell">
        <![CDATA[
ansible windows -i /home/jobs/ansible/hosts -m raw -a "c:\work\test.bat"
st=$?
echo "status=$st"
exit $st
        ]]>
    </script>
    <run_time />
</job>

即時実行するとジョブが正常終了し、ログが以下のように表示されます。
2016-02-27 15:09:57.854+0900 [info]   SCHEDULER-918  state=starting (at=2016-02-27 15:09:57.841+0900)
2016-02-27 15:09:57.854+0900 [info]   SCHEDULER-987  Starting process: '/bin/sh' '-c' '"/tmp/jobs/sos.MmXDIF"'
2016-02-27 15:09:58.444+0900 [info]   10.1.0.114 | success | rc=0 >>
2016-02-27 15:09:58.444+0900 [info]    
2016-02-27 15:09:58.444+0900 [info]   C:\Users\Administrator>hostname 
2016-02-27 15:09:58.444+0900 [info]   WIN-F7P411FIOMA 
2016-02-27 15:09:58.444+0900 [info]    
2016-02-27 15:09:58.444+0900 [info]   C:\Users\Administrator>exit 0  
2016-02-27 15:09:58.444+0900 [info]   
2016-02-27 15:09:58.444+0900 [info]   
2016-02-27 15:09:58.444+0900 [info]   status=0
2016-02-27 15:09:58.445+0900 [info]   SCHEDULER-915  Process event

つぎに、test.bat の終了ステータス を 1 にして 即時実行するとジョブが異常終了しログが以下のように表示されます。
2016-02-27 15:12:19.557+0900 [info]   SCHEDULER-918  state=starting (at=2016-02-27 15:12:19.544+0900)
2016-02-27 15:12:19.558+0900 [info]   SCHEDULER-987  Starting process: '/bin/sh' '-c' '"/tmp/jobs/sos.Bt5Hy7"'
2016-02-27 15:12:20.110+0900 [info]   10.1.0.114 | FAILED | rc=1 >>
2016-02-27 15:12:20.110+0900 [info]    
2016-02-27 15:12:20.110+0900 [info]   C:\Users\Administrator>hostname 
2016-02-27 15:12:20.110+0900 [info]   WIN-F7P411FIOMA 
2016-02-27 15:12:20.110+0900 [info]    
2016-02-27 15:12:20.110+0900 [info]   C:\Users\Administrator>exit 1  
2016-02-27 15:12:20.110+0900 [info]   
2016-02-27 15:12:20.110+0900 [info]   
2016-02-27 15:12:20.110+0900 [info]   status=2
2016-02-27 15:12:20.111+0900 [info]   SCHEDULER-915  Process event
2016-02-27 15:12:20.112+0900 [ERROR]  SCHEDULER-280  Process terminated with exit code 2 (0x2)
2016-02-27 15:12:20.546+0900 [WARN]   SCHEDULER-320  Could not send mail

なんとかなりそう。。





2016年2月21日日曜日

[CentOS6][Serverspec] 配列に定義した値で繰り返しテストする




たとえば、ユーザのテストをする場合、ユーザ数だけテストコードを書くのは面倒なので、ユーザを配列で定義して、同じテストコードをループ処理化します。

以下の例は、Ruby の書式でテストコードにユーザを定義しています。
テストコードはループで処理するようにします。

users = [{:nm => 'user01', :id => 501 },
         {:nm => 'user02', :id => 502 }]

users.each do |u|
  describe user( "#{u[:nm]}" ) do
    it { should exist }
    it { should have_uid "#{u[:id]}" }
  end
end


以下の例では、YAMLでユーザを定義しています。Serverspec でYAML を使用する方法は、以前の記事を参照にしてください。

YAML は以下のように定義します。
:users:
  - { :nm: "user01", :id: 501 }
  - { :nm: "user02", :id: 502 }

YAMLで定義した変数を使用するテストコードは以下のとおり
users = property[:users]
users.each do |u|
  describe user( "#{u[:nm]}" ) do
    it { should exist }
    it { should have_uid "#{u[:id]}" }
  end
end


上記とは異なり、単純な配列を使いたい場合は、以下のような書き方になります。
cmds={
  'cmd1' => "ret1",
  'cmd2' => "ret2",
  'cmd3' => "ret3"
}

cmds.each do |cmd, value|
  describe command("#{cmd}") do
    its(:stdout) { should match /#{value}/ }
  end
end



2016年2月20日土曜日

[CentOS6] 多段のsshポート転送を使って踏み台経由でWEBサーバにアクセスする


ファイヤーウォールなどに阻まれて、直接、WEBサイトにアクセスできない場合でも、SSH接続が可能であれば、SSHポート転送を利用して、ファイヤーウォール越しにブラウザでWEBサイトにアクセスできる場合があります。 

SSHポート転送は、ローカルコンピュータの特定のポートに送られてきたデータを、SSHの通信経路を用いてリモートコンピュータの特定ポートに送信する事です。

今回は、下図にような環境で、「WindowsPC」から「WEBサーバ」にアクセスしてブラウザでページを表示してみます。
  • WindowsPC: 192.168.1.2
  • 踏み台サーバ: 192.168.56.11
  • WEBサーバ: 10.0.2.5


この環境では、「WEBサーバ」は localhost からのアクセスしか許可せず、「WindowsPC」と「WEBサーバ」のサブネットを異なるものにして、「WindowsPC」から「WEBサーバ」への直接の疎通を不可能にしています。
「WindowsPC」から「WEBサーバ」にアクセスするには、「踏み台」を経由する必要があります。

通常だと、外部から「WEBサーバ」にアクセスすることは不可能ですが、SSH接続が可能だと、ポート転送を利用して、外部からブラウザでWEBページを表示できるようになります。

以下のようにSSHポート転送を繰り返して(WindowsPC ⇒ 踏み台 ⇒ WEBサーバ)、「WindowsPC」から直接、「WEBサーバ」にアクセスできるようにします。

SSH接続元 転送元のポート SSH接続先 転送先のポート
踏み台 10080 WEBサーバ 127.0.0.1:80
WindowsPC 10080 踏み台 127.0.0.1:10080


WEBサーバの準備


まず、テスト用に「WEBサーバ」を用意します。
Apacheの httpd.ocnf を以下のようにして、localhost からの接続のみ受け付けるようにします。
通常なら、外部からページを表示できません。
#
# Controls who can get stuff from this server.
#
    Order allow,deny
    Allow from localhost

</Directory>


「踏み台」から「WEBサーバ」にポート転送でアクセスする


「WindowsPC」でPuTTYを開いて「踏み台」にSSHログインします。
「踏み台」にログインしたら、以下のようにポート転送を設定して、「WEBサーバ」にSSHログインします。
[root@node01 ~]# ssh -g -L 10080:127.0.0.1:80 centos@10.0.2.5

ログインしたら、この PuTTYのターミナルを、開いたまま置いておくと、このターミナルの SSH接続を通して、ポート転送が行われます。

これで、「踏み台」の 10080 ポートが、「WEBサーバ」の 80 ポートに転送されるようになったので、「踏み台」からWEBページを見ることができます。



新しくPuTTYを開いて、「踏み台」にSSHログインし、以下のように curl コマンドでアクセスすると、「WEBサーバ」のページを表示します。
[root@node01 ~]# curl http://127.0.0.1:10080/index.html
<html>
<head>
<title>Test Page</title>
</head>
<body>
<h1>Test Page</h1>
</body>
</html>


「WindowsPC」から「踏み台」にポート転送でアクセスする


上記で「WEBサーバ」にSSHログインしたターミナルは残しておきます。

この状態で、「WindowsPC」から「踏み台」の10080ポートに接続できれば、「WindowsPC」から「WEBサーバ」にアクセスできます。
使用するURL は http://192.168.56.11:10080/ です。

しかし、今回は、「WindowsPC」から「踏み台」にアクセスできるのが SSHポート(22)だけなので、下図のように多段のSSHポート転送で「WEBサーバ」にアクセスします。



まず、PuTTY で 「踏み台」にSSHログインします。

PuTTYのメニューで[設定の変更]を選択し、[接続] > [SSH] > [トンネル] で下図の画面が表示されます。
下図のように入力して、[追加]ボタンをクリックすると、ポート転送が設定できます。
[適用]ボタンをクリックすれば、ポート転送が有効になります。



これで、「WindowsPC」から「WEBサーバ」に直接アクセスできるようになります。

ブラウザを開いて、http://127.0.0.1:10080 にアクセスすると、下図のように「WEBサーバ」のページが表示できるようになります。




同じような方法で、踏み台経由のSCPやFTPなども可能になります。








2016年2月15日月曜日

[CentOS6][Serverspec] sudo を使わずにテストケースを実行する


sudo を無効にする方法が、2つあります。

全体的に sudo を使用したくない場合などは、spec_helper.rb に設定を追加します。

# Disable sudo
set :disable_sudo, true

特定のテストケースで一時的に sudo を使用したくない場合は、以下のように設定します。

describe command('xxxxx') do
  let(:disable_sudo) { true }
  it { should return_stdout('yyyy') }
end






2016年2月14日日曜日

[CentOS6][Serverspec] ロールと変数を使い、コマンドラインでIPアドレスを指定する


Serverspec advanced Tips」を見て、以下のような使い方ができないか考えてみました。
  • テストケースを複数サーバで使いまわす。
  • 全サーバ共通の変数を yaml (spec_all.yml)で定義する。
  • サーバ個別の変数を yaml (spec_<IPアドレス>.yml)で定義する。
  • ロール単位でテストケースを作成する。
  • テスト対象のロールは、yaml で定義し、コマンドラインでファイル名を指定する。
  • コマンドラインでテスト対象のIPアドレスを指定する。
  • コマンドラインでSSHユーザ/パスワードを指定する。

ディレクトリ・ファイル構成は以下のようになります。
[user01@node01 serverspec]$ tree
.
├── Rakefile
├── roles.yml
├── spec
│   ├── 00_common
│   │   └── os_spec.rb
│   ├── 01_private
│   │   └── os_spec.rb
│   ├── 99_sample
│   │   └── sample_spec.rb
│   └── spec_helper.rb
└── vars
    ├── spec_192.168.56.11.yml
    └── spec_all.yml
  • Rakefile
    対象ロール(roles.yml)のテストケース(*_spec.rb)を実行するように定義します。
  • roles.yml
    対象ロールを定義します。ファイル名は任意です。
  • spec ディレクトリ
    この配下にロール単位のディレクトリを作成します。ロール名は任意です。
  • spec/<ロール名>ディレクトリ
    この配下にテストケースを作成します。ファイル名は *_spec.rb です。(*は任意)
  • spec_helper.rb
    対象サーバへのSSH接続や、変数の読み込みなどを行います。
  • vars ディレクトリ
    この配下に変数ファイルを定義します。全サーバ共通の変数は、"spec_all.yml" に定義します。サーバ個別の変数は、"spec_<IPアドレス>.yml" に定義します。


テストケースの実行方法は以下のとおりです。
パラメータは環境変数で渡します。
env TARGET_HOST=192.168.56.11 TARGET_USER=centos TARGET_PASSWORD=p@ssw0rd SUDO_PASSWORD=p@ssw0rd TARGET_ROLES=roles.yml rake spec:all
  • TARGET_HOST
    テスト対象のサーバのIPアドレスを指定する
  • TARGET_USER
    SSH接続に使用するユーザを指定する。このユーザで sudo が使えるようにしておくこと。
  • TARGET_PASSWORD
    SSH接続ユーザのパスワードを指定する
  • SUDO_PASSWORD
    SUDOのパスワードを指定する
  • TARGET_ROLES
    対象ロールファイル名を指定する


Rakefile は以下のとおり
require 'rake'
require 'rspec/core/rake_task'
require 'yaml'

task :spec => 'spec:all'

roles_yaml = YAML.load_file(ENV['TARGET_ROLES'])

namespace :spec do

  short_name = 'all'
  role       = roles_yaml['roles'].join(',')

  desc "Run serverspec to all"
  RSpec::Core::RakeTask.new(short_name) do |t|
    t.pattern = "spec/{#{role}}/*_spec.rb"
  end
end


spec_helper.rb は以下のとおり
require 'serverspec'
require 'net/ssh'
require 'yaml'

set :backend, :ssh

if ENV['ASK_SUDO_PASSWORD']
  begin
    require 'highline/import'
  rescue LoadError
    fail "highline is not available. Try installing it."
  end
  set :sudo_password, ask("Enter sudo password: ") { |q| q.echo = false }
else
  set :sudo_password, ENV['SUDO_PASSWORD']
end

host = ENV['TARGET_HOST']

options = Net::SSH::Config.for(host)

options[:user] =  ENV['TARGET_USER']
options[:password] =  ENV['TARGET_PASSWORD']

set :host,        options[:host_name] || host
set :ssh_options, options

# Disable sudo
# set :disable_sudo, true


# Set environment variables
# set :env, :LANG => 'C', :LC_MESSAGES => 'C'

# Set PATH
# set :path, '/sbin:/usr/local/sbin:$PATH'

# sudoersに「Defaults requiretty」が設定されている場合
set :request_pty, true

# 全体共通の値を書いたファイルをつかう。
all_vars = YAML.load_file(
                    File.expand_path("../../vars/spec_all.yml", __FILE__)
            )
# サーバ固有の値を書いたファイルがあればつかう。
host_vars = YAML.load_file(
                    File.expand_path("../../vars/spec_#{host}.yml", __FILE__)
            ) if File.exists?(File.expand_path("../../vars/spec_#{host}.yml", __FILE__))

spec_property = all_vars
spec_property[:host_vars] =  host_vars ||= {}
#puts spec_property.to_yaml
set_property spec_property


roles.yml は以下のとおり
---
roles:
 - 00_common
 - 01_private


spec_all.yml は以下のとおり
# os_basic
:os_rel: "6.7"
:os_lang: "ja_JP.UTF-8"
:os_localtime: "JST"
:os_zone: "Asia/Tokyo"


spec_192.168.56.11.yml は以下のとおり
# private
:system: R&D
:env: Develop
:role: web
:hostname: node01


00_common/os_spec.rb は以下のとおり
require 'rubygems'
require 'spec_helper'

# OS version
describe command('cat /etc/redhat-release') do
  its(:stdout) { should match /#{property[:os_rel]}/ }
end

# LANG
describe command('grep LANG /etc/sysconfig/i18n') do
  its(:stdout) { should match /#{property[:os_lang]}/ }
end

# timezone
describe command('date') do
  its(:stdout) { should match /#{property[:os_localtime]}/ }
end
describe command('grep ZONE /etc/sysconfig/clock') do
  its(:stdout) { should match /#{property[:os_zone]}/ }
end

# selinux
describe selinux do
  it { should be_disabled }
end

# firewall
describe service('iptables') do
  it { should_not be_enabled }
  it { should_not be_running }
end
describe service('ipi6tables') do
  it { should_not be_enabled }
  it { should_not be_running }
end


00_private/os_spec.rb は以下のとおり
require 'rubygems'
require 'spec_helper'

# hostname
describe file('/etc/sysconfig/network') do
  it { should be_file }
  it { should be_mode 644 }
  it { should be_owned_by 'root' }
  it { should be_grouped_into 'root' }
  it { should contain "HOSTNAME=#{property[:host_vars][:hostname]}" }
end


実行結果は以下のとおり。
[user01@node01 serverspec]$ env TARGET_HOST=192.168.56.11 TARGET_USER=centos TARGET_PASSWORD=p@ssw0rd SUDO_PASSWORD=p@ssw0rd TARGET_ROLES=roles.yml rake spec:all
/usr/bin/ruby -I/usr/lib/ruby/gems/1.8/gems/rspec-support-3.4.0/lib:/usr/lib/ruby/gems/1.8/gems/rspec-core-3.4.0/lib /usr/lib/ruby/gems/1.8/gems/rspec-core-3.4.0/exe/rspec --pattern spec/\{00_common,01_private\}/\*_spec.rb

Command "cat /etc/redhat-release"
  stdout
    should match /6.7/

Command "grep LANG /etc/sysconfig/i18n"
  stdout
    should match /ja_JP.UTF-8/

Command "date"
  stdout
    should match /JST/

Command "grep ZONE /etc/sysconfig/clock"
  stdout
    should match /Asia\/Tokyo/

SELinux
  should be disabled

Service "iptables"
  should not be enabled
  should not be running

Service "ipi6tables"
  should not be enabled
  should not be running

File "/etc/sysconfig/network"
  should be file
  should be mode 644
  should be owned by "root"
  should be grouped into "root"
  should contain "HOSTNAME=node01"

Finished in 1.51 seconds (files took 0.43561 seconds to load)
14 examples, 0 failures



これで、一応、想定通りの動きをするようになったと思います。

ただし、上記サンプルでは、"rake -T" でタスク一覧を表示することはできません。





2016年2月13日土曜日

[CentOS6][Ansible] Inventoryファイルを作らずにPlaybookを実行する


【Ansible】Inventoryファイルを利用せずにansibleコマンドを実行する」 という記事を参考にして、ansible-playbook コマンドでも同じことができるか試してみました。

インベントリファイルを作らずに ansible-palybook コマンドのコマンドラインでIPアドレスを指定して プレイブックを実行します。

テスト用のプレイブックは以下のようにしました。
hosts は all にします。

---
- hosts: all
  vars:
    myip_eth0: '{{ hostvars[inventory_hostname]["ansible_eth0"]["ipv4"]["address"] }}'
    myip_eth1: '{{ hostvars[inventory_hostname]["ansible_eth1"]["ipv4"]["address"] }}'

  tasks:
    - name: IPアドレス(eth0)
      debug: var=myip_eth0
    - name: IPアドレス(eth1)
      debug: var=myip_eth1

以下のようにして -i でIPアドレスを指定して プレイブック を実行します。
IPアドレスの最後にカンマをつけることで、ファイルではなくIPアドレスとして認識されるようです。
-u で ssh ユーザを指定し、 -k でsshユーザのパスワードを入力するようにします。

[user01@node01 ansible]$ export ANSIBLE_HOST_KEY_CHECKING=False
[user01@node01 ansible]$ ansible-playbook -i 192.168.56.11, -u user01 -k site.yml
SSH password:

PLAY ***************************************************************************

TASK [setup] *******************************************************************
ok: [192.168.56.11]

TASK [IPアドレス(eth0)] ************************************************************
ok: [192.168.56.11] => {
    "myip_eth0": "10.0.2.15"
}

TASK [IPアドレス(eth1)] ************************************************************
ok: [192.168.56.11] => {
    "myip_eth1": "192.168.56.11"
}

PLAY RECAP *********************************************************************
192.168.56.11              : ok=3    changed=0    unreachable=0    failed=0



環境変数のANSIBLE_HOST_KEY_CHECKINGにFalseを設定すると ssh の HostKeyChecking を無効にできます。

パスワードを入力したくない場合は、/etc/ansible/ansible.cfg でSSHの秘密鍵(private_key)を指定するか、ansible-playbookコマンドの "--private-key" で秘密鍵を指定します。






2016年2月10日水曜日

[CentOS6][Ansible] Playbook の変数とタスクの使用例いろいろ


環境変数でプロキシを指定して yum を使う


vars:
  proxy_env:
    http_proxy: http://192.168.1.1:8080
    https_proxy: http://192.168.1.1:8080

tasks:
  - name: epelレポジトリの追加
    yum: name=epel-release state=latest
    environment: proxy_env


変数の値をJSONで設定する


vars:
  os: {
    hostname: "node01",
    locale: "ja_JP.UTF-8",
    zone: "Asia/Tokyo",
    zoneinfo_path: "/usr/share/zoneinfo/Asia/Tokyo"
  }

tasks:
  - name: ホスト名の設定
    hostname: name="{{os.hostname}}"


ユーザを配列で設定して作成する


vars:
  #  md5-password) openssl passwd -1 password
  os_users:
    - { name: "user01",  password: "$1$ZjFvuZTg$djhcNWh2.GAWtf5TOgzTa2", uid: "2001", group: "users", home: "/home/user01", shell: "/bin/bash" }
    - { name: "user02",  password: "$1$ZjFvuZTg$djhcNWh2.GAWtf5TOgzTa2", uid: "2002", group: "users", home: "/home/user02", shell: "/bin/bash" }

tasks:
  - name: (OS) ユーザの作成
    user: >
      name={{item.name}}
      state=present
      password={{item.password}}
      uid={{item.uid}}
      group={{item.group}}
      home={{item.home}}
      shell={{item.shell}}
    with_items: os_users

ディレクトリを配列で設定して作成する


tasks:
  - name: ディレクトリ作成
    file: path={{item}} state=directory owner=root group=root mode=0755
    with_items:
      - /data1
      - /data2

あるファイルが存在したら処理をする


tasks:
  - stat: path=/etc/yum.repos.d/epel.repo
    register: epel_stat
  - name: yumパッケージのインストール
    yum: name={{item}} enablerepo=epel state=latest
    with_items:
      - pkg1
      - pkg2
    when: epel_stat.stat.exists == true

コマンドを実行する


tasks:
  - name: パーティション拡張の指示
    shell: "dracut --force --add growroot /boot/initramfs-$(uname -r).img"
    register: dracut
    ignore_errors: true
    changed_when: false

  - name: reboot!
    command: shutdown -r now


処理対象のホスト名とIPアドレスを変数に設定する


vars:
  myhost: '{{ inventory_hostname }}'
  myip: '{{ hostvars[inventory_hostname]["ansible_eth0"]["ipv4"]["address"] }}'

tasks:
  - debug: var=myhost
  - debug: var=myip





2016年2月6日土曜日

検証で使っている便利ツール1


検証環境を作るときに、よく利用するツールを紹介します。

今回は、「BluckJumboDog」 です。
メール環境の検証などで、よく使わせてもらっています。

BlackJumboDogは、Windows上で動作する軽量なパーソナルサーバです。

Web・Ftp・Proxy・DNS・DHCP・SMTP・POP3・TFTP等のサーバを軽易に構築することができます。
以下の利用制限があります。
営利を目的としない場合、本プログラムの開発に障害となるような使用をしない限り制限は有りません。自由にご利用下さい。 営利を目的とする利用の場合、個別に判断させて頂きたいと考えておりますので、事前に御連絡下さい。
(特に問題と感じない限り、承諾させて頂きます)




2016年2月5日金曜日

[CentOS7] パスワードをコマンドラインで指定してSSH接続する


sshpass を使用すると、コマンドラインでパスワードを指定して SSH接続できます。

expect を使うより簡単です。

CentOS7 には、yum で sshpass をインストールできます。 まず、epel レポジトリをインストールします。

[root@node71 ~]# yum install epel-release

sshpass は以下のようにインストールします。

[root@node71 ~]# yum install sshpass

使い方は以下のとおり。
"-p" でパスワードを指定します。
下記例では root ユーザで実行していますが、一般ユーザでも同じように実行できます。

[root@node71 ~]# sshpass -p 'password' ssh user@10.1.0.21

パスワードは、環境変数やファイルでも指定できます。

[root@node71 ~]# sshpass -h
Usage: sshpass [-f|-d|-p|-e] [-hV] command parameters
   -f filename   Take password to use from file
   -d number     Use number as file descriptor for getting password
   -p password   Provide password as argument (security unwise)
   -e            Password is passed as env-var "SSHPASS"
   With no parameters - password will be taken from stdin

   -h            Show help (this screen)
   -V            Print version information
At most one of -f, -d, -p or -e should be used





2016年2月4日木曜日

[XenServer6.5] CentOS7 で Gnomeデスクトップを使う


XenServer6.5 環境のCentOS7(最小構成)に、GNOMEデスクトップ環境をいれます。

# yum groupinstall "GNOME Desktop"

デフォルトのランレベルをGUIモードに変更します。

# systemctl set-default graphical.target

これで、再起動すればXenCenterでGNOMEデスクトップを使用できます。







2016年2月3日水曜日

[CentOS7] SHA512 で暗号化したい


SHA512の暗号化コードが欲しい場合、CentOS6 だと grub-crypt コマンドを使用してましたが、CentOS7 には grub-crypt がありません。

最小構成だと perl はインストールされませんが、 python はあるので、python で暗号化コードを作成します。

"password" という文字列を暗号化したい場合、以下のようになります。
SALT値として "salt1234" を与えて暗号化しています。

[root@node71 ~]# python -c "import crypt, getpass, pwd; print crypt.crypt('password', '\$6\$salt1234\$')"
$6$salt1234$Zr07alHmuONZlfKILiGKKULQZaBG6Qmf5smHCNH35KnciTapZ7dItwaCv5SKZ1xH9ydG59SCgkdtsTqVWGhk81


usermod コマンドでパスワードを設定する場合は、以下のようになります。

[root@node71 ~]# usermod -p '$6$salt1234$Zr07alHmuONZlfKILiGKKULQZaBG6Qmf5smHCNH35KnciTapZ7dItwaCv5SKZ1xH9ydG59SCgkdtsTqVWGhk81' user01
[root@node71 ~]# getent shadow user01
user01:$6$salt1234$Zr07alHmuONZlfKILiGKKULQZaBG6Qmf5smHCNH35KnciTapZ7dItwaCv5SKZ1xH9ydG59SCgkdtsTqVWGhk81:16833:0:99999:7:::


2016年2月2日火曜日

[CentOS6] OSユーザにグループを追加する


以下のような user01 ユーザがいます。
[root@node01 ~]# id user01
uid=501(user01) gid=501(user01) 所属グループ=501(user01)

このuser01ユーザに、"users", "wheel" グループを追加したいとします。

usermod コマンドだと以下のように実行します。
[root@node01 ~]# usermod -G users,wheel user01
[root@node01 ~]# id user01
uid=501(user01) gid=501(user01) 所属グループ=501(user01),10(wheel),100(users)

gpasswd コマンドだと以下のように実行します。
[root@node01 ~]# gpasswd -a user01 users
Adding user user01 to group users
[root@node01 ~]# gpasswd -a user01 wheel
Adding user user01 to group wheel
[root@node01 ~]# id user01
uid=501(user01) gid=501(user01) 所属グループ=501(user01),10(wheel),100(users)

user01 からグループを削除したい場合は、以下のようにします。
[root@node01 ~]# gpasswd -d user01 wheel
Removing user user01 from group wheel
[root@node01 ~]# gpasswd -d user01 users
Removing user user01 from group users
[root@node01 ~]# id user01
uid=501(user01) gid=501(user01) 所属グループ=501(user01)



2016年2月1日月曜日

[aws-cli] ELB関連で、よく使うコマンド


ELB 関連で、よく使うコマンドのメモです。


ELBの作成


以下の例ではリスナーを2つもったVPC内部用のELBを作成しています。
複数のセキュリティグループに所属するようにし、タグを設定しています。
ELB_SUBNET=subnet-xxxx
ELB_SECURITY_GROUP_ID="sg-xxxx sg-yyyy"
TAG_SYSTEM=website
TAG_ENV=Develop
elb_nm=elb01

aws elb create-load-balancer --load-balancer-name ${elb_nm} \
    --listeners "Protocol=HTTP,LoadBalancerPort=80,InstanceProtocol=HTTP,InstancePort=80" \
                 "Protocol=TCP,LoadBalancerPort=8000,InstanceProtocol=TCP,InstancePort=8000" \
    --subnets ${ELB_SUBNET} \
    --scheme internal \
    --security-groups ${ELB_SECURITY_GROUP_ID} \
    --tags "Key=Name,Value=${elb_nm}" "Key=System,Value=${TAG_SYSTEM}" "Key=Env,Value=${TAG_ENV}" \
    --output table


ヘルスチェックの設定


以下の例では、ELB名を指定して、ヘルスチェックを設定しています。
aws elb configure-health-check \
    --load-balancer-name ${elb_nm} \
    --health-check Target=HTTP:80/app/health,Interval=15,UnhealthyThreshold=3,HealthyThreshold=2,Timeout=5 \
    --output table


ELB属性の設定


以下の例では、ELB名を指定して、ELBのアクセスログなど各種属性を設定しています。
なお、ELBのアクセスログをS3に出力するには、S3バケットポリシーを設定する必要があります。
S3_BUCKET=example-blue21
S3_BUCKET_ELBLOG="log/website"

aws elb modify-load-balancer-attributes \
    --load-balancer-name ${elb_nm} \
    --load-balancer-attributes "{\"CrossZoneLoadBalancing\":{\"Enabled\":true},\"AccessLog\":{\"Enabled\":true,\"S3BucketName\":\"${S3_BUCKET}\",\"EmitInterval\":5,\"S3BucketPrefix\":\"${S3_BUCKET_ELBLOG}\"},\"ConnectionDraining\":{\"Enabled\":true,\"Timeout\":300},\"ConnectionSettings\":{\"IdleTimeout\":60}}" \
    --output table


ELBにEC2インスタンスを登録/削除


以下の例では、ELB名を指定して、EC2インスタンスを登録/削除しています。
# EC2インスタンスを登録 
aws elb register-instances-with-load-balancer --instance $INSTANCE_ID --load-balancer-name $elb_nm --output table
# EC2インスタンスを削除
aws elb deregister-instances-from-load-balancer --instance $INSTANCE_ID --load-balancer-name $elb_nm --output table


ELBの状態確認


以下の例では、ELB名を指定して、状態を確認しています。
aws elb describe-instance-health --load-balancer-name $elb_nm --output table


ELBの削除


以下の例では、ELB名を指定してELBを削除しています。
aws elb delete-load-balancer --load-balancer-name ${elb_nm} --output table