gitlab-ciで、VPN経由でansibleデプロイするまで(ansibleは、特に関係ないです）

# gitlab-ciで、VPN経由でansibleデプロイするまで(ansibleは、特に関係ないです）

VPN接続しないと、サーバーへssh接続することができない環境に、gitlab-ciからデプロイするための手順です。

## 今回の環境

gitlab.com -> VPN(ローカルには、192.168.0.0/22で割当られる) -> 目的のサーバー（172.26.1.45）

## 前提

- gitlab-ciのベースイメージは、最終的にansibleを実行してデプロイするので、ansibleが使えるイメージを使っています。

- ネットワークの状態やping疎通確認してます。

## gitlabユーザー用のクライアント設定ファイルの例
今回は、クライアントの証明書（cert）とクライアントの鍵(key)は、ファイルを参照させず、直接記述しました。

```
client
dev tun
proto udp
remote vpn-endpoint-hogehoge.com 443
remote-random-hostname
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
cipher AES-256-GCM
verb 3
<ca>
-----BEGIN CERTIFICATE-----
サーバーの証明書
-----END CERTIFICATE-----
</ca>

<cert>
-----BEGIN CERTIFICATE-----
クライアントの証明書
-----END CERTIFICATE-----
</cert>

<key>
-----BEGIN PRIVATE KEY-----
クライアントの鍵
-----END PRIVATE KEY-----
</key>

reneg-sec 0
```

## gitlab-ciの環境変数に追加

<img width="1087" alt="gitlab-ci-Variables.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44351/1f080edf-513e-bee6-ad8f-0a7b6dc82df4.png">

| Type | Key | Value |
|-----------------|------------------|------------------|
| File | CLIENT_OVPN | クライアント設定ファイルの内容を貼り付ける |
| Variable | SSH_PRIVATE_KEY | sshキー(pem)の内容 |

- Active Directory 認証の使用する場合

| Type | Key | Value |
|-----------------|------------------|------------------|
| Variable | VPN_U | vpnユーザー名 |
| Variable | VPN_P | vpnパスワード |

Protectedにした方が良いかと思います。

## .gitlab-ci.yml

```
# 最終的にansibleを実行してデプロイするので、ansibleが使えるイメージを使っています。
image: webdevops/ansible

stages:
  - provision

provision:
  stage: provision
  before_script:
    ##
    ## VPN接続
    ##

    # 最新のopenvpnをインストールしたいので準備（ご自分で、イメージを用意すればこのあたりは要らなくなりますね）
    - which curl || (apt-get update -y -qq && apt-get install -y -qq curl)
    - curl -s https://swupdate.openvpn.net/repos/repo-public.gpg | apt-key add
    - echo "deb http://build.openvpn.net/debian/openvpn/stable xenial main" > /etc/apt/sources.list.d/openvpn-aptrepo.list
    - which openvpn || (apt-get update -y -qq && apt-get install -y -qq openvpn) 

    # pingやifconfigで確認するために、インストール
    - which iputils-ping || (apt-get update -y -qq && apt-get install -y -qq iputils-ping)
    - which net-tools || (apt-get update -y -qq && apt-get install -y -qq net-tools)

    # openvpnのクライアント設定ファイルを作成していく
    # CLIENT_OVPNは、gitlab-ciの環境変数に登録しておきます。

    # クライアント設定ファイルをgitlab変数から設定ファイルに書き出します.
    - cat $CLIENT_OVPN > /etc/openvpn/client.conf

    # 今回は、使用しませんが、Active Directory 認証の使用する場合は、以下をコメント解除
    # vpnユーザーとパスワードをgitlab変数からパスワードファイルに追記します。
    # - cat $VPN_U > /etc/openvpn/pass.txt
    # - cat $VPN_P >> /etc/openvpn/pass.txt

    # vpn configにパスワードファイルを使用する設定を追記
    # - cat "auth-user-pass /etc/openvpn/pass.txt" >> /etc/openvpn/client.conf

    # ログファイルを使う場合は、以下をコメント解除
    # vpn configにログファイルを使用する設定を追記
    # - cat <<< "log /etc/openvpn/client.log" >> /etc/openvpn/client.conf
    # ログファイルを作っておく
    # - touch /etc/openvpn/client.log

    # VPN接続を開始
    - openvpn --config /etc/openvpn/client.conf --daemon
    # vpnが接続できるようになるまでしばらく待ってから、他の操作を行います。
    - sleep 30s

    # ログファイルを使う場合は、以下をコメント解除
    # - cat /etc/openvpn/client.log # Print the vpn log.

    # ネットワークの情報や、ping疎通
    - ifconfig
    - ping -c 1 172.26.1.45

    ##
    ## SSH接続
    ##

    # ssh-agentをインストールします。
    - 'which ssh-agent || ( apt-get update -y && apt-get install -y -qq openssh-client )'
    # 現在のコンソールでのみ有効にします。
    - eval $(ssh-agent -s)
    # SSH_PRIVATE_KEYは、gitlab-ciの環境変数に登録しておきます。
    - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
    # SSH_PRIVATE_KEYは、 ~/.ssh/keyに書き込まれています。
    # IdentityFile ~/.ssh/keyってことになります。
    - mkdir -p ~/.ssh
    - chmod 700 ~/.ssh
 
  script:
    - ansible-galaxy install -r requirements.yml --force
    - ansible-playbook -v -i hosts myPlaybook.yml

  when: manual

```

## 実行してみる(インストールの状況はカットしてます）
```
 $ which curl || (apt-get update -y -qq && apt-get install -y -qq curl)
 $ which iputils-ping || (apt-get update -y -qq && apt-get install -y -qq iputils-ping)
 $ which net-tools || (apt-get update -y -qq && apt-get install -y -qq net-tools)
 $ curl -s https://swupdate.openvpn.net/repos/repo-public.gpg | apt-key add
 OK
 $ echo "deb http://build.openvpn.net/debian/openvpn/stable xenial main" > /etc/apt/sources.list.d/openvpn-aptrepo.list
 $ which openvpn || (apt-get update -y -qq && apt-get install -y -qq openvpn)
 $ cat $CLIENT_OVPN > /etc/openvpn/client.conf
 $ openvpn --config /etc/openvpn/client.conf --daemon
 $ sleep 30s
 $ ifconfig
 eth0      Link encap:Ethernet  HWaddr XX:XX:XX:XX:XX:XX  
           inet addr:172.17.0.3  Bcast:172.17.255.255  Mask:255.255.0.0

 lo        Link encap:Local Loopback  
           inet addr:127.0.0.1  Mask:255.0.0.0

 tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
           inet addr:192.168.0.2  P-t-P:192.168.0.2  Mask:255.255.255.224

おおお！！！　tun0がVPN接続

 $ ping -c 1 172.26.1.45
 PING 172.26.1.45 (172.26.1.45) 56(84) bytes of data.
 64 bytes from 172.26.1.45: icmp_seq=1 ttl=63 time=159 ms
 --- 172.26.1.45 ping statistics ---

おおおおおおお！！！！！！　PING通った！

 $ which ssh-agent || ( apt-get update -y && apt-get install -y -qq openssh-client )
 /usr/bin/ssh-agent
 $ eval $(ssh-agent -s)
 Agent pid 1182
 $ echo "$STG_SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
 Identity added: (stdin) ((stdin))
 $ mkdir -p ~/.ssh
 $ chmod 700 ~/.ssh

ここまでで、before_scriptが終わった。

 $ ansible-galaxy install -r requirements.yml --force
 $ ansible-playbook -v -i hosts myPlaybook.yml

 [WARNING]: Not prompting as we are not in interactive mode
 PLAY [web_server] **************************************************************
 TASK [Gathering Facts] *********************************************************
 ok: [server_test01]
 TASK [geerlingguy.repo-epel : Check if EPEL repo is already configured.] *******
 ok: [server_test01] => {"changed": false, "stat": {"exists": false}}

server_test01は、172.26.1.45のことです。
やった！absible実行できた！

```

## ssh_configはこんな感じになります。

```
Host server_test01
  HostName 172.26.1.45
  User centos
  Port 22
  IdentityFile ~/.ssh/key
```

# 最後に
ざっくり、走り書きで申し訳ないです。
何かお役にたてば幸いです。