【Amazon Connect】ルーティングプロファイルのキューをAWS CLIで一括変更する方法

## 経緯
業務で既存の52個のルーティングプロファイルに対して、複数の「割り当てキュー」を追加する設定をしなくてはいけないタスクがありました。手作業かつ2人でこれらを追加したところ、約1時間半かかってしまっていたので、業務短縮のためAWS CLIを使用しました。

## 前提
設定するルーティングプロファイルのキューは「割り当てキュー」を想定しています。（アウトバウンドキュー、チャネルの定義などは事前に作成されていることとする）
割り当てキューは以下の画像の赤枠の部分を示している。
そのうえで以下のパラメータが必要になる。
- インスタンスID
- ルーティングプロファイル名
- ルーティングプロファイルID
- キュー名
- キューID
- チャネル
- 優先度
- 遅延（秒）

![スクリーンショット 2025-01-17 15.36.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3843904/5906de3f-1179-033f-fef9-52ab12975e33.png)

## 実装全体イメージ図
![ルーティングプロファイルキュー変更_AWS-CLI構造図解.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3843904/46650757-8659-ce1d-4c9a-cb0f37c30edb.png)


## 実装方法
1. JSONファイル作成に必要なパラメータを、以下のようなCSVファイルにまとめる

    ※ルーティングプロファイル名とキュー名は論理名
    ※ルーティングプロファイルIDとキューID、インスタンスIDは物理名を使用すること
    
    ![スクリーンショット 2025-01-16 11.22.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3843904/42e6211f-0700-4264-12d0-c63a0904b1c8.png)


    物理名の取得は以下のAWS CLIを使用する
    
    ```sh
    $ aws connect list-instances
    $ aws connect list-routing-profiles
    $ aws connect list-queues
    ```
    
1. Pythonを使用してCSVファイルからインプットするJSONファイルに変換する
    - CSVファイル構造が上記と同じであれば、インプットするCSVファイル名と出力するJSONディレクトリ名を追加していただければ、下記のPythonスクリプトコピペで使用できます
    - ルーティングプロファイルの数だけ、ルーティングプロファイル名のJSONファイルを生成するように組んでいます

    ```py
    import csv
    import json
    import os
    
    def generate_json_per_routing_profile(input_csv_path, output_directory):
        # 出力ディレクトリを作成
        if not os.path.exists(output_directory):
            os.makedirs(output_directory)
    
        with open(input_csv_path, encoding="utf-8") as csv_file:
            csv_reader = csv.reader(csv_file) 
            rows = list(csv_reader) 
    
            # 初期データの取得 (InstanceId, Delay)
            instance_id = None
            delay = None
            for row in rows:
                if row[0] == "InstanceId":
                    instance_id = row[1]
                    delay = int(row[3]) if row[3].isdigit() else 0 
                    break
    
            # ルーティングプロファイルごとのデータ格納用
            routing_profiles = {}
            current_profile = None
            current_profile_id = None
    
            # CSVの処理
            for row in rows[3:]:  # データは4行目以降から
                if row[0]:  # 0列目に値がある場合、ルーティングプロファイル名
                    current_profile = row[0]
                    current_profile_id = row[1]
                    if current_profile not in routing_profiles: # routing_profilesにcurrent_profileがない場合
                        routing_profiles[current_profile] = {
                            "InstanceId": instance_id,
                            "RoutingProfileId": current_profile_id,
                            "QueueConfigs": []
                        }
                elif current_profile and row[3]:  # キュー情報がある行
                    queue_config = {
                        "QueueReference": {
                            "QueueId": row[3],
                            "Channel": "VOICE"
                        },
                        "Priority": int(row[4]) if row[4].isdigit() else 0,
                        "Delay": delay
                    }
                    routing_profiles[current_profile]["QueueConfigs"].append(queue_config)
    
        # 各ルーティングプロファイルごとにJSONファイルを出力
        for profile_name, profile_data in routing_profiles.items():
            json_filename = f"{profile_name}.json"
            json_path = os.path.join(output_directory, json_filename)
            with open(json_path, "w", encoding="utf-8") as json_file:
                json.dump(profile_data, json_file, ensure_ascii=False, indent=2)
            print(f"JSONファイルが生成されました: {json_path}")
    
    # 各環境のデータCSVファイル名と出力ディレクトリ名
    input_csv_path = ""
    output_directory = ""
    
    # 実行
    generate_json_per_routing_profile(input_csv_path, output_directory)
    ```

1. 作成されたJSONファイル
    - JSON構成例

    ```json
    {
      "InstanceId": "sample",
      "RoutingProfileId": "sample",
      "QueueConfigs": [
        {
          "QueueReference": {
            "QueueId": "sample",
            "Channel": "VOICE"
          },
          "Priority": 1,
          "Delay": 0
        }
      ]
    }
    ```

1. 使用するAWS CLI例

    - JSONファイル内にインスタンスIDなどを記載しているためコマンドライン上に記載は不要です

    ```sh
   $ aws connect associate-routing-profile-queues --cli-input-json file://test.json
    ```

1. zip化するなどしてCloudShell内にJSONファイルを配備
1. zipファイルを解凍し、配備したJSONディレクトリに移動
    ```
    $ unzip "ファイル名"
    $ cd "ファイル名"
    ```
1. シェルスクリプトにAWS CLIをまとめ、権限を付与して実行
    ```
    $ chmod +x "スクリプト名".sh
    $ ./"スクリプト名".sh
    ```

    - シェルスクリプトイメージ
    ```sh
   $ aws connect associate-routing-profile-queues --cli-input-json file://test.json
   $ aws connect associate-routing-profile-queues --cli-input-json file://test1.json
   $ aws connect associate-routing-profile-queues --cli-input-json file://test2.json
    ...
    ...
    ...
    ```

    - 実行前
![スクリプト実施前.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3843904/39af0949-769a-3a92-4cf3-5afb62ae3e69.png)
    - 実行後
![スクリプト実施後.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3843904/af0dbc2f-04f7-2b22-4c42-b5b33960db4e.png)

## 注意点
今回、`aws connect associate-routing-profile-queues`のコマンドを使用している。これは新規で、ルーティングプロファイルキューを設定する時に用いられる。設定するキューが存在している場合、エラーとなるので注意が必要。
よって、JSON出力用に用いるCSVファイルでは新規で追加する割り当てキューの情報のみ記載する必要があることに注意する。

また、`aws connect update-routing-profile-queues`では既存のルーティングプロファイルキューの更新は可能だが、設定されていないキューの追加はできない。

## まとめ
今回はAWS CLIを使用して、複数のルーティングプロファイルキューを作成しました。
CLIリファレンスを見ても、どのような構成のJSON形式で書けばよいのか分かりづらく、大変でした。
実際の作業は52個のルーティングプロファイルを変更する必要があり、約1時間半（作業人数2人）かかっていましたが、約30分で完了することができました。

### 参考記事
- https://docs.aws.amazon.com/cli/latest/reference/connect/associate-routing-profile-queues.html