2021年にもなって CentOS6 な EC2 インスタンスから CloudWatch Logs する

# 時は2021年、春。
参考 : [実行中の EC2 Linux インスタンスに CloudWatch Logs エージェントをインストールして設定する](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/QuickStartEC2Instance.html)

すでにオワコン化している CentOS 6 ですが、いまだ現役稼働している環境も多くあるのではなかろうか。
自分が管理する８年目(！)のプロジェクトも、そのひとつ。
フレームワークの都合上、OS も言語も更新できないWebサービスなんだけど、
管理は可能な限りモダンにしていきたいという。
(フレームワークを更新しろよ、というのは予算的にアレなのです)

そんなわけで、CentOS 6 な環境で apache のログを CloudWatch に流したいというケースが発生して、いざやってみたらいろいろとハマってしまったので、手順を残しておくことにする。

root 作業大好きマンなので、そのへんは各自読み替え希望。


# yum update できるようにする
参考 : [yumがupdateできない件（CentOS6）](https://node4u.info/2021/01/23/yum%E3%81%8Cupdate%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84%E4%BB%B6%EF%BC%88centos6%EF%BC%89/)

CentOS 6 は 2020/11/30 をもってサポートを終了しているので、更新用の yum リポジトリが使用できなくなっている。
そのため、過去バージョン用のリポジトリ公開場所である [CentOS Vault](https://vault.centos.org/) を利用すべく、 /etc/yum.repos.d/ 配下のリポジトリ設定ファイルをいじって、更新可能な状態にしておく必要がある。
ただし、この対応もいつまで有効か・・・？ は未知数。
具体的には、CentOS-Base.repo, CentOS-SCLo-scl-rh.repo, CentOS-SCLo-scl.repo の `baseurl` を Vault のものに書き換える感じ。

## CentOS-Base.repo
ビフォー

```/etc/yum.repos.d/CentOS-Base.repo
[base]
name = none
baseurl = http://mirror.rightscale.com/centos/6/os/x86_64/archive/latest/
  http://ec2-us-east-mirror.rightscale.com/centos/6/os/x86_64/archive/latest/
  http://ec2-us-west-mirror.rightscale.com/centos/6/os/x86_64/archive/latest/
failovermethod=priority
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6

...省略...

[extras]
name = none
baseurl = http://mirror.rightscale.com/centos/6/extras/x86_64/archive/latest/
  http://ec2-us-east-mirror.rightscale.com/centos/6/extras/x86_64/archive/latest/
  http://ec2-us-west-mirror.rightscale.com/centos/6/extras/x86_64/archive/latest/
failovermethod=priority
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6

[updates]
name = none
baseurl = http://mirror.rightscale.com/centos/6/updates/x86_64/archive/latest/
  http://ec2-us-east-mirror.rightscale.com/centos/6/updates/x86_64/archive/latest/
  http://ec2-us-west-mirror.rightscale.com/centos/6/updates/x86_64/archive/latest/
failovermethod=priority
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
```
↓
アフター

```/etc/yum.repos.d/CentOS-Base.repo
[base]
name = none
baseurl=http://vault.centos.org/centos/$releasever/os/$basearch/
# baseurl = http://mirror.rightscale.com/centos/6/os/x86_64/archive/latest/
#   http://ec2-us-east-mirror.rightscale.com/centos/6/os/x86_64/archive/latest/
#   http://ec2-us-west-mirror.rightscale.com/centos/6/os/x86_64/archive/latest/
failovermethod=priority
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6

...省略...

[extras]
name = none
baseurl=http://vault.centos.org/centos/$releasever/extras/$basearch/
# baseurl = http://mirror.rightscale.com/centos/6/extras/x86_64/archive/latest/
#   http://ec2-us-east-mirror.rightscale.com/centos/6/extras/x86_64/archive/latest/
#   http://ec2-us-west-mirror.rightscale.com/centos/6/extras/x86_64/archive/latest/
failovermethod=priority
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6

[updates]
name = none
baseurl=http://vault.centos.org/centos/$releasever/updates/$basearch/
# baseurl = http://mirror.rightscale.com/centos/6/updates/x86_64/archive/latest/
#   http://ec2-us-east-mirror.rightscale.com/centos/6/updates/x86_64/archive/latest/
#   http://ec2-us-west-mirror.rightscale.com/centos/6/updates/x86_64/archive/latest/
failovermethod=priority
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
```

## CentOS-SCLo-scl-rh.repo
ビフォー

```/etc/yum.repos.d/CentOS-SCLo-scl-rh.repo
[centos-sclo-rh]
name=CentOS-6 - SCLo rh
#baseurl=http://mirror.centos.org/centos/6/sclo/$basearch/rh/
mirrorlist=http://mirrorlist.centos.org?arch=$basearch&release=6&repo=sclo-rh
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-SCLo
```

↓
アフター

```/etc/yum.repos.d/CentOS-SCLo-scl-rh.repo
[centos-sclo-rh]
name=CentOS-6 - SCLo rh
baseurl=http://vault.centos.org/centos/6/sclo/$basearch/rh/
#baseurl=http://mirror.centos.org/centos/6/sclo/$basearch/rh/
mirrorlist=http://mirrorlist.centos.org?arch=$basearch&release=6&repo=sclo-rh
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-SCLo
```

## CentOS-SCLo-scl.repo
ビフォー

```/etc/yum.repos.d/CentOS-SCLo-scl.repo
[centos-sclo-sclo]
name=CentOS-6 - SCLo sclo
# baseurl=http://mirror.centos.org/centos/6/sclo/$basearch/sclo/
mirrorlist=http://mirrorlist.centos.org?arch=$basearch&release=6&repo=sclo-sclo
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-SCLo
```

↓
アフター

```/etc/yum.repos.d/CentOS-SCLo-scl.repo
[centos-sclo-sclo]
name=CentOS-6 - SCLo sclo
baseurl=http://vault.centos.org/centos/6/sclo/$basearch/sclo/
# baseurl=http://mirror.centos.org/centos/6/sclo/$basearch/sclo/
mirrorlist=http://mirrorlist.centos.org?arch=$basearch&release=6&repo=sclo-sclo
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-SCLo
```

必要に応じて yum update、再起動などしておく。

# Python 3.5 を使えるようにする
自分の環境では、Python が 3.6 になっていたので(たぶん Let's Encrypt まわり)、後述の awslogs 用インストールスクリプトが動かない。
このため SCL : Software Collections から追加インストールする。

```
[root@host ~]# python --version
Python 3.6.0
[root@host ~]# yum -y install rh-python35
[root@host ~]# scl enable rh-python35 bash
[root@host ~]# python --version
Python 3.5.1
```
ヽ(=´▽`=)ﾉ

ただし、このままではあとで `libpython3.5m.so` が見つからないとか言われて困ることになるので、以下のおまじないをしておく。

```
[root@host ~]# ln -fs /opt/rh/rh-python35/root/usr/lib64/libpython3.5m.so.rh-python35-1.0 /lib64/
```

# .aws/credentials を一時退避
自分の環境では、どうも既存の .aws/credentials に書いてある aws_access_key_id, aws_secret_access_key を使った awslogs がうまいこと動かなかったので、一時退避しておく。
これをやると他の aws cli 関連で問題が起きるかもしれないので、環境によっては要注意。

```
[root@host ~]# cd ~/.aws
[root@host .aws]# mv credentials _credentials
```

# IAM ロールを作成して EC2 インスタンスに割り当てる
↑で credentials を退避してしまって、どうやって EC2 インスタンスから対象の CloudWatch に接続するの？ というところで、IAM ロールを活用することに。
どうやら、awslogs (実態は /var/awslogs/bin に配置された aws cli v1 )は credentials が未設定の場合、IAM ロールを使うという挙動になってるようす。
もし対象の EC2 インスタンスに、すでに別の IAM ロールが割り当てられてた場合は、そのロールに追加することで対応可能なはず。

## 先に IAM ポリシーを作成
### IAM の「ポリシー作成」を押す
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317903/15374617-c0e6-78af-5019-e6b12f1d11a2.png)


### 「JSON」タブを選ぶ
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317903/bfbb0b01-a963-691b-486b-cdf5f112a825.png)

### JSON の内容を入力
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317903/d0e6a65a-460a-725f-7404-ad244404a9a0.png)
公式が案内している ↓ の JSON をコピペ。

```
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents",
        "logs:DescribeLogStreams"
    ],
      "Resource": [
        "*"
    ]
  }
 ]
}
```

### ポリシー名を入力
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317903/2e5598b4-ecb9-833c-a288-5457383a20d1.png)

## 次に IAM ロールを 作る

### IAM の「ロールの作成」を押す
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317903/9fcec19b-85e4-45c0-6577-a3cbbf408287.png)

### ユースケースの「EC2」を選ぶ
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317903/8495a265-aedf-a370-1121-433bc889bf77.png)

### 作ったポリシーを選ぶ
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317903/913a2681-3bee-058a-2407-071a9cd3cdde.png)

このあとのタグとかはよしなにして保存。

## EC2 インスタンスに IAM ロールを割り当てる

### ロール割り当てを開く
![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317903/8388bfd3-c1f0-d59a-d762-591a759d9256.png)
対象のインスタンスの行で右クリック → セキュリティ → IAM ロールを変更 を選ぶ。

### 作成したロールを選択する
![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317903/c054489c-2a07-0363-4972-8f75308b0932.png)

保存しておわり。

# awslogs インストール & 設定
## 作業環境を用意

```
[root@host ~]# cd ~
[root@host ~]# mkdir awslogs
[root@host ~]# cd awslogs
```

## インストーラのダウンロードと依存ライブラリの展開

```
[root@host awslogs]# curl https://s3.amazonaws.com/aws-cloudwatch/downloads/latest/awslogs-agent-setup.py -O
[root@host awslogs]# curl https://s3.amazonaws.com/aws-cloudwatch/downloads/latest/AgentDependencies.tar.gz -O
[root@host awslogs]# tar xvf AgentDependencies.tar.gz -C /tmp/
```

## インストール実行
ここでは apache のエラーログのみ扱うことにするので、それ以外は各自繰り返し登録。
apache のログを CloudWatch に流すにあたって、datetime_format を `[%a %b %d %H:%M:%S %Y]` としてやるのが小技。

```
[root@host awslogs]# python ./awslogs-agent-setup.py --region ap-northeast-1 --dependency-path /tmp/AgentDependencies

Launching interactive setup of CloudWatch Logs agent ...

Step 1 of 5: Installing pip ...DONE

Step 2 of 5: Downloading the latest CloudWatch Logs agent bits ...

Step 3 of 5: Configuring AWS CLI ...
AWS Access Key ID [None]:　【※何も入力せず Enter】
AWS Secret Access Key [None]:　【※何も入力せず Enter】
Default region name [ap-northeast-1]:　【※何も入力せず Enter】
Default output format [None]:　【※何も入力せず Enter】

Step 4 of 5: Configuring the CloudWatch Logs Agent ...
Path of log file to upload [/var/log/messages]: /var/log/httpd/error_log　【※監視対象のログファイルを入力】
Destination Log Group name [/var/log/httpd/error_log]: EXAMPLE-LOG-GROUP　【※ CloudWatch のロググループ名を入力、存在してなかったら自動で作成してくれる】

Choose Log Stream name:
  1. Use EC2 instance id.
  2. Use hostname.
  3. Custom.
Enter choice [1]: 1　【※ 1 を入力】

Choose Log Event timestamp format:
  1. %b %d %H:%M:%S    (Dec 31 23:59:59)
  2. %d/%b/%Y:%H:%M:%S (10/Oct/2000:13:55:36)
  3. %Y-%m-%d %H:%M:%S (2008-09-08 11:52:54)
  4. Custom
Enter choice [1]: 4　【※ 4 を入力】
Enter customer timestamp format [None]: [%a %b %d %H:%M:%S %Y]　【※ apache のフォーマットに基いた内容を入力】

Choose initial position of upload:
  1. From start of file.
  2. From end of file.
Enter choice [1]: 1　【※ 1 を入力】
More log files to configure? [Y]: n　【※ 他にも流したいログファイルがある場合は y を入力してこのステップを繰り返す】

Step 5 of 5: Setting up agent as a daemon ...DONE


------------------------------------------------------
- Configuration file successfully saved at: /var/awslogs/etc/awslogs.conf
- You can begin accessing new log events after a few moments at https://console.aws.amazon.com/cloudwatch/home?region=ap-northeast-1#logs:
- You can use 'sudo service awslogs start|stop|status|restart' to control the daemon.
- To see diagnostic information for the CloudWatch Logs Agent, see /var/log/awslogs.log
- You can rerun interactive setup using 'sudo python ./awslogs-agent-setup.py --region ap-northeast-1 --only-generate-config'
------------------------------------------------------

[root@host awslogs]# chkconfig awslogs on
[root@host awslogs]# service awslogs status
 (pid  10675) is running...
```

ヽ(=´▽`=)ﾉ

これで CloudWatch のロググループが作成されてるはず。
なかったら、たぶん何かエラーが起きてると思うので、 /var/log/awslogs.log を眺める。