Systems ManagerのRunCommandでClamAVをインストールしてみた

## まだまだEC2を扱うことが多い
EC2は管理する範囲が広いので利用するには大変なのですが、クラウド移行の文脈ではまだまだ多く利用されているのが事実です。そこでEC2を利用することを揶揄するのではなく、また諦めるのでもなく、できる範囲で効率化をしていきたいと考えています。

## ということで、Systems Managerを利用
今回は、EC2にClamAV(アンチウイルスソフト)をインストールするという作業をSystems Managerの`Run Command`を利用してなんとか効率化していこうという試みをしてみました。

## Run Commandとは？
`Run Command`はEC2インスタンスに対して特定のコマンドを実行することができるSystems Managerの機能の1つです。
![001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415280/b9622f5e-398b-438d-0061-12203244e787.jpeg)

上の画面はコマンドを実行するための画面で、実際に実行されるコマンドは`共有リソース>ドキュメント`として登録する必要があります。

![002.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415280/c7ee5d1f-a8aa-1821-40d2-2ce7cf43a358.jpeg)

今回はこのドキュメントにClamAVをインストールしConfigファイルを修正してServiceを有効化する内容を仕込んでみました。

### 設定方法
まずはドキュメントの設定をします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415280/a492b6a3-3fbc-47fe-0193-e9ec9aa756dc.png)
コンテンツに`YAML`を指定して、その中に以下の内容をコピペします

```RunCommand.yaml

---
schemaVersion: '2.2'
description: Software Inventory Policy Document.
mainSteps:
  - action: aws:runShellScript
    name: install #ここでClamAVをインストール
    inputs:
      runCommand:
      - amazon-linux-extras install epel
      - yum install -y clamav clamav-update clamd
  - action: aws:runShellScript
    name: makelogs #ログの出力先を作成
    inputs:
      runCommand:
      - mkdir /var/log/clamav
      - cd /var/log/clamav/
      - touch clam.log
      - chmod 666 clam.log
  - action: aws:runShellScript
    name: configmodify #Configファイル(/etc/clamd.d/scan.conf)の修正
    inputs:
      runCommand:
      - cp /etc/clamd.d/scan.conf /etc/clamd.d/scan.conf.org
      - sed -i -e 's%#LogFile /var/log/clamd.scan%LogFile /var/log/clamav/clam.log%g' -e 's/#LogFileUnlock yes/LogFileUnlock yes/g' -e 's/#LogFileMaxSize 2M/LogFileMaxSize 2M/g' -e 's/#LogTime yes/LogTime yes/g' -e 's/#LogVerbose yes/LogVerbose yes/g' -e 's/#LogRotate yes/LogRotate yes/g' -e 's/#TCPSocket 3310/TCPSocket 3310/g' -e 's/#TCPAddr 127.0.0.1/TCPAddr 127.0.0.1/g' -e 's%#ExcludePath ^/proc/%ExcludePath ^/proc/%g' -e 's%#ExcludePath ^/sys/%ExcludePath ^/sys/%g' -e 's/#User clamscan/User root/g' -e '$ a OnAccessIncludePath /home/ec2-user' /etc/clamd.d/scan.conf
      - sed -i -e 's%#UpdateLogFile /var/log/freshclam.log%UpdateLogFile /var/log/freshclam.log%g' /etc/freshclam.conf
  - action: aws:runShellScript
    name: start #Serviceの開始と有効化
    inputs:
      runCommand:
      - systemctl start clamd@scan
      - systemctl enable clamd@scan
      - systemctl start clamav-clamonacc.service
      - systemctl enable clamav-clamonacc.service
      - systemctl start clamav-freshclam
      - systemctl enable clamav-freshclam
  - action: aws:runShellScript
    name: cronsetting #定期スキャンのcron設定
    inputs:
      runCommand:
      - (crontab -l; echo "40 * * * * clamdscan /home/ec2-user  -l /var/log/clamav/clam.log") | crontab -
```
以上で設定完了です。

ClamAVのConfigの修正については以下を参照しています。

- [ClamAVによるリアルタイムスキャンの設定 | 稲葉サーバーデザイン](https://inaba-serverdesign.jp/blog/20210409/clamav-realtime-scan.html)

## Run Commandの実行
ドキュメントの準備ができたのであとはRun Commandを実行するだけです。設定対象のEC2が1台であればいいですが、数台に増えてくると1台ずつOSに乗り込んでコマンドを実行するのは大変です。これがRun Commandであれば1回実行すればいいだけなので便利ですね！

![004.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415280/2349107c-c8b0-8015-9995-b7ad3f51c10a.jpeg)

今回ターゲットとなるインスタンスは手動で設定していますが、ここをタグで指定したりすればより便利です。

以下の画像が実行結果です。成功したのが分かります。
![005.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415280/33cb1959-8758-12e3-9eac-001547daf505.jpeg)

ドキュメントに登録したYAMLでnameのところにつけた名前がステップとして分かれて表示されており、ステップ毎の結果を見ることができます。エラーがあった場合は「▶Error」のところにその内容が表示されます。(今回エラーは出てないです)
![006.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415280/3dd90e04-17f9-b56e-68a7-b8113f3d4d54.jpeg)

## YAMLの書き方次第で色々できそう
今回は、ClamAVのインストールだけを`ドキュメント`として保存し実行しましたが、この前段階であるHostnameの設定や言語・時刻設定などOSを作成したら実行する基本的なこともドキュメントにしRun Commandで実行できます。以下のような使い方です。

- [Amazon Linux 2用 AWS Systems ManagerでOSの簡易設定ドキュメントを作ってみた | DevelopersIO](https://dev.classmethod.jp/articles/ssm-document-amzn2_setup/)

上記の例もそうですし、今回のClamAVインストールもsedでconfigを書き換えたりしていて、何でもできることが魅力的なのですが、一方で冪等性とかは慎重に見極めたほうがいいと思いました。

今回の場合だと何度もRun Commandを実行するとcronが複数登録されてしまっていたなんてこともありました。YAMLの書き方次第だとは思いますが、、、

とはいえ、EC2を利用する際には積極的にSystems Managerを利用して設定や運用管理をオンプレの延長のようにさせないようにやっていきたいです。