2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

terraformerを使って複数のDatadog Organizationを統合する

Last updated at Posted at 2021-03-08

#概要
監視、モニタリングで使用している複数のDatadogの環境(Organization)がある。
これらを1つにOrganizationをまとめて管理しやすくしたい。

でも、、、全部手作業でやるのはめんどくs工数が掛かる!
そこでterraformを使って一気にできたらいいなぁなんて思ってやってみました。

#前提条件
Orgaqnizationは2つあり、以下のダッシュボードのみを持つ。
記事簡略化のためダッシュボード以外のリソースは持たないことにする。

また、各Organizationでは共通のメトリクスが取得できているものとする。
既存Datadogリソースのtf化については以下の方法が考えられた。

  1. 手動で全部書く
  2. terraform importでリソースを取得し、tfファイルに記載する
  3. terraformerというインポートツールを使用して自動インポートする

結果、3のterraformerを使用する方法を採用した。Datadog公式ページにて推奨されていることと、リソースが多い場合一括でimportできるので結果的に一番手間が少ないと判断したためである。

###Datadog環境(example)

  • Organizetion1: Yojo_Dog
    • resourse: Dog_moniter_dashboard
  • Organization2: Yojo_Cat
    • resourse: Cat_moniter_dashboard

今回は、Yojo_Cat環境のCat_moniter_dashboardをterraformerを使ってtfファイルとして出力し、Yojo_Dog環境にterraformからapplyすることで、2つのdashboardがある状態を作ります!:muscle: :innocent:

#使用ツール

  • Terraform: コンピュータやネットワークを自動構築するツール。Datadog用のモジュールが用意されているためDatadogの環境をコード化、自動化できる。

  • terraformer: 構築済みの既存リソース(AWSやDatadogなど)を読み取り、terraformのコードとして出力してくれるインポートツール

  • tfenv: 複数のTerraformバージョンを切り替えして使用できる管理ツール

#構築作業手順
###ツールのインストール、セットアップ
local環境は:apple:Mac:apple:向けとなります。:desktop:Widows:desktop:をお使いの方は~~Macを買ってください:relaxed:~~
WSLのUbuntuとかでできるんじゃないですかねぇ(投げやり)

####tfenvのインストール

#Terraformがインストールされている場合エラーになるので一旦消す
$ brew uninstall terraform

#tfenvをインストール
$ brew install tfenv

#tfenvの確認
$ tfenv --version
tfenv 2.2.0

####tfenvからterraformをインストール

今回はterraformer用にv0.13.6を使用します。

#tfenvからterraformをインストール
$ tfenv install 0.13.6

Installing Terraform v0.13.6
Downloading release tarball from https://releases.hashicorp.com/terraform/0.13.6/terraform_0.13.6_darwin_amd64.zip
##################################################################################################################### 100.0%
Downloading SHA hash file from https://releases.hashicorp.com/terraform/0.13.6/terraform_0.13.6_SHA256SUMS
No keybase install found, skipping OpenPGP signature verification
Archive:  tfenv_download.TOSAgI/terraform_0.13.6_darwin_amd64.zip
  inflating: /usr/local/Cellar/tfenv/2.2.0/versions/0.13.6/terraform
Installation of terraform v0.13.6 successful. To make this your default version, run 'tfenv use 0.13.6'

#インストールされたか確認
$ tfenv list
* 0.13.6 (set by /usr/local/Cellar/tfenv/2.2.0/version)

#インストールしたterraformバージョンを使用する
$ tfenv use 0.13.6

#terraformコマンドの確認
$ terraform --version
Terraform v0.13.6

####terraformerのインストール

$ brew install terraformer
$ terraformer version
Terraformer v0.8.10

###Datadogリソースをインポートする準備
terraformerでDatadogリソースをインポートするにはAPI KeyAPP Keyが必要になります。
以下手順で確認します。

####API Keyの確認

Datadogのコンソールにログインし、左のメニューからIntegrations → APIsを選択します。
以下画面に遷移しますので、API Keysを展開しKeyを控えておきます。

datadogapi.png

####APP Keyの確認

同様のページからApplication Keys have moved to the Teams pageを選択するとApp Keyの作成、確認ページに遷移します。
作成済みのKeyがあっても作成時に一度しかKeyは確認できないようです。
また、Key作成の際は自身のユーザの権限のみを持ちますので個人ではなく会社でやる際は偉い人を脅す確認しましょう。

+New Keyボタンを押すとKey作成されクリップボードにコピーすることができます。控えておいてください。

datadogapp.png

これでこのOrganizationからterraformerでtfファイルをインポートする準備ができました!!ヨシっ!!:smiley_cat: :point_right:

同様の手順でもう一つのOrganizationのKeyを控えておきます。

###terraformerの実行

####terraformの初期設定

まずはterraformを実行できるようにサクっと環境を作りましょう。


#実行ディレクトリの作成(自由に)
terraform
└── datadog

####main.tfの作成

Datadog公式ドキュメント通りに書いていきます。
api_key app_keyは__Datadogリソースをインポートする準備__で取得したリソースを書き出したい方のOrganizationのものを記載します。
この記事ではkeyを直接記載しますので間違えてgithubに公開しないように気をつけてくださいね:frowning2:

Yojo_CatのリソースをYojo_Dogに追加するので以下のようになります。

terraform/datadog/main.tf
terraform {
  required_providers {
    datadog = {
      source = "Datadog/datadog"
    }
  }
}

provider "datadog" {
  api_key = "Yojo_Dog_api_key"
  app_key = "Yojo_Dog_app_key"
}

####initする

Datadog用のprovidersをインストールするため、initします。

$ terraform init

Terraform has been successfully initialized!

####1つ目のOrganizationのリソースをterraformer importする

今回はdashboardだけですが、その他のリソースがある場合は--resorces=hoge,fuga,piyoとカンマ区切りで指定できます。
また、特定のリソースだけを出力する場合は--filter=dashboard=Dog_moniter_dashboardIDのように指定できます。1


#Yojo_Dog Organizationのリソースを出力
$ terraformer import datadog --resources=dashboard --api-key "Yojo_Dog_api_key" --app-key "Yojo_Dog_app_key"

2021/03/05 02:58:27 datadog importing... dashboard
2021/03/05 02:58:28 Refreshing state... datadog_dashboard.tfer--dashboard_<Dog_moniter_dashboardID>
2021/03/05 02:58:36 datadog Connecting....
2021/03/05 02:58:36 datadog save dashboard
2021/03/05 02:58:37 datadog save tfstate for dashboard

#generateディレクトリとファイルが出力される
./generated
└── datadog
    └── dashboard
        ├── dashboard.tf
        ├── outputs.tf
        ├── provider.tf
        └── terraform.tfstate

####2つ目のOrganizationのリソースをterraformer importする

このまま実行すると__なんと全部上書きされてしまいます・・・What's!?:scream:__
なので、別のディレクトリに一旦退避させましょう:sweat:

terraform
└── datadog
    ├── Yojo_Dog
    │   └── generated
    │       └── datadog
    │           └── dashboard
    │               ├── dashboard.tf
    │               ├── outputs.tf
    │               ├── provider.tf
    │               └── terraform.tfstate
    └── main.tf
#Yojo_Cat Organizationのリソースを出力
$ terraformer import datadog --resources=dashboard --api-key "Yojo_Cat_api_key" --app-key "Yojo_Cat_app_key"

2021/03/05 03:16:40 datadog importing... dashboard
2021/03/05 03:16:44 Refreshing state... datadog_dashboard.tfer--dashboard_<Cat_moniter_dashboardID>
2021/03/05 03:16:55 datadog save dashboard
2021/03/05 03:16:56 datadog save tfstate for dashboard

#generateディレクトリとファイルが出力される
.
├── Yojo_Dog
│   └── generated
│       └── datadog
│           └── dashboard
│               ├── dashboard.tf
│               ├── outputs.tf
│               ├── provider.tf
│               └── terraform.tfstate
├── generated
│   └── datadog
│       └── dashboard
│           ├── dashboard.tf
│           ├── outputs.tf
│           ├── provider.tf
│           └── terraform.tfstate
└── main.tf

#統一感だしていこ???笑笑笑
.
├── Yojo_Cat
()
├── Yojo_Dog

###リソースファイルの修正

出力したファイルはそのままでは使うことができません。これを使用するために2つのことをファイル追加修正します。

  1. tfファイルのバージョンアップを行う
  2. 競合するIDを削除する

####tfファイルのバージョンアップを行う
これはDatadog公式ドキュメントの手順で推奨されているので実行します。
terraformerでimportしたtfファイルのバージョンをv0.13.xに調整します。

#Yojo_Catに実行
$ pwd
/datadog/Yojo_Cat/datadog/dashboard

$ terraform 0.13upgrade .

Would you like to upgrade the module in the current directory?
  Only 'yes' will be accepted to confirm.

  Enter a value: yes #yesを入力してエンター

-----------------------------------------------------------------------------

Upgrade complete!

#なんか変わってる。まぁ任せた!!
$ git status
Changes not staged for commit:
	modified:   provider.tf

Untracked files:
  (use "git add <file>..." to include in what will be committed)
	versions.tf

#initする
$ terraform init
Terraform has been successfully initialized

.
├── dashboard.tf
├── outputs.tf
├── provider.tf
├── terraform.tfstate
└── versions.tf

#忘れずにYojo_Dogにも適用する
$ pwd
/terraform/datadog/Yojo_Dog/generated/datadog/dashboard

$ terraform 0.13upgrade .
$ terraform init

####競合するIDを削除する
terraformerの弱点の一つとして、リソースの固有IDまでtfファイルにもってきてしまうことです。
このままapplyしようとしても既存リソースと競合してしまいエラーとなります。

ちょっと状況を確認してみましょう。

$  terraform plan
Error: "widget.10.id": this field cannot be set
  on dashboard.tf line 125, in resource "datadog_dashboard" "tfer--dashboard_<dashboard_ID>":
 125: resource "datadog_dashboard" "tfer--dashboard_<dashboard_ID>" {

Error: "widget.10.id": this field cannot be set
.
.
.
.
echo '天才の僕「ぎゃーーー!!!!」'

・・・とご丁寧にどのリソースやウィジットがエラーになってるか書いているのでtfファイルを修正していきましょう:relaxed:
以下は"爆速なお仕事(笑)"が特技の筆者の方法です。

$ ls
dashboard.tf      outputs.tf        provider.tf       terraform.tfstate versions.tf

#伝説の武器、VSCodeを起動!!俺のターーーン!!!!!(エンターキーをターン!する)
$ code dashboard.tf

ID = .*$で検索してみると。。。
なんかいた!!!!これが入ってるとapplyできません。
全部いらないので置換で消しちゃいましょう。神経質な方は確認してから消しましょう。
筆者はできなきゃ戻せばいいやみたいな悪いエンジニアなのでそのまま全部置換:heart_eyes:

new_vscode.png

エラーが出なくなるまで特定して修正します。

$ terraform plan
Error: api_key and app_key must be set unless validate = false

上記は大丈夫なやつです。generated配下でplanしているのでキーがなくて正常です。
エラーが出なくなったらもう一つのOrganizationも修正しましょう。

:innocent: :interrobang:

$ terraform plan
Error: "widget": required field is not set
6731: resource "datadog_dashboard" "tfer--dashboard_<dashboard_ID>" {

見たところ、widgetが無いテストみたいなダッシュボードでした。
からっぽのdashboardはGUIから保存できてしまいますがコード上は許されていないようです。

ただファイルから削除しただけだとtfstateとの整合性が取れなくなりややこしくなります。
その辺りは、今回は触れません。

つまり、、、GUIから物理削除してimportしなおしました!
(exampleだとdashboardが1個になってますが、こういうエラーもあるよということで例外紹介でした)

###リソースを統合する
いよいよ最終章です。2つのOrganizatioのdashboardをおまとめして、Yojo_Dog環境を最強にします。

####ファイルの移動
importしたデータメインディレクトリに移動しましょう。
dashboard.t terraform.tfstate versions.tfが対象です。

$ pwd
/datadog/Yojo_Cat/datadog/dashboard

$ cp dashboard.tf terraform.tfstate versions.tf ../../../

.
├── Yojo_Cat
│   └── datadog
│       └── dashboard
│           ├── dashboard.tf
│           ├── outputs.tf
│           ├── provider.tf
│           ├── terraform.tfstate
│           └── versions.tf
├── Yojo_Dog
│   └── generated
│       └── datadog
│           └── dashboard
│               ├── dashboard.tf
│               ├── outputs.tf
│               ├── provider.tf
│               ├── terraform.tfstate
│               └── versions.tf
├── dashboard.tf
├── main.tf
├── terraform.tfstate
└── versions.tf

###planで内容を確認する。
注意:このログは良く確認してください。適当に実行してしまうと・・・
:star_and_crescent:破壊と創造:star_of_david:を行うシステム障害の神になりえます。
しっっかっかっかっかりとログを確認して念のため退職届を書いておきましょう。

#ファイルが増えているので一旦initしておく
$ terraform init
$ terraform plan

#変更のあるリソースを確認
datadog_dashboard.tfer--dashboard_<Cat_moniter_dashboard_ID>: Refreshing state... [id=Cat_moniter_dashboard_ID]

------------------------------------------------------------------------

#Createdのみなはず。deleteがあるなら要確認
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # datadog_dashboard.tfer--dashboard_<Cat_moniter_dashboard_ID> will be created
  + resource "datadog_dashboard" "<Cat_moniter_dashboard_ID>" {
      + dashboard_lists_removed = (known after apply)
      + description             = <<~EOT
            ## Overall
            Dashbord for
(略)
# +が追加される部分です。リソース、ウィジットなど変更点を確認しましょう。

#最後に変更点のカウントが出ます。
Plan: 1 to add, 0 to change, 0 to destroy.
------------------------------------------------------------------------

###applyする
ここまで問題がなければapplyすることでリソースの統合ができるはずです。
Yojo_DogにYojo_Catの全てをぶっこんであげましょう!!!:golf:

$ terraform apply
datadog_dashboard.tfer--dashboard_<Cat_moniter_dashboard_ID>: Refreshing state... [id=<Cat_moniter_dashboard_ID>]

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create
(略)

#実行するか聞かれるのでyesを入力します。
Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

Apply complete! Resources: 7 added, 0 changed, 0 destroyed.

Outputs:
datadog_dashboard_tfer--dashboard_<Cat_moniter_dashboard_ID>_id = datadog_dashboard.tfer--dashboard_<Cat_moniter_dashboard_ID>.id

Apply complete!が出ていれば成功です!お疲れ様でした:muscle::innocent:

###結果をGUIから確認する
ナイスー!!!!!
勝ち申した!!!!
datadog_apply.png


####Twitterやってます!エンジニアアカウントも音楽アカウントもフォローしてね:two_hearts::two_hearts::two_hearts::two_hearts::two_hearts:

  1. --filterで使用するIDはリソースのnameではなく個別にDatadogから振られているIDを使います。ブラウザから例えば対象のダッシュボードを開くとブラウザのURLにIDが表示されているのでそれを使用します。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?