CloudFunctionsでWEBサイトのSSL証明書の監視をしてみる

# この記事は？ 
- この記事は[「Google Cloud Platform Advent Calendar 2021」](https://qiita.com/advent-calendar/2021/gcp)カレンダー2の25日目の記事です。  

# 謝辞
- お忙しい中、快く相談に乗っていただいた、Google Cloud JapanのCEの皆様に多大なる感謝を。
- 以下の記事、大変参考になりました。ありがとうございます。
    - [証明書期限切れまであと何日かチェックする](https://qiita.com/k8uwall/items/2ecc8057fc4c0dae878e)

# この記事でやること/やりたいこと
- WEBサイトのSSL証明書監視をGCPで実装してみます。
    - 有効期限残りXX日(閾値)を下回ったらSlackに通知、がゴールです。
    - ここでは例として、google.comの証明書有効期限をチェックするようにしています。
- イメージ図  
![check_ssl_cert.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36284/237054cf-1ecc-622b-b4f1-df85a766a15a.png)


# 出来上がったもの
- SlackでSSL証明書の有効期限アラートの受信  
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36284/de973d4e-ddb6-9f34-b9b6-f5370846c59e.png)

- [CloudFuntcionsのサンプルコード](https://github.com/koitatu/gcf_check_cert_sample/)


# 所感
- Monitoringで直接SSL証明書の有効期限ができると嬉しいなあ…
- おそらく、CloudFuntcions→Logging→ログベースのアラートは良くない。
    - 本来
        - MonitoringAPIで直接メトリクス書き込むべき。
            - でないと、Monitoring側でメトリクス表示できなさそう。
            - 別途直していきます。
- 残り有効期限何日、をSlackで通知したい。
- とはいえ、プログラム万年初心者でも、こういったものをサクッと作れるのはGCPの良いところ。
    - 大変ありがたい。




# 前提
- 課金設定済みのGCP環境があること。
- 以下のGCPリソースの作成権限があり、APIが有効化されていること。
    - CloudScheduler
    - Pub/Sub
    - CloudFunctions
    - CloudLogging
    - CloudMonitoring
- 通知用のSlackがあること。
    - Slackへの通知設定等はここでは割愛します。

# 要素
- 1.CloudScheduler
    - JOBキック用。
    - Pub/Subへ連携します。
- 2.Pub/Sub
    - CloudSchedulerとCloudFunctionsの橋渡し。
- 3.CloudFunctions
    - Pub/Subから経由でCloudFuntcionsを実行します。
        - pythonでgoogle.comのSSL証明書有効期限をチェック。
        - 残り日数をCloudLoggingへ記録。
- 4.CloudLogging
    - ログベースのアラートを仕掛ける。
- 5.CloudMonitoring
    - 通知先にSlackを指定。
        - ここでは割愛します。
- 6.Slack
    - Monitoring側から通知を受信。

# やること
## 1.CloudScheduler
JOBキック用にCloudSchedulerを設定します。  

以下のようにJOBを作成します。
### 1.スケジュールの定義する。  
- 説明
    - よしなに。極力分かりやすい命名規則に。
- 頻度
    - 毎日00:00に実行したいので以下のように設定しています。  
        ```
        0 0 * * *
        ```
    - タイムゾーン
        - 日本在住なのでJSTで。  

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36284/87f8408f-a989-a134-0342-79edb71ad808.png)

### 2.実行内容を構成する。
- ターゲットタイプ
    - Pub/Sub
- CloudPub/Subトピック
    - ここでは、`check_web_ssl_expire_for_google_topic`というトピックを作成しています。  
        ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36284/e2d1dbf1-2832-2c9e-2b15-d85bf43ea705.png)
- メッセージ本文  
    - 今回はメッセージは使用しないのですが、必須項目なので`check_web_ssl_expire`と入力しています。  

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36284/0354e287-f4b4-6eb1-6205-c5ec604cd607.png)

### 3.Configure the job's retry (optional)
- リトライ回数、リトライ時間等の設定。
- オプションなので、今回はそのまま。
  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36284/ef59430d-db92-c087-8f83-715dcad7ff80.png)

## 2.Pub/Sub 
- 今回、上記1のCloudScheduler設定時にPub/Subのトピックも作成したので不要です。

## 3.CloudFunctions  
CloudFunctionsで関数の作成を行います。
### 3-1.構成
- 関数名
    - 任意の値を入力。ここでは`check_web_ssl_expire_test2`としています。
- リージョン
    - 実行したいリージョンを選択。ここでは`us-central1`にしています。
- トリガー
    - トリガーのタイプ
        - Cloud Pub/Subを選択。
    - Cloud　Pub/Subのトピック
        - 先に作成したものを選択。ここでは`check_web_ssl_expire_for_google_topic`を選択します。
- ランタイム、ビルド、接続、セキュリティの設定
    - 今回はデフォルトのまま次へ。 
      
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36284/d32cc9af-b095-7960-070e-b1ef9e49ff7d.png)

### 3-2.関数の作成
- ランタイム 
    - Python 3.9 を選択。
- エントリ ポイント
    - `main` と入力
- ソースコード
    - ZIPアップロードを選択。
        - ZIPファイル
            - ローカルに落としてきた、function-source.zipを選択。
                -  https://github.com/koitatu/gcf_check_cert_sample/blob/main/function-source.zip
        - ステージバケット
            - ここでは`gcf-source-check-ssl-expire`というGCSを作成して、選択しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36284/7fb922b5-0d67-27da-6274-ce89dc53809e.png)

## 4.CloudLogging
ログエクスプローラーにてアラートを作成します。  
まずはログエクスプローラーで対象のログを検索します。

- クエリ  

```
logName="projects/<プロジェクト名>/logs/check_web_ssl_expire_remaining_days_log"
textPayload <= 72
```
- アラートを作成を選択。  
      ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36284/43cd48a7-2cba-794c-c670-22e18ed0b58c.png)

    - Alert details
        - Alert Name
            - 通知名を入力。
        - ドキュメント
            - 通知を見て分かりやすいように入力。
    - Choose logs to include in the alert
        - 検索条件が既に入力されているので、そのまま次へ。
    - う. 
    - Set time between notifications
        - 通知の間隔を任意のものを選択し、次へ。
    - Who should be notified?
        - 通知先の選択。
            - ここでは既にCloudMonitoringへ仕込んでおいた通知先設定を使用。  
               ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36284/0bdb63b7-1088-c392-d5e5-b98d63a77be7.png)
- ログベースのアラートポリシー設定イメージ  
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36284/f60ce97b-f80f-c782-585b-956aadd6e893.png)

# 通知テスト.  
- Cloud SchedulerからJOBを実行.  
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36284/a1a04982-a544-c6ca-daa1-b2c9b92dae98.png)
- Slackで受信を確認。　　
　　　　　　　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36284/48b03226-b59f-24d9-1964-4402c271b160.png)