CentOS6へAnsibleを流そうとした時にPython2.6起因なHTTPS関連のエラーが出ちゃうのをSCLを上手く使って何とかする

タイトルが…長い…

# 概要
近頃CentOS6系でHTTPSな通信を行おうと思うと辛い(当社比)

HTTPSでリクエストした時にTLS1.2に対応していないクライアントをお断りしてくるページが増えているので、そういったところからデータを取ってこようとするとエラーになったりするわけでして。あと証明書エラーもめんどくさい。
こんな感じで詰まっている人たちは恐らくそれなりに居ると思っていて、 `nss` を上げたり `openssl` を上げたり試行錯誤して対応しているんじゃないかと想像。 `yum` で `epel` から取ってこようとしただけでエラーが出ることも有るっぽく地獄ですね。

Ansibleでもやっぱり詰まる。
`get_url` なんかはリモート上のPythonで実行されているようで、PythonがTLS1.2をしゃべれないと死ぬ。証明書の問題も結局有る。CentOS6の標準なPythonは2.6なので辛い。

## エラー例

例えば下記みたいなAnsibleを走らせようとしたら…

```yaml
- name: Download NASM
  get_url:
    url: https://www.nasm.us/pub/nasm/releasebuilds/2.13.03/nasm-2.13.03.tar.bz2
    dest: ~/ffmpeg_sources
```

こんなエラーが出てしまうわけでして辛い。

```
fatal: [localhost]: FAILED! => {"changed": false, "msg": "Failed to validate the SSL certificate for www.nasm.us:443. Make sure your managed systems have a valid CA certificate installed. If the website serving the url uses SNI you need python >= 2.7.9 on your managed machine  (the python executable used (/usr/bin/python2.6) is version: 2.6.6 (r266:84292, Jun 20 2019, 14:14:55) [GCC 4.4.7 20120313 (Red Hat 4.4.7-23)]) or you can install the `urllib3`, `pyOpenSSL`, `ndg-httpsclient`, and `pyasn1` python modules to perform SNI verification in python >= 2.6. You can use validate_certs=False if you do not need to confirm the servers identity but this is unsafe and not recommended. Paths checked for this platform: /etc/ssl/certs, /etc/pki/ca-trust/extracted/pem, /etc/pki/tls/certs, /usr/share/ca-certificates/cacert.org, /etc/ansible. The exception msg was: hostname 'www.nasm.us' doesn't match either of 'www.zytor.com', 'zytor.com'."}
```

## ということで

そんなこんなでAnsibleで `get_url` とかができなくて辛い思いをしたのでそれを解決した時のメモ。


# 戦略
`yum` もPythonで動いているわけで、できれば標準でインストールされたPythonのバージョンは上げたくない。
ってことで以下みたいな方法で対応した。

1. SCLでPython2.7をインストール
2. 環境変数諸々を変更して以後のタスクを実行

リモート上で利用されているPythonを変更するには `ansible_python_interpreter` 変数を書き換えれば良いらしい。
`--extra-vars` で `ansbile-playbook` コマンドから直接設定するのでも良いし、inventoryで設定したりPlaybook内の `set_fact` で設定しても良い。

ただ、これを設定するだけでは各種環境変数等々が不足して動かない可能性があることを気をつけたい。適宜 `environment` で良い感じに環境変数を設定したほうが良さげ。


# こんなAnsibleを書いた
例えば `install.yml` の中身をPython2.7で実行したい場合…

```yaml
- name: If CentOS 6
  block:
    - name: Install Python2.7
      yum: name={{ item }}
      with_items:
        - centos-release-scl-rh
        - python27
    - set_fact:
        custum_env:
          PATH: "/opt/rh/python27/root/usr/bin:{{ ansible_env.PATH }}"
          LD_LIBRARY_PATH: "/opt/rh/python27/root/usr/lib64"
          MANPATH: "/opt/rh/python27/root/usr/share/man"
          XDG_DATA_DIRS: "/opt/rh/python27/root/usr/share"
          PKG_CONFIG_PATH: "/opt/rh/python27/root/usr/lib64/pkgconfig"      
        ansible_python_interpreter: "/opt/rh/python27/root/usr/bin/python"
  when:
   - ansible_distribution == "CentOS"
   - ansible_distribution_major_version == "6"

- name: Setup Tools Install
  include: install.yml
  environment: "{{ custum_env }}"

- set_fact:
    ansible_python_interpreter: "python"
```

恐らく `set_fact` で定義している `LD_LIBRARY_PATH` とかは、真面目にやるなら固定値ではなく `ansible_env.LD_LIBRARY_PATH` とかでデータを抜き出してこねくり回した方が良いとは思う。
めんどくさいからあんまりちゃんとやってないけど。

あと最後に `ansible_python_interpreter: "python"` をやることでそれ以降の処理に影響が出ないようにしている(例えば `yum` を叩く時はPythonは2.6に戻したほうが無難)
場合によっては `witch` とかでいい感じに `python` のパスを予め取得しておいたほうが良いのかもしれない。

ちなみにSSLなエラーという文脈でいうと、`git`等の`nss`を上げればいい感じに動きそうなやつは`nss`を上げるだけで幸せになれそう。

# 総評
CentOS8が出た昨今、CentOS6とは早々におさらばしたほうが良い気がするし個人的にはUbuntuを使いたい(ぼそっ