Code Engineのアプリケーションを時間指定でPublicの公開を停止する[IBM Cloud汎用操作ツール]

# はじめに
こちらは、下記で公開したツールを利用したユースケースの1例になります。

https://qiita.com/katahiro/items/70502a32492d9320309f

IBM CloudのCode Engineは手軽にコンテナアプリケーションを公開することが可能です。また、比較的安価なサービスなので、検証環境として利用されるケースもよく見られます。
利用されるケースによっては、特定の時間帯のみアプリケーションを公開して、それ以外は外部からのアクセスは拒否したい、というケースがあるかもしれません。

Code Engineはゼロスケールに対応しているため、アプリの呼び出しが無い間は課金が発生しない状態にすることはできますが、これはあくまで稼働しているコンテナの取り扱いのため、呼び出されても動かないようにする、といったものではありません。
なので、特定の時間帯だけアプリをPublicに公開して、それ以外は閉じる、というのはゼロスケール以外の方法で実現する必要があります。

Code Engineでは、アプリケーションのドメインマッピングを以下の3つで設定が可能です。
- `Public` : インターネットからアクセス可能にする
- `Private` : VPC環境からPrivateネットワークでアクセス可能にする
- `Project(No external system domain mapping)` : Code Engineの同じProject内からのみアクセス可能にする

インターネットアクセス可能な状態は、このドメインマッピングの設定が `Public` になっているので、外部からのアクセスを完全に遮断する場合は `Project` の状態に設定を変更するのが良いです。

では、Code Engineに時間指定でドメインマッピングの設定を変更するようなサービスはあるのでしょうか？

ありません。。。

なので、先の記事で紹介したツールを利用してそれを実現しましょう。

# Code Engineでの設定
Code Engineの設定をCode Engineで行うという形になりますが、Jobを作成する時に、以下のように設定しましょう。これはドメインマッピングの設定を `Project` にするJobです。

- Job Name : `任意の名称`
- Image Reference : `docker.io/hiroapps/ibmcloud-cli-image:1.1.0`
- Job instances : `1`
- Instance resources 
    - CPU and memory : `0.125 vCPU / 0.25 GB`
    - Ephemeral storage (GB) : `0.04`
- Resiliency settings 
    - Mode : `Task`
    - Number of job retries : 3
- Optional settings
    - Environment Variables (optional)
        - `COMMAND00` : `ibmcloud config --check-version=false`
        - `COMMAND01` : `ibmcloud login -- apikey [権限のあるAPIキー] -r [Code Engineのあるリージョン] -g [Code Engineのリソースグループ]`
        - `COMMAND02` : `ibmcloud ce project select -n [Code Engineのプロジェクト名]`
        - `COMMAND03` : `ibmcloud ce app update -n [Code Engineのアプリ名] --visibility project`

:::note warn
2024/3/5 `COMMAND00`を追加しています。CLIのバージョンアップを問われるので、それを無視するために実行が必要です。
:::
:::note
執筆時点で利用するイメージは `docker.io/hiroapps/ibmcloud-cli-image:1.0.0`としていますが、最新のイメージがある場合はそちらを利用ください。
 
また、利用者でツールのイメージを別のコンテナレジストリに格納している場合はそちらを利用ください。
:::

:::note warn
`権限のあるAPIキー`と記載していますが、このCode Engineの操作しか行わないように権限を厳密に指定する場合は、作成するAPIキーには、Code Engineが作成されたリソースグループに対するReader権限が最低必須になります。
:::

最初に指定しているログインコマンドですが、仮にAPIキーが `abcde` 、サービスを作成したリージョンが東京、リソースグループが `Default`の場合は、以下のようになります。
`ibmcloud login --apikey abcde -r jp-tok -g Default`

# 実行してみよう
さて、上記の権限設定に問題なければ、先ほど指定した環境変数のコマンドに従ってCode Engineのアプリケーションのドメインマッピングが変更されます。

Jobを作成して、`Submit Job`でJobを手動実行してみましょう。

以下はJobの実行ログをLogDNAのサービスで確認したものです。
```console
Jan 25 17:33:10 Code Engine ce-cli-test-jobrun-w5kr2-0-0 ## COMMAND01 ##
Jan 25 17:33:10 Code Engine ce-cli-test-jobrun-w5kr2-0-0 $ ibmcloud login *****
Jan 25 17:33:20 Code Engine ce-cli-test-jobrun-w5kr2-0-0 API endpoint: https://cloud.ibm.com
Jan 25 17:33:20 Code Engine ce-cli-test-jobrun-w5kr2-0-0 Authenticating...
Jan 25 17:33:20 Code Engine ce-cli-test-jobrun-w5kr2-0-0 OK
Jan 25 17:33:20 Code Engine ce-cli-test-jobrun-w5kr2-0-0 Targeted account IBM (アカウントID)
Jan 25 17:33:20 Code Engine ce-cli-test-jobrun-w5kr2-0-0 Targeted resource group Default
Jan 25 17:33:20 Code Engine ce-cli-test-jobrun-w5kr2-0-0 Targeted region au-syd
Jan 25 17:33:20 Code Engine ce-cli-test-jobrun-w5kr2-0-0 API endpoint:      https://cloud.ibm.com
Jan 25 17:33:20 Code Engine ce-cli-test-jobrun-w5kr2-0-0 Region:            au-syd
Jan 25 17:33:20 Code Engine ce-cli-test-jobrun-w5kr2-0-0 User:              ServiceId-サービスID (サービスID名)
Jan 25 17:33:20 Code Engine ce-cli-test-jobrun-w5kr2-0-0 Account:           IBM (アカウントID)
Jan 25 17:33:20 Code Engine ce-cli-test-jobrun-w5kr2-0-0 Resource group:    Default
Jan 25 17:33:20 Code Engine ce-cli-test-jobrun-w5kr2-0-0 CF API endpoint:   
Jan 25 17:33:20 Code Engine ce-cli-test-jobrun-w5kr2-0-0 Org:               
Jan 25 17:33:20 Code Engine ce-cli-test-jobrun-w5kr2-0-0 Space:             
Jan 25 17:33:30 Code Engine ce-cli-test-jobrun-w5kr2-0-0 ## COMMAND02 ##
Jan 25 17:33:30 Code Engine ce-cli-test-jobrun-w5kr2-0-0 $ ibmcloud ce proj select --name Code Engineのプロジェクト名
Jan 25 17:33:40 Code Engine ce-cli-test-jobrun-w5kr2-0-0 Selecting project 'プロジェクト名'...
Jan 25 17:33:40 Code Engine ce-cli-test-jobrun-w5kr2-0-0 OK
Jan 25 17:33:40 Code Engine ce-cli-test-jobrun-w5kr2-0-0 ## COMMAND03 ##
Jan 25 17:33:40 Code Engine ce-cli-test-jobrun-w5kr2-0-0 $ ibmcloud ce app update --name アプリケーション名 --visibility project
Jan 25 17:33:40 Code Engine ce-cli-test-jobrun-w5kr2-0-0 Updating application 'アプリケーション名' to latest revision.
Jan 25 17:33:40 Code Engine ce-cli-test-jobrun-w5kr2-0-0 Ingress has not yet been reconciled.
Jan 25 17:34:00 Code Engine ce-cli-test-jobrun-w5kr2-0-0 Traffic is not yet migrated to the latest revision.
Jan 25 17:34:00 Code Engine ce-cli-test-jobrun-w5kr2-0-0 Ingress has not yet been reconciled.
Jan 25 17:34:00 Code Engine ce-cli-test-jobrun-w5kr2-0-0 Run 'ibmcloud ce application get -n アプリケーション名' to check the application status.
Jan 25 17:34:00 Code Engine ce-cli-test-jobrun-w5kr2-0-0 OK
Jan 25 17:34:00 Code Engine ce-cli-test-jobrun-w5kr2-0-0 http://sample-app.1ck6jq0hn2yk.svc.cluster.local
```
問題なくCode Engineのドメインマッピングが `Project` になりました。

アクセス可能だったPublicのURLにアクセスしても、以下のような画面しか表示されません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651598/e1fbc3fa-6b48-3057-3f34-4358795f4877.png)

これでドメインマッピングを `Project` に変更するJobが作成できたので、今度は `Public` に戻すJobを作成しましょう。

- Job Name : `任意の名称`
- Image Reference : `docker.io/hiroapps/ibmcloud-cli-image:1.1.0`
- Job instances : `1`
- Instance resources 
    - CPU and memory : `0.125 vCPU / 0.25 GB`
    - Ephemeral storage (GB) : `0.04`
- Resiliency settings 
    - Mode : `Task`
    - Number of job retries : 3
- Optional settings
    - Environment Variables (optional)
        - `COMMAND01` : `ibmcloud login -- apikey [権限のあるAPIキー] -r [Code Engineのあるリージョン] -g [Code Engineのリソースグループ]`
        - `COMMAND02` : `ibmcloud ce project select -n [Code Engineのプロジェクト名]`
        - `COMMAND03` : `ibmcloud ce app update -n [Code Engineのアプリ名] --visibility public`

先ほどとの違いは、 `COMMAND03`で指定するvisibilityのパラメータが `public` になっただけです。

# Event Subsctiptionへの登録
Event Subscriptionへの登録は次のリンク記事の途中から記載しているので、そちらを参考にしてください。

https://qiita.com/katahiro/items/68dd7609844b98925937#code-engine%E3%81%A7%E7%A8%BC%E5%83%8D%E8%A8%AD%E5%AE%9A

cron形式で起動する時間を指定できるので、必要な時間帯を過ぎるとドメインマッピングを `Project` に設定して外部からアクセスできないようにし、朝にまた `Public` に戻すJobを登録すれば良いでしょう。

:::note warn
Code EngineのJobは指定された起動時間から、Jobのコンテナイメージをロードして動作するので、指定した時間ピッタリに処理が動く、というわけではありません。少し余裕をみて設定させるようにしましょう。
:::

# さいごに
いかがでしたでしょうか？
IBM Cloud汎用操作ツールで、Code Engineの環境を時間指定して外部からアクセスできないようにする方法の目途がつきました。ぜひ、このユースケースを参考にIBM Cloudで理想的な運用が実現できると幸いです。