既存のDigitalOceanアセットをTerraformにインポートする方法
著者は、 Write for DOnations プログラムの一環として、 Free and Open SourceFundを選択して寄付を受け取りました。
序章
Terraform は、 HashiCorp によって作成されたInfrastructure-as-Codeツールであり、開発者がインフラストラクチャのさまざまなアセットを効率的かつスケーラブルな方法で展開、更新、および削除するのに役立ちます。
開発者はTerraformを使用して、さまざまな環境を整理し、バージョン管理を通じて変更を追跡し、反復作業を自動化して人的エラーを制限できます。 また、共有構成を通じてインフラストラクチャの改善にチームが協力する方法も提供します。
このチュートリアルでは、既存のDigitalOceanインフラストラクチャをTerraformにインポートします。 このチュートリアルを終了すると、新しいアセットの作成に加えて、既存のすべてのインフラストラクチャにTerraformを使用できるようになります。
前提条件
- DigitalOceanパーソナルアクセストークン。DigitalOceanコントロールパネルから作成できます。 手順については、DigitalOcean製品ドキュメントパーソナルアクセストークンの作成方法を参照してください。
- タグ付きのDigitalOceanドロップレット。 DigitalOceanコントロールパネルからドロップレットを作成する方法で次のガイドを使用できます。 このチュートリアルでは、タグ
terraform-testing
を使用します。 - ドロップレットに適用されたDigitalOceanクラウドファイアウォール。 ガイドファイアウォールの作成方法を使用できます。 このチュートリアルでは、ファイアウォール名
testing-terraform-firewall
を使用します。 - ローカルマシンにインストールされたDigitalOceanコマンドラインクライアント。これは、doctlGitHubページのインストール手順に従って実行できます。 追加のガイダンスについては、チュートリアル Doctlの使用方法、公式のDigitalOceanコマンドラインクライアントを読むことができます。
このチュートリアルは、Terraform1.0.10を使用してテストされました。
ステップ1—Terraformをローカルにインストールする
この最初のステップでは、Terraformをローカルマシンにインストールします。 このステップでは、LinuxディストリビューションへのTerraformのインストールについて詳しく説明します。 WindowsまたはMacOSを使用している場合は、TerraformWebサイトのTerraformのダウンロードページを確認できます。
インストール手順は、HashiCorpのWebサイトに記載されています。
注:インターネットから直接ダウンロードしたオブジェクト/実行可能ファイルを同じコマンドでパイプ/実行することは通常悪い習慣ですが、HashiCorpは信頼できるソースであるため、ここでは例外を作成します。 これを行うことに不安がある場合は、最初にオブジェクトをダウンロードして検査し、すべてが良好に見える場合は先に進んでください。
Ubuntu20.04へのインストール
HashiCorpはリポジトリにデジタル署名するため、GNU Privacy Guard(GPG)キーを追加する必要があります。 これにより、リポジトリが実際にHashiCorpによって所有および保守されていることが合理的に保証されます。
curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
公式のHashiCorpリポジトリをシステムに追加します。
sudo apt-add-repository "deb [arch=$(dpkg --print-architecture)] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
Terraformをインストールします。
sudo apt update; sudo apt install terraform=1.0.10
Fedora34へのインストール
HashiCorpリポジトリを追加するには、リポジトリリストに追加する必要があります。 コアDNFプラグインconfig-manager
はこの目的で使用され、dnf-plugins-core
パッケージによって提供されます。 必要なdnf
プラグインをインストールします。
sudo dnf install -y dnf-plugins-core
公式のHashiCorpリポジトリをシステムに追加します。
sudo dnf config-manager --add-repo https://rpm.releases.hashicorp.com/fedora/hashicorp.repo
Terraformをインストールします。
sudo dnf install terraform-1.0.10-1
OSのインストール手順に従った後、バージョンを確認して、Terraformが正しくインストールされているかどうかを確認します。
terraform version
出力は次のようになります。
OutputTerraform v1.0.10 on linux_amd64
Terraformをローカルマシンにインストールしました。 次に、構成ファイルを準備します。
ステップ2—Terraform構成ファイルの準備
このステップでは、プロジェクトディレクトリを作成し、構成ファイルを書き込むことにより、既存のアセットをTerraformにインポートします。 現時点では、Terraformはimportコマンドからの構成の生成をサポートしていないため、これらの構成を手動で作成する必要があります。
次のコマンドを実行して、プロジェクトディレクトリを作成します。
mkdir -p do_terraform_import
次に、そのディレクトリに移動します。
cd do_terraform_import
新しいTerraformワークスペースを初期化します。
terraform workspace new do_terraform_import
新しく作成したワークスペースを使用しているかどうかを確認します。
terraform workspace list
出力は次のようになります。
Output default * do_terraform_import
このステップでは、必要な構成を含む3つの追加ファイルを作成します。 このプロジェクトのディレクトリ構造は次のようになります。
├── digitalocean_droplet.tf ├── digitalocean_firewall.tf ├── provider.tf ├── .terraform └── terraform.tfstate.d
まず、ファイルprovider.tf
を作成して、DigitalOceanアクセストークンを構成にハードコーディングするのではなく、環境変数として定義します。
警告:アクセストークンは、無制限のアクセスで完全なインフラストラクチャへのアクセスを提供するため、そのように扱います。 そのトークンが保存されているマシンにアクセスできるのはあなただけであることを確認してください。
アクセストークンに加えて、使用するプロバイダーも指定します。 このチュートリアルでは、それはdigitalocean
です。 Terraformを使用したDigitalOceanで利用可能なデータソースとリソースの完全なリストについては、Webサイトのプロバイダーページにアクセスしてください。
次のコマンドを使用して、provider.tf
を作成および編集します。
nano provider.tf
次のコンテンツをprovider.tf
ファイルに追加します。
プロバイダー.tf
terraform { required_providers { digitalocean = { source = "digitalocean/digitalocean" version = "2.15.0" } } } variable "do_token" {} provider "digitalocean" { token = var.do_token }
このファイルでは、DigitalOceanアクセストークンを変数として追加します。これは、TerraformがDigitalOceanAPIのIDとして使用します。 DigitalOceanプロバイダープラグインのバージョンも指定します。 Terraformは、将来の更新によって現在の設定が損なわれないように、使用しているプロバイダーのバージョンを指定することをお勧めします。
ファイルを保存して閉じます。
次に、digitalocean_droplet.tf
ファイルを作成します。 ここでは、使用するリソース(この場合はdroplet
)を指定します。
このファイルは、後の手順でTerraform状態で正常にインポートするために、既存のリソースを複製する必要があります。
次のコマンドでファイルを作成します。
nano digitalocean_droplet.tf
次の構成を追加し、必要に応じて既存のリソースと一致するように更新します。
digitalocean_droplet.tf
resource "digitalocean_droplet" "do_droplet" { name = "testing-terraform" region = "fra1" tags = ["terraform-testing"] count = "1" }
ここでは、既存のリソースと一致する必要がある4つのパラメーターを指定します。
name
:ドロップレット名。region
:ドロップレットが配置されている領域。tags
:このドロップレットに適用されるタグのリスト。count
:この構成に必要なリソースの数。
ファイルを保存して閉じます。
次に、ファイアウォールの構成ファイルを作成します。 次のコマンドを使用して、ファイルdigitalocean_firewall.tf
を作成します。
nano digitalocean_firewall.tf
次のコンテンツをファイルに追加します。
digitalocean_firewall.tf
resource "digitalocean_firewall" "do_firewall" { name = "testing-terraform-firewall" tags = ["terraform-testing"] }
ここでは、インポートするファイアウォールの名前と、ファイアウォールルールが適用されるドロップレットのタグを指定します。
ファイルを保存して閉じます。
注:digitalocean_droplet.tf
ファイルにファイアウォールリソースを含めることもできます。 ただし、複数のドロップレットが同じファイアウォールを共有する複数の環境がある場合、単一のドロップレットのみを削除する場合は、それらを分離することをお勧めします。 これにより、ファイアウォールは影響を受けません。
次に、これらの変更を初期化して、Terraformが必要な依存関係をダウンロードできるようにします。 これにはterraform init
コマンドを使用します。これにより、Terraform構成ファイルを含む作業ディレクトリを初期化できます。
プロジェクトディレクトリから次のコマンドを実行します。
terraform init
次の出力が表示されます。
OutputTerraform has been successfully initialized!
Terraformは、プラグインのダウンロード、モジュールの検索などにより、作業ディレクトリを正常に準備しました。 次に、Terraformへのアセットのインポートを開始します。
ステップ3—アセットをTerraformにインポートする
このステップでは、DigitalOceanアセットをTerraformにインポートします。 アセットをインポートする前に、doctl
を使用してドロップレットのID番号を検索します。 次に、terraform show
およびterraform plan
コマンドを使用してインポート構成を確認します。
まず、DigitalOceanアクセストークンを環境変数としてエクスポートし、実行時にTerraformに挿入します。
次のコマンドを使用して、環境変数として現在のシェルセッションにエクスポートします。
export DO_TOKEN="YOUR_TOKEN"
既存のドロップレットとファイアウォールをインポートするには、それらのID番号が必要です。 DigitalOceanAPIのコマンドラインインターフェイスであるdoctl
を使用できます。
次のコマンドを実行して、ドロップレットを一覧表示し、それらのIDにアクセスします。
doctl compute droplet list
次のような出力が表示されます。
OutputID Name Public IPv4 DROPLET-ID DROPLET-NAME DROPLET-IPv4 DROPLET-ID DROPLET-NAME DROPLET-IPv4 DROPLET-ID DROPLET-NAME DROPLET-IPv4
後のコマンドで必要になるため、インポートするリソースのドロップレットIDをメモします。
次に、次のコマンドを実行してファイアウォールを一覧表示し、ファイアウォールのIDにアクセスします。
doctl compute firewall list
次のような出力が表示されます。
OutputID Name Status FIREWALL-ID FIREWALL-NAME succeeded
後のコマンドで必要になるため、インポートするリソースのファイアウォールIDをメモします。
DROPLET-ID をドロップレットのIDに置き換えて、既存のドロップレットをTerraformにインポートします。
terraform import -var "do_token=${DO_TOKEN}" digitalocean_droplet.do_droplet DROPLET-ID
-var
フラグを使用して、以前にシェルセッションにエクスポートしたDigitalOceanアクセストークン値を指定します。 これは、DigitalOcean APIがユーザーを確認し、インフラストラクチャに変更を適用できるようにするために必要です。
次に、ファイアウォールに対して同じコマンドを実行し、 FIREWALLIDをファイアウォールのIDに置き換えます。
terraform import -var "do_token=${DO_TOKEN}" digitalocean_firewall.do_firewall FIREWALL-ID
terraform show
コマンドを使用して、インポートが成功したことを確認します。 このコマンドは、インフラストラクチャの状態を人間が読める形式で出力します。 計画を検査して、必要な変更が実行されることを確認したり、Terraformが認識している現在の状態を検査したりするために使用できます。
このコンテキストでは、 state は、DigitalOceanアセットの作成したTerraform構成へのマッピング、およびメタデータの追跡を指します。 これにより、インポートする既存のDigitalOceanアセットと、Terraformが追跡しているアセットの間に違いがないことを確認できます。
terraform show
出力は次のようになります。
Output. . . # digitalocean_droplet.do_droplet: resource "digitalocean_droplet" "do_droplet" { backups = false created_at = "2020-02-03T16:12:02Z" disk = 25 id = "DROPLET-ID" image = "DROPLET-IMAGE" ipv4_address = "DROPLET-IP" ipv6 = false locked = false memory = 1024 monitoring = false name = "testing-terraform-0" price_hourly = 0.00744 price_monthly = 5 private_networking = false region = "fra1" resize_disk = true size = "s-1vcpu-1gb" status = "active" tags = [ "terraform-testing", ] urn = "DROPLET-URN" vcpus = 1 volume_ids = [] . . . }
出力には、属性とともに2つのリソースが表示されます。
ドロップレットとファイアウォールをTerraform状態にインポートした後、構成がインポートされたアセットの現在の状態を表していることを確認する必要があります。 これを行うには、ドロップレットのimage
とそのsize
を指定します。 これらの2つの値は、digitalocean_droplet.do_droplet
リソースのterraform show
の出力にあります。
digitalocean_droplet.tf
ファイルを開きます。
nano digitalocean_droplet.tf
このチュートリアルでは:
- 既存のドロップレットに使用されているオペレーティングシステムイメージは
ubuntu-20-04-x64
です。 - ドロップレットが配置されている領域は
fra1
です。 - 既存のドロップレットのドロップレットタグは
terraform-testing
です。
注:オペレーティングシステム、リージョン、ドロップレットのサイズ、およびその他のリソースは異なる場合があります。値を反映するようにファイルを更新してください。
digitalocean_droplet.tf
の構成が、インポートされたドロップレットの現在の状態と一致することを確認するには、次のように更新する必要があります。
digitalocean_droplet.tf
resource "digitalocean_droplet" "do_droplet" { image = "ubuntu-20-04-x64" name = "testing-terraform" region = "fra1" size = "s-1vcpu-1gb" tags = ["terraform-testing"] }
必要に応じて、インポートしたドロップレットに一致するように構成を更新します。
次に、ファイアウォールルールを追加します。 この例では、インバウンドトラフィック用に開いているポートは、22
、80
、および443
です。 すべてのポートはアウトバウンドトラフィック用に開かれています。 開いているポートに応じて、この構成を調整できます。
digitalocean_firewall.tf
を開きます:
nano digitalocean_firewall.tf
次の構成を追加します。
digitalocean_firewall.tf
resource "digitalocean_firewall" "do_firewall" { name = "testing-terraform-firewall" tags = ["terraform-testing"] inbound_rule { protocol = "tcp" port_range = "22" source_addresses = ["0.0.0.0/0", "::/0"] } inbound_rule { protocol = "tcp" port_range = "80" source_addresses = ["0.0.0.0/0", "::/0"] } inbound_rule { protocol = "tcp" port_range = "443" source_addresses = ["0.0.0.0/0", "::/0"] } outbound_rule { protocol = "tcp" port_range = "all" destination_addresses = ["0.0.0.0/0", "::/0"] } outbound_rule { protocol = "udp" port_range = "all" destination_addresses = ["0.0.0.0/0", "::/0"] } outbound_rule { protocol = "icmp" destination_addresses = ["0.0.0.0/0", "::/0"] } }
これらのルールは、既存のファイアウォールの例の状態を複製します。 トラフィックを異なるIPアドレス、異なるポート、または異なるプロトコルに制限する場合は、ファイルを調整して既存のファイアウォールを複製できます。
ファイルを保存して閉じます。
Terraformファイルを更新したら、plan
コマンドを使用して、行った変更がDigitalOceanの既存のアセットの状態を複製しているかどうかを確認します。
terraform plan
コマンドはドライランとして使用されます。 このコマンドを使用すると、Terraformが行う変更が必要な変更であるかどうかを確認できます。 変更を適用する前に、確認のためにこのコマンドを常に実行することをお勧めします。
次のコマンドでterraform plan
を実行します。
terraform plan -var "do_token=$DO_TOKEN"
変更が検出されない場合、出力は次のようになります。
OutputNo changes. Infrastructure is up-to-date.
変更が検出されると、Terraformの出力に変更が表示され、それに応じて確認および調整できます。
Terraformに既存のDigitalOceanアセットを正常にインポートしました。これで、既存のアセットを誤って削除または変更するリスクなしに、Terraformを介してインフラストラクチャに変更を加えることができます。
ステップ4—Terraformを介して新しいアセットを作成する
このステップでは、既存のインフラストラクチャに2つのドロップレットを追加します。 この方法で既存のインフラストラクチャにアセットを追加すると、たとえば、ライブWebサイトがあり、作業中にそのWebサイトに重大な変更を加える可能性がない場合に役立ちます。 代わりに、開発環境として使用するドロップレットを追加し、潜在的なリスクなしに、本番ドロップレットと同じ環境でプロジェクトに取り組むことができます。
digitalocean_droplet.tf
を開いて、新しいドロップレットのルールを追加します。
nano digitalocean_droplet.tf
強調表示された行をファイルに追加します。
digitalocean_droplet.tf
resource "digitalocean_droplet" "do_droplet" { image = "ubuntu-20-04-x64" name = "testing-terraform" region = "fra1" size = "s-1vcpu-1gb" tags = ["terraform-testing"] count = "1" } resource "digitalocean_droplet" "do_droplet_new" { image = "ubuntu-20-04-x64" name = "testing-terraform-${count.index}" region = "fra1" size = "s-1vcpu-1gb" tags = ["terraform-testing"] count = "2" }
count
メタ引数を使用して、同じ仕様のドロップレットがいくつ必要かをTerraformに伝えることができます。 これらの新しいドロップレットは、ファイアウォールと同じタグを指定すると、既存のファイアウォールにも追加されます。
次のルールを適用して、digitalocean_droplet.tf
で指定している変更を確認します。
terraform plan -var "do_token=$DO_TOKEN"
加えたい変更がこのコマンドの出力に複製されていることを確認します。
次のような出力が表示されます。
. . . [secondary_label Output] # digitalocean_droplet.do_droplet_new[1] will be created + resource "digitalocean_droplet" "do_droplet_new" { + backups = false + created_at = (known after apply) + disk = (known after apply) + id = (known after apply) + image = "ubuntu-20-04-x64" + ipv4_address = (known after apply) + ipv4_address_private = (known after apply) + ipv6 = false + ipv6_address = (known after apply) + ipv6_address_private = (known after apply) + locked = (known after apply) + memory = (known after apply) + monitoring = false + name = "testing-terraform-1" + price_hourly = (known after apply) + price_monthly = (known after apply) + private_networking = true + region = "fra1" + resize_disk = true + size = "s-1vcpu-1gb" + status = (known after apply) + tags = [ + "terraform-testing", ] + urn = (known after apply) + vcpus = (known after apply) + volume_ids = (known after apply) } Plan: 2 to add, 1 to change, 0 to destroy.
出力に満足したら、terraform apply
コマンドを使用して、指定した変更を構成の状態に適用します。
terraform apply -var "do_token=$DO_TOKEN"
コマンドラインでyes
と入力して、変更を確認します。 正常に実行されると、次のような出力が表示されます。
Output. . . digitalocean_droplet.do_droplet_new[1]: Creating... digitalocean_droplet.do_droplet_new[0]: Creating... digitalocean_firewall.do_firewall[0]: Modifying... [id=FIREWALL-ID] digitalocean_firewall.do_firewall[0]: Modifications complete after 1s [id=FIREWALL-ID] digitalocean_droplet.do_droplet_new[0]: Still creating... [10s elapsed] digitalocean_droplet.do_droplet_new[1]: Still creating... [10s elapsed] digitalocean_droplet.do_droplet_new[0]: Creation complete after 16s [id=DROPLET-ID] digitalocean_droplet.do_droplet_new[1]: Still creating... [20s elapsed] digitalocean_droplet.do_droplet_new[1]: Creation complete after 22s [id=DROPLET-ID] Apply complete! Resources: 2 added, 1 changed, 0 destroyed.
DigitalOceanWebパネルに2つの新しいドロップレットが表示されます。
また、既存のファイアウォールに接続されていることもわかります。
既存のアセットを使用して、Terraformで新しいアセットを作成しました。 これらのアセットを破棄する方法を学ぶために、オプションで次のステップを完了することができます。
ステップ5—インポートおよび作成されたアセットの破棄(オプション)
このステップでは、Terraformのdestroy
オプションを使用してインポートおよび作成したアセットを破棄します。
Terraformによって処理されるアセットを破棄するには、次のコマンドを実行します。
terraform destroy -var "do_token=${DO_TOKEN}"
Terraformは、ドロップレットとファイアウォールを破棄するかどうかを確認するように求めます。 これにより、Terraformを介してインポートおよび作成したすべてのアセットが破棄されるため、yes
と入力する前に続行することを確認してください。
出力は次のようになります。
Output. . . digitalocean_droplet.do_droplet[0]: Destroying... [id=YOUR-DROPLET-ID]] digitalocean_droplet.do_droplet_new[0]: Destroying... [id=YOUR-DROPLET-ID] digitalocean_droplet.do_droplet_new[1]: Destroying... [id=YOUR-DROPLET-ID] digitalocean_firewall.do_firewall[0]: Destroying... [id=YOUR-FIREWALL-ID] digitalocean_firewall.do_firewall[0]: Destruction complete after 1s digitalocean_droplet.do_droplet_new[1]: Still destroying... [id=YOUR-DROPLET-ID, 10s elapsed] digitalocean_droplet.do_droplet[0]: Still destroying... [id=YOUR-DROPLET-ID, 10s elapsed] digitalocean_droplet.do_droplet_new[0]: Still destroying... [id=YOUR-DROPLET-ID, 10s elapsed] digitalocean_droplet.do_droplet_new[1]: Still destroying... [id=YOUR-DROPLET-ID, 20s elapsed] digitalocean_droplet.do_droplet_new[0]: Still destroying... [id=YOUR-DROPLET-ID, 20s elapsed] digitalocean_droplet.do_droplet[0]: Still destroying... [id=YOUR-DROPLET-ID, 20s elapsed] digitalocean_droplet.do_droplet_new[1]: Destruction complete after 22s digitalocean_droplet.do_droplet[0]: Destruction complete after 22s digitalocean_droplet.do_droplet_new[0]: Destruction complete after 22s Apply complete! Resources: 0 added, 0 changed, 4 destroyed.
Terraformによって管理されているすべてのアセットが正常に削除されました。
結論
このチュートリアルでは、Terraformをインストールし、既存のアセットをインポートし、新しいアセットを作成し、オプションでそれらのアセットを破棄しました。 このワークフローは、本番環境に対応したKubernetesクラスターのデプロイなど、より大きなプロジェクトに拡張できます。 Terraformを使用すると、すべてのノード、DNSエントリ、ファイアウォール、ストレージ、およびその他の資産を管理できるだけでなく、バージョン管理を使用して変更を追跡し、チームと協力することができます。
追加のTerraform機能を調べるには、ドキュメントをお読みください。 また読むことができます DigitalOceanのTerraformコンテンツさらなるチュートリアルとQ&Aのために。