🥢

Terraform Cloud の各 Workspace で利用されているリソースの取得方法

2024/01/05に公開

Terraform Cloudの課金体系が、2023年5月にResource Under Management(以下RUM)の数に変更されました(資料によっては、Managed Resourcesと表現されている事もありますが、RUMと同じ意味になります)。
https://www.hashicorp.com/blog/terraform-cloud-updates-plans-with-an-enhanced-free-tier-and-more-flexibility

RUMの対象になるTerraformリソースは、ステートファイルでmode = managedとなっているリソースになります。

RUM対象となるTerraformリソースの一例
  {
    "mode": "managed",
    "type": "vault_mount",
    "name": "int",
    "provider": "provider[\"registry.terraform.io/hashicorp/vault\"]",
...

Terraformリソースの全てがRUMの対象となるわけではなく、データソースnull_resourceRUMの対象外となります。

Terraform CloudではWorkspace毎にステートが管理されるわけですが、Workspace毎にどの様なリソースが管理され、どの程度RUMを消費しているか一元的に確認したくなるケースもあるかと思います。BetaリリースされているExplorerを含め、現状Terraform CloudのGUIから良い感じに確認出来る方法は無さそうなので、それを実現するためにはTerraform Cloud APIを利用するしか現状はなさそうです。

以下お使いのTerraform CloudのOrganization内のWorkspace毎にどの様なリソースが作成され、どの程度RUMを消費しているか確認する方法について記載します。

Resources in Terraform Cloud workspace

Terraform Cloudの各WorkspaceのOverviewから、そのWorkspaceでどの様なリソースが管理され、何リソース存在しているか確認して頂く事が可能です。

Terraform CloudのWorkspaceのOverview

これはRUMの数ではなく、Workspaceで管理されているステートでリソースとして定義されている数になりますので、

Terraform CloudのWorkspaceのOverviewで確認出来るリソース数 >= そのWorkspaceで消費しているRUM数

となります。

Workspace毎にどの程度RUMを消費しているか概算を把握する上ではこれでも十分かと思います。
また、WorkspaceのStates確認画面から対象となるステートを選択した上で、filterフィールドで.resources[].modeと入力し、Applyボタンをクリックすると、mode = managedとなっているリソース数を確認する事も出来ます。

WorkspaceのStateのfilterを利用して確認

ただ、Terraform CloudのOrganization内にある各Workspaceでどの程度RUMが消費され、各Workspace毎にどの様なリソースが管理されているか一元的に可視化する機能は現状無いため、その様な情報を確認したい場合、Terraform Cloud APIのWorkspace Resources APIを利用して頂くと良い感じに取得出来そうです。

Get resources via Terraform Cloud API

上記のAPIを利用するとサンプルレスポンスにある通り、data[].attributes.addressからWorkspaceで管理されているリソース情報を取得出来そうです。

{
  "data": [
    {
      "id": "wsr-KNYb3Jj3JTBgoBFs",
      "type": "resources",
      "attributes": {
        "address": "random_pet.animal",
        "name": "animal",
        "created-at": "2021-10-27",
        "updated-at": "2021-10-27",
        "module": "root",
        "provider": "hashicorp/random",
        "provider-type": "random_pet",
        "modified-by-state-version-id": "sv-y4pjfGHkGUBAa9AX",
        "name-index": null
      }
    },
    {
      "id": "wsr-kYsf5A3hQ1y9zFWq",
      "type": "resources",
      "attributes": {
        "address": "random_pet.animal2",
        "name": "animal2",
        "created-at": "2021-10-27",
        "updated-at": "2021-10-27",
        "module": "root",
        "provider": "hashicorp/random",
        "provider-type": "random_pet",
        "modified-by-state-version-id": "sv-y4pjfGHkGUBAa9AX",
        "name-index": null
      }
    }
  ],
  "links": {
    "self": "https://app.terraform.io/api/v2/workspaces/ws-DiTzUDRpjrArAfSS/resources?page%5Bnumber%5D=1&page%5Bsize%5D=20",
    "first": "https://app.terraform.io/api/v2/workspaces/ws-DiTzUDRpjrArAfSS/resources?page%5Bnumber%5D=1&page%5Bsize%5D=20",
    "prev": null,
    "next": null,
    "last": "https://app.terraform.io/api/v2/workspaces/ws-DiTzUDRpjrArAfSS/resources?page%5Bnumber%5D=1&page%5Bsize%5D=20"
  },
  ...
}

色々と手直ししたり、工夫したりする箇所あると思いますが、以下の様な形でスクリプトを作成し、実行して頂ければ、Terraform CloudのOrganizationで管理されているWorkspace毎のRUM数は取得頂けそうです。

get-rum.sh
#!/bin/bash

#Terraform Cloud APIトークンとOrganization名を変数にセット
TFC_TOKEN=xxx
TFC_ORG_NAME=xxx

#Organization配下の全てのWorkspaceのIDを取得
for a in $(curl -s --header "Authorization: Bearer $TFC_TOKEN" --request GET https://app.terraform.io/api/v2/organizations/$TFC_ORG_NAME/workspaces | jq -r '.data[].id')
  do
    WORKSPACE_NAME=$(curl -s --header "Authorization: Bearer $TFC_TOKEN" --request GET https://app.terraform.io/api/v2/workspaces/${a} | jq -r '.data.attributes.name')
    PROJECT_ID=$(curl -s --header "Authorization: Bearer $TFC_TOKEN" --request GET https://app.terraform.io/api/v2/workspaces/${a} | jq -r '.data.relationships.project.data.id')
    PROJECT_NAME=$(curl -s --header "Authorization: Bearer $TFC_TOKEN" --request GET https://app.terraform.io/api/v2/projects/$PROJECT_ID | jq -r '.data.attributes.name')
    echo "###### RUM info ######"
    echo "----------"
    echo "Workspace: ${WORKSPACE_NAME}"
    echo "Project:   ${PROJECT_NAME}"
    echo "----------"
    #Workspaceで管理されているRUM情報を取得
    curl -s --header "Authorization: Bearer $TFC_TOKEN" --request GET https://app.terraform.io/api/v2/workspaces/${a}/resources | jq -r '.data[].attributes.address' | sort -n | grep -vE '^data\.|null_resource'
    WORKSPACE_RUM=$(curl -s --header "Authorization: Bearer $TFC_TOKEN" --request GET https://app.terraform.io/api/v2/workspaces/${a}/resources | jq -r '.data[].attributes.address' | sort -n | grep -vE '^data\.|null_resource' | wc -l)
    echo "----------"
    echo "RUM: ${WORKSPACE_RUM}"
    echo ""
  done

出力結果は以下の様な形になります。

###### RUM info ######
----------
Workspace: approle-test
Project:   demo_hcpv
----------
vault_approle_auth_backend_role.example
vault_approle_auth_backend_role_secret_id.example
vault_kv_secret_v2.example
vault_mount.example
vault_policy.example
vault_policy.gen_secret_id
----------
RUM:        6

###### RUM info ######
----------
Workspace: vault-hcp-demo_pki
Project:   demo_hcpv
----------
vault_mount.int
vault_mount.root
vault_pki_secret_backend_cert.app
vault_pki_secret_backend_cert.client
vault_pki_secret_backend_cert.db
vault_pki_secret_backend_config_urls.config_urls
vault_pki_secret_backend_intermediate_cert_request.int
vault_pki_secret_backend_intermediate_set_signed.int
vault_pki_secret_backend_role.int1
vault_pki_secret_backend_role.int2
vault_pki_secret_backend_role.int3
vault_pki_secret_backend_root_cert.root
vault_pki_secret_backend_root_sign_intermediate.root
----------
RUM:       13
...

必要に応じてご活用下さい!

References

Discussion