ubuntu で Ansible を使う

1. 構成

server ---> client
役割 IP OS ホスト名
server 10.0.0.204 ubuntu 18.04 develop01
client 10.0.1.217 ubuntu 16.04 develop02

2. Ansibleの導入

インストール

ubuntu@develop01:~$ sudo apt-get update
ubuntu@develop01:~$ sudo apt-get install software-properties-common
ubuntu@develop01:~$ sudo apt-add-repository --yes --update ppa:ansible/ansible
ubuntu@develop01:~$ sudo apt-get install ansible

バージョン確認

$ ansible --version

ansible 2.7.5
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/home/ubuntu/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/dist-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.15rc1 (default, Nov 12 2018, 14:31:15) [GCC 7.3.0]

3. 秘密鍵、公開鍵の作成

ubuntu@develop01:~$ mkdir .ssh
ubuntu@develop01:~$ cd .ssh
ubuntu@develop01:~/.ssh$ ssh-keygen -t rsa -b 4096 -C "your-email@example.com"
Generating public/private rsa key pair.
Enter file in which to save the key (/home/ubuntu/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/ubuntu/.ssh/id_rsa.
Your public key has been saved in /home/ubuntu/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:fMv/Wvlb/igct568ePTx4HeyMkANomdxEvA3xqqCQ7Q your-email@example.com
The key's randomart image is:
+---[RSA 4096]----+
|      ....       |
|       .+.o      |
|  .    ..==o     |
| . .  ..o+...    |
|  E    oS..      |
| . .   . o... +o |
|  o . .   oo =o++|
|   . .     .=+==*|
|            +OO*B|
+----[SHA256]-----+
ubuntu@develop01:~/.ssh$

作成した秘密鍵、公開鍵を確認。

ubuntu@develop01:~/.ssh$ ll
合計 16
drwxrwxr-x 2 ubuntu ubuntu 4096 1214 15:19 ./
drwxr-xr-x 3 ubuntu ubuntu 4096 1214 15:18 ../
-rw------- 1 ubuntu ubuntu 3326 1214 15:19 id_rsa
-rw-r--r-- 1 ubuntu ubuntu  748 1214 15:19 id_rsa.pub
ubuntu@develop01:~/.ssh$

ansible の playbook を実行するとデフォルトでrootに対してSSHを行う。 今回はrootに対するSSH接続を許可する。

server で作成した公開鍵を client の~/.ssh/authorized_keysに追記。

/etc/ssh/sshd_configに以下を設定。

PermitRootLogin prohibit-password

playbookの実行を許可するホストの管理を行う。

/etc/ansible/hostsの末尾に接続先の情報を追記。

# This is the default ansible 'hosts' file.
#
# It should live in /etc/ansible/hosts
#
#   - Comments begin with the '#' character
#   - Blank lines are ignored
#   - Groups of hosts are delimited by [header] elements
#   - You can enter hostnames or ip addresses
#   - A hostname/ip can be a member of multiple groups

# Ex 1: Ungrouped hosts, specify before any group headers.

## green.example.com
## blue.example.com
## 192.168.100.1
## 192.168.100.10

# Ex 2: A collection of hosts belonging to the 'webservers' group

## [webservers]
## alpha.example.org
## beta.example.org
## 192.168.1.100
## 192.168.1.110

# If you have multiple hosts following a pattern you can specify
# them like this:

## www[001:006].example.com

# Ex 3: A collection of database servers in the 'dbservers' group

## [dbservers]
##
## db01.intranet.mydomain.net
## db02.intranet.mydomain.net
## 10.25.1.56
## 10.25.1.57

# Here's another example of host ranges, this time there are no
# leading 0s:

## db-[99:101]-node.example.com

[client]
10.0.1.217

Ansibleで client のタイムゾーンと言語設定を変更する。 以下のファイルを用意。

/etc/ansible/common.yml

---
- hosts: all
  become: yes
  roles:
    - system
    - lang

/etc/ansible/roles/lang/tasks/main.yml

 name: install language-pack-ja
  apt:
    name: language-pack-ja
    update_cache: yes
- name: create locale ja_JP.UTF-8
  locale_gen:
    name: ja_JP.UTF-8
- name: change locale
  command: update-locale LANG=ja_JP.UTF-8

/etc/ansible/roles/system/tasks/main.yml

- name: set timezone to Asia/Tokyo
  timezone:
    name: Asia/Tokyo

まずは--checkを付与しドライランする。

ubuntu@develop01:/etc/ansible$ ansible-playbook -i hosts common.yml --check

PLAY [all] *************************************************************************************************

TASK [Gathering Facts] *************************************************************************************
Enter passphrase for key '/home/ubuntu/.ssh/id_rsa':
ok: [10.0.1.217]

TASK [system : set timezone to Asia/Tokyo] *****************************************************************
changed: [10.0.1.217]

TASK [lang : install language-pack-ja] *********************************************************************
changed: [10.0.1.217]

TASK [lang : create locale ja_JP.UTF-8] ********************************************************************
changed: [10.0.1.217]

TASK [lang : change locale] ********************************************************************************
skipping: [10.0.1.217]

PLAY RECAP *************************************************************************************************
10.0.1.217                 : ok=4    changed=3    unreachable=0    failed=0

ubuntu@develop01:/etc/ansible$
  • -i: ホストリストのパスを指定(デフォルトは /etc/anonymous/hosts)
  • --check: ドライラン実行

client の状態

root@develop02:~/.ssh# loclae
No command 'loclae' found, did you mean:
 Command 'locale' from package 'libc-bin' (main)
loclae: command not found
root@develop02:~/.ssh# locale
LANG=en_US.UTF-8
LANGUAGE=
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
root@develop02:~/.ssh#
root@develop02:~/.ssh#
root@develop02:~/.ssh# echo $TIMEZONE

root@develop02:~/.ssh#
root@develop02:~/.ssh#
root@develop02:~/.ssh# timedatectl
      Local time: Mon 2018-12-17 05:03:53 UTC
  Universal time: Mon 2018-12-17 05:03:53 UTC
        RTC time: Mon 2018-12-17 05:03:53
       Time zone: Etc/UTC (UTC, +0000)
 Network time on: yes
NTP synchronized: yes
 RTC in local TZ: no
root@develop02:~/.ssh#

変更実行

$ ansible-playbook -i hosts common.yml

再ログイン後に設定確認

ubuntu@develop01:~$ locale
LANG=ja_JP.utf8
LANGUAGE=
LC_CTYPE="ja_JP.utf8"
LC_NUMERIC="ja_JP.utf8"
LC_TIME="ja_JP.utf8"
LC_COLLATE="ja_JP.utf8"
LC_MONETARY="ja_JP.utf8"
LC_MESSAGES="ja_JP.utf8"
LC_PAPER="ja_JP.utf8"
LC_NAME="ja_JP.utf8"
LC_ADDRESS="ja_JP.utf8"
LC_TELEPHONE="ja_JP.utf8"
LC_MEASUREMENT="ja_JP.utf8"
LC_IDENTIFICATION="ja_JP.utf8"
LC_ALL=
ubuntu@develop01:~$
ubuntu@develop01:~$ timedatactl
      Local time: Mon 2018-12-17 14:06:21 JST
  Universal time: Mon 2018-12-17 05:06:21 UTC
        RTC time: Mon 2018-12-17 05:06:21
       Time zone: Asia/Tokyo (JST, +0900)
 Network time on: yes
NTP synchronized: yes
 RTC in local TZ: no
ubuntu@develop01:~$

変更の反映を確認。

ユーザansibleを作成してplaybook commandを実行するといくつかエラーが出たので、対処と併せて記録。

"module_stdout": "sudo: unable to resolve host" 接続先サーバの /etc/hosts にホスト名を設定。

"module_stdout": "sudo: a password is required\r\n"

usernameansible_sudo_pass を指定する

$ ansible-playbook -i hosts common.yml --user=username --extra-vars "ansible_sudo_pass=yourpassword" --check

ヤマハRTX830 の設定

既存のルータをヤマハRTX830と置き換えることにした。

設定はWeb GUIとコマンドで行う方法がある。 Web GUIでは設定できないパラメータ(DHCPの割当予約)があるためコマンドによる設定を行う。

1. telnetで接続

Teratarmを使用。192.168.100.1にtelnet接続する。

RTX830 Rev.15.02.01 (Thu Jun 22 16:17:56 2017)
Copyright (c) 1994-2017 Yamaha Corporation. All Rights Reserved.
To display the software copyright statement, use 'show copyright' command.
AA:BB:CC:DD:EE:FF, AA:BB:CC:DD:EE:FF
Memory 256Mbytes, 2LAN
> 

2. ユーザー変更

以下のコマンドを実行し、管理ユーザにスイッチする。

administrator

> 
> adadministrator 
Password: 
# 

3. LANポート1のIPアドレス変更

既存のルータとRTX830を置き換えるにあたってデフォルトゲートウェイのアドレスを合わせたいため、以下のコマンドを実行しルータのIPアドレスを変更する。

ip lan1 address 192.168.10.1/24

> 
> ip lan1 address 192.168.10.1/24

実行するとルータのIPアドレスが変更され、telnet通信が切断される。 前回のセッションがタイムアウトするまでしばらく時間を置いてから192.168.10.1に再度telnetする。

4. DHCPの設定

DHCPの割当範囲を100から開始させて、予約 & 空きはいつでも使える状態にしておきたかったが、設定がよくわからなかった。

今回は以下のように設定した。

範囲 用途
192.168.10.1-192.168.10.99 予約 & 空き
192.168.10.100-192.168.10.199 クライアント割り当て

administratorでログインした状態で以下を実行する。

dhcp service server
dhcp server rfc2131 compliant except remain-silent
dhcp scope 1 192.168.10.1-192.168.10.199/24 except 192.168.10.8-192.168.10.99

dhcp scope lease type 1 bind-priority
dhcp scope bind 1 192.168.10.2 ethernet AA:BB:CC:DD:EE:FF
dhcp scope bind 1 192.168.10.3 ethernet AA:BB:CC:DD:EE:FF

設定を保存する。

save

余談

公式サイトの手順に沿ってbind-onlyを設定したらDHCPでアドレスが割り当てできなくて少し考えた。

参考 : DHCP認証機能

Salesforce Connectの設定 (WCF Data Services 4.5)

Salesforce Connectとは

Salesforceから外部データに対してリアルタイムでアクセスできる機能。 データ自体をSalesforceに蓄えることなく外部オブジェクトとして操作することができる。

参考 : Salesforce Connect の概要

環境

AWS上に以下の環境を構築。

  • Webサーバ

    • WindowsServer 2008
    • IIS7.5
  • DBサーバ

データベースの準備

テーブル作成

Keyを設定した簡単なテーブルを用意。

ユーザ作成

適当なユーザを作成。

参考 : データベースのユーザーとデータベースへのログインユーザーの作成 (SQL Server Tips)

ログイン許可

  • SQL Server を右クリック > プロパティ > セキュリティ > 認証をSQL Serverも含めるモードに設定
  • ログインするユーザのデータベース接続権限を許可に設定

Webサーバの準備

IIS7.5 設定

「機能の追加」でIISを追加。 regeditを使い、今回使用するAMIに.NetFramework4.5がインストールされていることを確認する。

参考 : 方法: インストールされている .NET Framework バージョンを確認する | Microsoft Docs

WCF HTTPアクティブ化

「機能の追加」で .Net Framework 3.5.1 > WCFアクティブ化 > HTTPアクティブ化 と 非HTTPアクティブ化 を追加。

IISの機能追加後アプリケーションプールのバージョンに.Net Framework v4.0を追加する。コマンドプロンプトで以下を実行する。

C:\Users\Administrator> cd C:\Windows\Microsoft.NET\Framework\v4.0.30319   

C:\Windows\Microsoft.NET\Framework\v4.0.30319> aspnet_regiis -i

参考 : VMware Mirage 5.3 Documentation Center

アプリケーションプールの変更

アプリケーションプールが2.0になっているため、4.0に変更する。

IISマネージャー > サイト(Default Web Site等) を選択 > 右ペインの 詳細設定 > アプリケーションプール(統合) を選択して変更。

ハンドラーマッピングの設定変更

以下ハンドラーの動詞にPUTDELETEを追加する。

  • ExtensionlessUrlHandler-Integrated-4.0
  • ExtensionlessUrlHandler-ISAPI-4.0_32bit
  • ExtensionlessUrlHandler-ISAPI-4.0_64bit

f:id:dafukui:20181226110413p:plain

認証の設定変更

IIS認証を確認すると匿名認証が有効になっており匿名ユーザIDがIUSRとなっている。この箇所をアプリケーション プールIDに設定。

WCF Data Services の作成

Visual Studio 2015を使って作成した。

※2017はWCF Data Servicesのテンプレートを使用するために追加の対応が必要となる

WCF data service template missing in VS2017 - Developer Community

ADO.NETで気を付けるところ

Entity Framework 5.0 を選択しないとエラーになった。

c# - VerificationException with WCF Data Services - Stack Overflow

変更箇所

    public class TestWcfDataService : DataService< /* TODO: put your data source class name here */ >
            // config.SetEntitySetAccessRule("MyEntityset", EntitySetRights.AllRead);

変更後

//------------------------------------------------------------------------------
// <copyright file="WebDataService.svc.cs" company="Microsoft">
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Data.Services;
using System.Data.Services.Common;
using System.Linq;
using System.ServiceModel.Web;
using System.Web;

namespace PetSuppliesService
{
    public class PetSuppliesData : DataService<YourEntities>
    {
        // This method is called only once to initialize service-wide policies.
        public static void InitializeService(DataServiceConfiguration config)
        {
            // TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.
            // Examples:
            config.SetEntitySetAccessRule("*", EntitySetRights.All);
            // config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All);
            config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
        }
    }
}

ビルドしてローカルに発行する。 出力されたすべてのファイルをIISにアップロードして .svc ファイルにアクセスできるか確認。

Salesforceの設定

Trailheadの単元の通りに設定すれば問題なし。

Salesforce Connect | Salesforce Trailhead

結果と残課題

外部データを外部オブジェクトとして認識できた。

また、外部オブジェクトの参照、作成、更新もできることを確認したが、削除が権限不足によりできなかった。 RESTの動きとして、GETPOSTはできるが、PUTDELETEができない状態。 できない理由は401 - Unauthorized: Access is denied due to invalid credentials.

余談

Visual StudioをローカルPCにインストールして作成を実施。 その際、ADO.NETクラス作成時に接続するDBはAWSのパブリックIPアドレスを指定し、DBとの通信ができることを確認した。 そのままAWS上のIISに発行したことで、IISからDBへの通信はパブリックIPアドレスをターゲットにした通信となるが、Security Groupにでは外部からの接続を許可していなかったため、DBとの通信が確率できずエラーとなっていた。 クラス作成後に.edmxファイルの中のDBのアドレスをPrivate IPに指定しなおしたところ接続できるようになった。