Terraform Exporter for SAP BTPを使ってみる

## はじめに
SAP BTPの環境構築を自動化するためのツールとして、[Terraform provider for SAP BTP](https://registry.terraform.io/providers/SAP/btp/latest/docs)があります。TerraformというInfrastructure as Code (IaC) ツールにより、設定ファイル（コード）を使用してインフラを自動で構築するというものです。以下の記事でTerraform provider for SAP BTPについて紹介しています。

https://qiita.com/tami/items/df0a43c70efa6a3d9d0d

## Terraform Exporter for SAP BTPとは
Terraformを使ってBTP環境を管理する際、Terraform導入前に作成したリソース（サブスクリプションやサービスインスタンスなど）はTerraformの管理外です。同様に、Terraform導入後にマニュアルで作成したリソースについてもTerraformは管理しません。

Terraformを使い始めたら他の方法（マニュアル、CLIなど）で変更を加えないことが推奨されています。このため、既存のリソースやマニュアルで作成してしまったリソースをTerraform管理下に置きたいという要望が出てきます。

Terraform Exporter for SAP BTPはそのような要望に応えるため、既存のリソースをTerraformに「インポート」するのを助けます。

:::note warn
2025年1月時点では、Terraform Exporter for SAP BTPはベータ版となっており本番での使用は非推奨です。
:::

**参考**
- [Terraform Exporter for SAP BTP](https://sap.github.io/terraform-exporter-btp/)
- [May I introduce you to the … Terraform Exporter for SAP BTP](https://www.linkedin.com/pulse/may-i-introduce-you-terraform-exporter-sap-btp-christian-lechner-lgzif/)

### 仕組み
Terraformにはもともと"**import**"という仕組みが備わっています。`import`ブロックをコードに追加するか、`terraform import`というコマンドを実行することで既存のリソースをTerraformの管理下に追加することができます。

例えば、Terraformで"SAPLaunchpad" (SAP Build Work Zone, standard edition)のサブスクリプションを定義するとします。
```tf
resource "btp_subaccount_subscription" "SAPLaunchpad" {
  app_name      = "SAPLaunchpad"
  plan_name     = "standard"
  subaccount_id = "2d25a254-1707-4201-9a26-5309217850b1"
}
```
サブアカウントですでにSAP Build Work Zoneがサブスクライブ済みの場合、以下の`import`ブロックによりTerraformにリソースを取り込むことができます。

```tf
import {
  to = btp_subaccount_subscription.SAPLaunchpad
  id = "2d25a254-1707-4201-9a26-5309217850b1,SAPLaunchpad,standard"
}
```
ターミナルで`import`コマンドを実行しても同じ結果になります。
```
terraform import btp_subaccount_subscription.SAPLaunchpad 6aa64c2f-38c1-49a9-b2e8-cf9fea769b7f,SAPLaunchpad,standard
```

`import`で必要なパラメータについては、各リソースの[ドキュメント](https://registry.terraform.io/providers/SAP/btp/latest/docs/resources/subaccount_subscription#import)に記載されています。

### Terraform Exporter for SAP BTPは何をしてくれるか
既存のリソースを取り込むとき、importブロックのidに何を指定するか調べるのに手間がかかります。特に取り込みたいリソースが大量にある場合は大変です。そこでTerraform Exporter for SAP BTPは、指定されたサブアカウントにあるリソースを取得し（※）、Terraformでのリソース定義とimportブロックを自動で生成してくれます。

※対象となるのはTerraform provider for SAP BTPでサポートされ、かつインポートが可能なリソースのみ
https://github.com/SAP/terraform-provider-btp/blob/main/guides/IMPORT.md

## 実行のステップ
### 1. インストール
以下のページに従ってTerraform Exporter for SAP BTPをインストールします。

https://sap.github.io/terraform-exporter-btp/install/

私はWSL環境のため、以下の手順でインストールしました。

- バイナリをダウンロード
```
wget https://github.com/SAP/terraform-exporter-btp/releases/download/v0.1.0-beta2/btptf_0.1.0-beta2_linux_amd64 -O btptf
```

- 実行権限を付与
```
chmod +x btptf
```

- システムパスに移動
```
sudo mv btptf /usr/local/bin/
```

- インストールの確認
```
btptf --help
```

### 2. 環境変数の設定
以下の環境変数を設定します。

- `BTP_GLOBALACCOUNT` : BTPグローバルアカウントのサブドメイン
- `BTP_USERNAME` : BTPログイン用のユーザ
- `BTP_PASSWORD` : BTPログイン用のパスワード

```:例（linuxの場合）
export BTP_GLOBALACCOUNT=b0f2992ctrial-ga
export BTP_USERNAME=email
export BTP_PASSWORD=password
```

このほかの設定可能な環境変数については、ドキュメントを参照してください。

https://sap.github.io/terraform-exporter-btp/prerequisites/

### 3. 実行
Terraform Exporter for SAP BTPではインポートのために2つの方法が用意されています。

- **2ステップでのインポート**：最初にインポート対象リソースが含まれたJSONファイルを生成し、必要なリソースを編集したうえでTerraformのコードを生成する
- **1ステップでのインポート**：必要なリソースを指定して直接Terraformのコードを生成する

以下では、2ステップでのインポートの方法について紹介します。

- 任意のディレクトリを作成
```
mkdir terraform_exporter
cd terraform_exporter
```

- インポート対象リソースが含まれたJSONファイルを生成
```
btptf create-json - s <subaccount id>
```
デフォルトではインポート可能なすべてのリソースが含まれるJSONファイルが生成されます。ファイルを編集して、インポートしたいリソースのみが含まれる状態にします。

```json:例
{
  "BtpResources": [
    {
      "Name": "subaccount",
      "Values": [
        "trial"
      ]
    },
    {
      "Name": "subscriptions",
      "Values": [
        "sap-identity-services-onboarding_default",
        "hana-cloud-tools-trial_tools",
        "SAPLaunchpad_standard",
        "it-cpitrial05-prov_trial"
      ]
    },
    {
      "Name": "trust-configurations",
      "Values": [
        "sap.custom"
      ]
    },
    {
      "Name": "service-bindings",
      "Values": [
        "service-manager-key"
      ]
    },
    {
      "Name": "service-instances",
      "Values": [
        "service-manager_8c308b8a-6ec2-4ce6-b11f-a5f024d7fa8c"
      ]
    }
  ]
}
```

- Terraformコードを生成
```
btptf export-by-json -p <path to json file> -s <subaccount id>
```
しばらく待つと、以下のメッセージが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/4b932399-b664-ace7-c45e-d75f5d98d962.png)

`generated_configurations_<subaccount id>`というフォルダ配下にTerraformのコードが生成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/4f7fa576-64f3-90cd-bd1c-1f50a23222cd.png)

`btp_resources.tf`というファイルにリソースの定義があります。コメントを読むと、このファイルを使ってそのまま`terraform apply`するというよりも、自分で作成したTerraformの定義にこれらのリソースブロックをコピーして追加するという使い方を意図しているようです。

```tf

###
# Resource: BTP_SUBACCOUNT
###
# __generated__ by Terraform
# Please review these resources and move them into your main configuration files.

# __generated__ by Terraform from "2d25a254-1707-4201-9a26-5309217850b1"
resource "btp_subaccount" "trial" {
  beta_enabled = false
  description  = null
  labels       = null
  name         = "trial"
  parent_id    = "0305f4bb-3bf5-4740-a472-d8ab350a0022"
  region       = "us10"
  subdomain    = "b0f2992ctrial"
  usage        = "UNSET"
}
```
`*_import.tf`というファイルに、既存のリソースをTerraformに取り込むためのimportブロックが入っています。
```tf:btp_subaccount_subscription_import.tf
import {
  to = btp_subaccount_subscription.sap_identity_services_onboarding
  id = "2d25a254-1707-4201-9a26-5309217850b1,sap-identity-services-onboarding,default"
}
import {
  to = btp_subaccount_subscription.hana_cloud_tools_trial
  id = "2d25a254-1707-4201-9a26-5309217850b1,hana-cloud-tools-trial,tools"
}
import {
  to = btp_subaccount_subscription.SAPLaunchpad
  id = "2d25a254-1707-4201-9a26-5309217850b1,SAPLaunchpad,standard"
}
import {
  to = btp_subaccount_subscription.it_cpitrial05_prov
  id = "2d25a254-1707-4201-9a26-5309217850b1,it-cpitrial05-prov,trial"
}
```

### 4. Terraformコードの調整
`NextSteps.md`というファイルに後続の作業手順が記載されています。以下は日本語で要約した内容です。

1. **プロバイダのバージョン制約を確認**
provider.tfで指定されたバージョン制約を確認し、会社のルールに準拠しているか確認してください。最新バージョンを使用するのが推奨されます。

2. **リソース設定の整理**
`btp_resources.tf`にはすべてのリソース情報（省略可能なデータを含む）が記載されています。明示的に設定する必要のないオプション属性を削除して、コードを簡素化してください。

3. **変数の宣言**
`provider.tf`に以下の変数を設定することを推奨します：
グローバルアカウントのサブドメイン
サブアカウントID
必要に応じてリージョンなどのパラメータも追加

4. **依存関係の追加**
エクスポート時に依存関係は検出されないため、手動で追加してください。例えば、エンタイトルメントとサービス/サブスクリプション間の依存関係を指定する必要があります。

5. **状態ファイルの保存場所を設定**
設定の状態はリモートステートバックエンドに保存してください。対応する設定（例：`provider.tf`）を追加します。詳細はTerraformドキュメントを参照してください。

6. **インポートの検証**
`terraform plan`を実行してインポートが可能か確認します。計画結果に「インポートするリソース数」が表示されれば成功です。

### 5. terraform planを実行してみる
`terraform plan`を実行すると、Terraform定義によってどのような変更が加えられるのかを確認することができます。

```
# コードが生成されたディレクトリに移動
cd generated_configurations_<subaccount_id> 
# terraform planを実行
terraform plan
```
以下のような結果が表示されます。import以外の件数が0になっている（リソースに変更がない）ことが重要です。

```
Plan: 8 to import, 0 to add, 0 to change, 0 to destroy.
```

## 使ってみた感想
Terraform Exporter for SAP BTPは「きれいなTerraform」コードを生成するツールではなく、あくまでimportブロックを簡単に生成するツールだと思いました。新規にBTPをTerraformで管理したい場合は[btp-terraform-samples](https://github.com/SAP-samples/btp-terraform-samples)のリポジトリを参考にTerraformコードを作成し、そこに既存のリソースを追加するためTerraform Exporter for SAP BTPを使う（生成したimportブロックを自分のコードに取り込む）という使い方がよいのではないかと考えます。