AnsibleでEPELパッケージ無効化の際に設定がまるごと上書きされる件

## 背景
Development-tools[^dev]をインストールする時だけEPELを利用するようにしたい！
という事情があり、EPELをインストールして**無効化**する処理をAnsibleで書いたときに苦戦したので執筆しました:santa_tone1:

### EPELとは
EPEL(Extra Packages for Enterprise Linux)とは、「エンタープライズ Linux 用の拡張パッケージ」です。[^epel]

ひとことで言えば、**RHELやCentOSに追加のソフトウェアパッケージを提供するリポジトリ**です。

### 今回行うこと
Ansibleを利用して以下を行います
 - EPELをインストールする
 - EPELをデフォルトでは無効化する
 - Development-toolsを入れる時だけEPELを有効にする処理
 - molecule[^molecule]を使用したロールテスト[^molecule_article]

### 環境

CentOS 7
ansible：2.9.27
molecule：3.2.4
molecule-docker：0.2.4

### EPELをインストールする
はじめに、yumを使ってEPELをインストールする処理を書きます。
```
# ロールにEPELをインストールする処理を書く
- name: epel-releaseをインストール
  ansible.builtin.yum:
    name: epel-release
    state: present
```

moleculeでEPELがインストールできるかテストします。
```
# テスト終了後にコンテナを消さないようにする
molecule test --destroy never

# テスト結果
TASK [packages : epel-releaseをインストール]
changed: [centos]
```
ステータスがchangedになっているのでEPELがインストールされました。

ここで、epelの設定ファイルを見てみます:eyes:
```
# テストコンテナにログイン
molecule login

# epelの設定ファイルを確認
[root@centos ~]# cat /etc/yum.repos.d/epel.repo
[epel]
name=Extra Packages for Enterprise Linux 7 - $basearch
#baseurl=http://download.fedoraproject.org/pub/epel/7/$basearch
metalink=https://mirrors.fedoraproject.org/metalink?repo=epel-7&arch=$basearch
failovermethod=priority
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7

[epel-debuginfo]
name=Extra Packages for Enterprise Linux 7 - $basearch - Debug
#baseurl=http://download.fedoraproject.org/pub/epel/7/$basearch/debug
metalink=https://mirrors.fedoraproject.org/metalink?repo=epel-debug-7&arch=$basearch
failovermethod=priority
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
gpgcheck=1

[epel-source]
name=Extra Packages for Enterprise Linux 7 - $basearch - Source
#baseurl=http://download.fedoraproject.org/pub/epel/7/SRPMS
metalink=https://mirrors.fedoraproject.org/metalink?repo=epel-source-7&arch=$basearch
failovermethod=priority
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
gpgcheck=1

```
EPELを無効化する設定では、上記の[epel]セクションを無効化にします。

### EPELを無効化する
続いて、yum_repositoryを使ってEPELを無効化する処理を書きます。
上記設定ファイルの内容をAnsibleで書いていきます。
ここでは、enabled: falseに設定してEPELを無効化します。
Ansibleでの記述は、name: epelとenabled: falseだけを設定すれば無効化されると思っていたので時間がかかりました。(もちろんエラーになりました。)
```
- name: EPELを無効化する
  ansible.builtin.yum_repository:
    name: epel
    description: Extra Packages for Enterprise Linux 7 - $basearch
    baseurl: http://download.fedoraproject.org/pub/epel/7/$basearch
    metalink: https://mirrors.fedoraproject.org/metalink?repo=epel-7&arch=$basearch
    failovermethod: priority
    gpgcheck: true
    gpgkey: file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
    enabled: false
```
moleculeでEPELが無効化できるかテストします。
```
# テスト終了後にコンテナを消さないようにする
molecule test --destroy never

# テスト結果
TASK [packages : リポジトリを無効化する] 
changed: [centos]
```
無事できました！コンテナ内にログインして設定ファイルを確認します。
```
# テストコンテナにログイン
molecule login

# epelの設定ファイルを確認
[root@centos yum.repos.d]# cat epel.repo 
[epel-debuginfo]
name = Extra Packages for Enterprise Linux 7 - $basearch - Debug
metalink = https://mirrors.fedoraproject.org/metalink?repo=epel-debug-7&arch=$basearch
failovermethod = priority
enabled = 0
gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
gpgcheck = 1

[epel-source]
name = Extra Packages for Enterprise Linux 7 - $basearch - Source
metalink = https://mirrors.fedoraproject.org/metalink?repo=epel-source-7&arch=$basearch
failovermethod = priority
enabled = 0
gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
gpgcheck = 1

[epel]
baseurl = http://download.fedoraproject.org/pub/epel/7/$basearch
enabled = 0
failovermethod = priority
gpgcheck = 1
gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
metalink = https://mirrors.fedoraproject.org/metalink?repo=epel-7&arch=$basearch
name = Extra Packages for Enterprise Linux 7 - $basearch
```
enabled = 0でEPELが無効になっていることを確認できました！

あれ？EPELをインストールした時点では[epel]セクションが設定ファイルの一番上にあったのに、**一番下にきている**ことに気づきます。

無効化しただけなのに、**[epel]セクションは丸ごと書き換えられてしまいました。**
前の設定が分からなくならないよう、テキストファイルなどに保存しておく必要がありそうです:pencil2:

### Development-toolsをインストールする
最後に、Development-toolsを入れる時だけEPELを有効にする処理を書きます。
--enablerepo=epelで、Development-toolsを入れるときだけEPELを有効にしています。
setoptのモジュールがなかったので、コマンドをそのまま書いております。

```
- name: Development-toolsを入れる時だけEPELを有効にする
  ansible.builtin.shell: |
    yum groupinstall -y --enablerepo=epel "Development Tools" --setopt=group_package_types=mandatory,default,optional
  changed_when: false
```
moleculeでDevelopment-toolsがインストールできるかテストします。
```
# テスト終了後にコンテナを消さないようにする
molecule test --destroy never

# テスト結果
TASK [packages : Development-toolsを入れる時だけEPELを有効にする] 
changed: [centos]
```
ステータスがchangedになり、EPELを有効化した上でdevelopment-toolsがインストールされました。


[^dev]:https://www.redhat.com/ja/technologies/management/ansible/development-tools
[^epel]:https://fedoraproject.org/wiki/EPEL/ja#EPEL
[^molecule]:https://ansible.readthedocs.io/projects/molecule/
[^molecule_article]:Ansible Molecule概要：https://qiita.com/satken2/items/d631ee5820597609a467