序章

Terraform プロジェクトをユースケースに応じて適切に構成し、認識された複雑さは、日常業務での保守性と拡張性を確保するために不可欠です。 プロジェクトを展開中にスケーラブルに保ち、ユーザーとチームが使用できるようにするには、コードファイルを適切に整理するための体系的なアプローチが必要です。

このチュートリアルでは、Terraformプロジェクトをその一般的な目的と複雑さに応じて構造化する方法について学習します。 次に、Terraformのより一般的な機能(変数、ローカル、データソース、プロビジョナー)を使用して、単純な構造のプロジェクトを作成します。 最終的に、プロジェクトはDigitalOceanにUbuntu 20.04サーバー(ドロップレット)をデプロイし、Apache Webサーバーをインストールして、ドメインをWebサーバーにポイントします。

前提条件

  • DigitalOceanパーソナルアクセストークン。DigitalOceanコントロールパネルから作成できます。 手順については、DigitalOcean製品ドキュメントパーソナルアクセストークンの作成方法を参照してください。

  • DigitalOceanアカウントに追加されたパスワードなしのSSHキー。これは、DigitalOceanDropletsでSSHキーを使用する方法に従って作成できます。

  • ローカルマシンにインストールされたTerraform。 オペレーティングシステムに応じた手順については、DigitalOceanチュートリアルでTerraformを使用する方法のステップ1を参照してください。

  • ローカルマシンにインストールされたPython3。 お使いのOS用のPython3のローカルプログラミング環境をインストールおよびセットアップする方法のステップ1を完了することができます。

  • DigitalOceanアカウントに追加された完全に登録されたドメイン名。 その方法については、公式ドキュメントにアクセスしてください。

注:このチュートリアルは、Terraform1.0.2で特別にテストされています。

Terraformプロジェクトの構造を理解する

このセクションでは、Terraformがプロジェクトと見なすもの、インフラストラクチャコードを構造化する方法、およびどのアプローチを選択するかについて学習します。 また、Terraformワークスペース、それらの機能、およびTerraformが状態を保存する方法についても学習します。

resource は、指定および推測されたプロパティに従って作成されたTerraformコードで宣言されたクラウドサービス(DigitalOcean Dropletなど)のエンティティです。 複数のリソースは、相互に接続されたインフラストラクチャを形成します。

Terraformは、インフラストラクチャを定義するために、 Hashicorp Configuration Language (HCL)と呼ばれる特殊なプログラミング言語を使用します。 HCLコードは通常、拡張子tfで終わるファイルに保存されます。 Terraformプロジェクトは、tfファイルを含み、initコマンドを使用して初期化されたディレクトリです。このコマンドはTerraformキャッシュとデフォルトのローカル状態を設定します。

Terraform state は、クラウドに実際にデプロイされているリソースを追跡するためのメカニズムです。 状態は、最適な冗長性と信頼性を実現するために、バックエンド(ローカルではディスク上、リモートではファイルストレージクラウドサービスまたは専用の状態管理ソフトウェア)に保存されます。 さまざまなバックエンドの詳細については、Terraformのドキュメントを参照してください。

プロジェクトworkspacesを使用すると、同じバックエンドに複数の状態を設定し、同じ構成に関連付けることができます。 これにより、同じインフラストラクチャの複数の異なるインスタンスをデプロイできます。 各プロジェクトは、defaultという名前のワークスペースで始まります。これは、明示的に作成したり、別のプロジェクトに切り替えたりしない場合に使用されます。

TerraformのModules(他のプログラミング言語のライブラリに似ています)は、複数のリソース宣言を囲むパラメーター化されたコードコンテナーです。 これらを使用すると、インフラストラクチャの共通部分を抽象化し、後でさまざまな入力で再利用できます。

Terraformプロジェクトには、動的データ入力で使用する外部コードファイルを含めることもできます。これにより、CLIコマンドの JSON出力を解析し、リソース宣言で使用できるようになります。 このチュートリアルでは、Pythonスクリプトを使用してこれを行います。

Terraformプロジェクトの構成がわかったところで、Terraformプロジェクトの構造化に対する2つの一般的なアプローチを確認しましょう。

シンプルな構造

単純な構造は、さまざまなタイプと変数のリソースがいくつかある、小規模なテストプロジェクトに適しています。 いくつかの構成ファイルがあり、通常はリソースタイプごとに1つ(またはメインと一緒にヘルパーファイルが多い)、カスタムモジュールはありません。これは、ほとんどのリソースが一意であり、一般化して再利用するのに十分ではないためです。 これに続いて、ほとんどのコードは同じディレクトリに隣り合って保存されます。 これらのプロジェクトには、多くの場合、いくつかの変数(クラウドにアクセスするためのAPIキーなど)があり、目立つわけではありませんが、動的データ入力やその他のTerraformおよびHCL機能を使用する場合があります。

このアプローチのファイル構造の例として、このチュートリアルでビルドするプロジェクトは、最終的に次のようになります。

.
└── tf/
    ├── versions.tf
    ├── variables.tf
    ├── provider.tf
    ├── droplets.tf
    ├── dns.tf
    ├── data-sources.tf
    └── external/
        └── name-generator.py

このプロジェクトはApacheWebサーバーのDropletをデプロイし、DNSレコードを設定するため、プロジェクト変数の定義、DigitalOcean Terraformプロバイダー、Droplet、およびDNSレコードがそれぞれのファイルに保存されます。 最低限必要なTerraformおよびDigitalOceanプロバイダーのバージョンはversions.tfで指定され、Dropletの名前を生成する(そしてdata-sources.tfで動的データソースとして使用される)Pythonスクリプトはexternalフォルダーに保存され、HCLコードから分離されます。

複雑な構造

単純な構造とは異なり、このアプローチは、通常のコードとは別に、さまざまなレベルの複雑さの複数のモジュールを含む明確に定義されたサブディレクトリ構造を持つ大規模なプロジェクトに適しています。 これらのモジュールは相互に依存できます。 これらのプロジェクトは、バージョン管理システムと組み合わせることで、ワークスペースを広範囲に使用できます。 このアプローチは、コードを可能な限り再利用しながら、複数のアプリを管理する大規模なプロジェクトに適しています。

開発、ステージング、品質保証、および本番インフラストラクチャインスタンスは、共通のモジュールに依存することにより、同じプロジェクトの下で異なるディレクトリに格納することもできます。これにより、重複するコードが排除され、プロジェクトが信頼できる唯一の情報源になります。 以下は、複数のデプロイメントアプリ、Terraformモジュール、およびターゲットクラウド環境を含む、より複雑な構造のサンプルプロジェクトのファイル構造です。

.
└── tf/
    ├── modules/
    │   ├── network/
    │   │   ├── main.tf
    │   │   ├── dns.tf
    │   │   ├── outputs.tf
    │   │   └── variables.tf
    │   └── spaces/
    │       ├── main.tf
    │       ├── outputs.tf
    │       └── variables.tf
    └── applications/
        ├── backend-app/
        │   ├── env/
        │   │   ├── dev.tfvars
        │   │   ├── staging.tfvars
        │   │   ├── qa.tfvars
        │   │   └── production.tfvars
        │   └── main.tf
        └── frontend-app/
            ├── env/
            │   ├── dev.tfvars
            │   ├── staging.tfvars
            │   ├── qa.tfvars
            │   └── production.tfvars
            └── main.tf

このアプローチは、シリーズTerraformを使用してインフラストラクチャを管理する方法でさらに詳しく説明されています。

これで、Terraformプロジェクトとは何か、認識された複雑さに応じてプロジェクトを最適に構成する方法、およびTerraformワークスペースが果たす役割を理解できました。 次の手順では、Apache Webサーバーがインストールされ、ドメインにDNSレコードが設定されたドロップレットをプロビジョニングする単純な構造のプロジェクトを作成します。 最初にDigitalOceanプロバイダーと変数を使用してプロジェクトを初期化し、次にDroplet、その名前を提供する動的データソース、および展開用のDNSレコードの定義に進みます。

ステップ1—最初のプロジェクトを設定する

このセクションでは、DigitalOcean Terraformプロバイダーをプロジェクトに追加し、プロジェクト変数を定義し、DigitalOceanプロバイダーインスタンスを宣言して、Terraformがアカウントに接続できるようにします。

次のコマンドを使用して、Terraformプロジェクトのディレクトリを作成することから始めます。

  1. mkdir ~/apache-droplet-terraform

そこに移動します:

  1. cd ~/apache-droplet-terraform

このプロジェクトは単純な構造化アプローチに従うため、前のセクションのファイル構造に従って、プロバイダー、変数、ドロップレット、およびDNSレコードコードを別々のファイルに保存します。 まず、DigitalOceanTerraformプロバイダーを必須プロバイダーとしてプロジェクトに追加する必要があります。

versions.tfという名前のファイルを作成し、次のコマンドを実行して編集用に開きます。

  1. nano versions.tf

次の行を追加します。

〜/ apache-droplet-terraform / versions.tf
terraform {
  required_providers {
    digitalocean = {
      source = "digitalocean/digitalocean"
      version = "~> 2.0"
    }
  }
}

このterraformブロックには、必要なプロバイダー(DigitalOcean、バージョン2.x)がリストされています。 完了したら、ファイルを保存して閉じます。

次に、プロジェクトが公開する変数をvariables.tfファイルで定義し、さまざまなリソースタイプを個別のコードファイルに保存する方法に従います。

  1. nano variables.tf

次の変数を追加します。

〜/ apache-droplet-terraform / variables.tf
variable "do_token" {}
variable "domain_name" {}

ファイルを保存して閉じます。

do_token変数はDigitalOceanパーソナルアクセストークンを保持し、domain_nameは目的のドメイン名を指定します。 デプロイされたドロップレットには、SSHフィンガープリントで識別されるSSHキーが自動的にインストールされます。

次に、このプロジェクトのDigitalOceanプロバイダーインスタンスを定義しましょう。 provider.tfという名前のファイルに保存します。 次のコマンドを実行して、編集用に作成して開きます。

  1. nano provider.tf

プロバイダーを追加します。

〜/ apache-droplet-terraform /provider.tf
provider "digitalocean" {
  token = var.do_token
}

完了したら、保存して終了します。 digitaloceanプロバイダーを定義しました。これは、provider.tfで前に指定した必須プロバイダーに対応し、そのトークンを実行時に提供される変数の値に設定します。

このステップでは、プロジェクトのディレクトリを作成し、DigitalOceanプロバイダーを使用可能にするように要求し、プロジェクト変数を宣言し、後で提供される認証トークンを使用するようにDigitalOceanプロバイダーインスタンスへの接続を設定しました。 次に、プロジェクト定義の動的データを生成するスクリプトを作成します。

ステップ2—動的データ用のPythonスクリプトを作成する

ドロップレットの定義に進む前に、ドロップレットの名前を動的に生成し、それを解析するためのデータソースリソースを宣言するPythonスクリプトを作成します。 この名前は、定数文字列(web)を、UNIXエポック形式で表されるローカルマシンの現在の時刻と連結することによって生成されます。 ネーミングスクリプトは、ネーミングスキームに従って複数のドロップレットを生成する場合に、それらを簡単に区別するために役立ちます。

スクリプトは、name-generator.pyという名前のファイルのexternalという名前のディレクトリに保存します。 まず、次のコマンドを実行してディレクトリを作成します。

  1. mkdir external

externalディレクトリはプロジェクトのルートにあり、作成するPythonスクリプトなどの非HCLコードファイルを保存します。

externalの下にname-generator.pyを作成し、編集用に開きます。

  1. nano external/name-generator.py

次のコードを追加します。

external / name-generator.py
import json, time

fixed_name = "web"
result = {
  "name": f"{fixed_name}-{int(time.time())}",
}

print(json.dumps(result))

このPythonスクリプトは、jsonおよびtimeモジュールをインポートし、resultという名前の辞書を宣言し、nameキーの値を設定します。 fixed_nameをそれが実行されているマシンの現在のUNIX時間と組み合わせた補間文字列に変換します。 次に、resultがJSONに変換され、stdoutに出力されます。 スクリプトが実行されるたびに、出力は異なります。

Output
{"name": "web-1597747959"}

完了したら、ファイルを保存して閉じます。

注:大規模で複雑な構造化プロジェクトでは、特に移植性とエラー処理の観点から、外部データソースの作成方法と使用方法についてさらに検討する必要があります。 Terraformは、実行されたプログラムが人間が読めるエラーメッセージをstderrに書き込み、ゼロ以外のステータスで正常に終了することを期待しています。これは、タスクが単純なため、このステップでは示されていません。 さらに、プログラムに副作用がないことを期待しているため、必要な回数だけ再実行できます。

Terraformが期待することの詳細については、データソースの公式ドキュメントにアクセスしてください。

スクリプトの準備ができたので、スクリプトからデータをプルするデータソースを定義できます。 単純な構造化アプローチに従って、プロジェクトのルートにあるdata-sources.tfという名前のファイルにデータソースを保存します。

次のコマンドを実行して、編集用に作成します。

  1. nano data-sources.tf

次の定義を追加します。

〜/ apache-droplet-terraform / data-sources.tf
data "external" "droplet_name" {
  program = ["python3", "${path.module}/external/name-generator.py"]
}

ファイルを保存して閉じます。

このデータソースはdroplet_nameと呼ばれ、作成したexternalディレクトリにあるPython3を使用してname-generator.pyスクリプトを実行します。 出力を自動的に解析し、他のリソース定義内で使用するために、result属性の下に逆シリアル化されたデータを提供します。

データソースが宣言されたら、Apacheを実行するドロップレットを定義できます。

ステップ3—ドロップレットを定義する

このステップでは、Dropletリソースの定義を記述し、単純な構造化アプローチに従って、Droplets専用のコードファイルに保存します。 その名前は、作成したばかりの動的データソースに由来し、デプロイされるたびに異なります。

droplets.tfファイルを作成して開き、編集します。

  1. nano droplets.tf

次のDropletリソース定義を追加します。

〜/ apache-droplet-terraform / droplets.tf
data "digitalocean_ssh_key" "ssh_key" {
  name = "your_ssh_key_name"
}

resource "digitalocean_droplet" "web" {
  image  = "ubuntu-20-04-x64"
  name   = data.external.droplet_name.result.name
  region = "fra1"
  size   = "s-1vcpu-1gb"
  ssh_keys = [
    data.digitalocean_ssh_key.ssh_key.id
  ]
}

最初に、ssh_keyと呼ばれるDigitalOceanSSHキーリソースを宣言します。これにより、アカウントからその名前でキーがフェッチされます。 強調表示されたコードをSSHキー名に置き換えてください。

次に、webというDropletリソースを宣言します。 droplet_name外部データソースからリクエストされているため、クラウドでの実際の名前は異なります。 デプロイされるたびにSSHキーを使用してDropletリソースをブートストラップするために、ssh_keyのIDがssh_keysパラメーターに渡され、DigitalOceanが適用するキーを認識できるようになります。

今のところ、droplet.tfに関連して構成する必要があるのはこれだけなので、完了したらファイルを保存して閉じます。

ここで、宣言されたばかりのドロップレットをドメインにポイントするDNSレコードの構成を記述します。

ステップ4—DNSレコードを定義する

プロセスの最後のステップは、ドメインからのドロップレットを指すDNSレコードを構成することです。

DNS構成は、前の手順で作成した他のリソースタイプとは別のリソースタイプであるため、dns.tfという名前のファイルに保存します。 編集のために作成して開きます。

  1. nano dns.tf

次の行を追加します。

〜/ apache-droplet-terraform / dns.tf
resource "digitalocean_record" "www" {
  domain = var.domain_name
  type   = "A"
  name   = "@"
  value  = digitalocean_droplet.web.ipv4_address
}

このコードは、Aタイプのドメイン名(変数を使用して渡される)でDigitalOceanDNSレコードを宣言します。 レコードの名前は@です。これは、ドメイン自体へのプレースホルダールーティングであり、ドロップレットIPアドレスをvalueとして使用します。 nameの値を別の値に置き換えると、サブドメインが作成されます。

完了したら、ファイルを保存して閉じます。

ドロップレット、名前ジェネレーターのデータソース、およびDNSレコードを構成したので、次にプロジェクトをクラウドにデプロイします。

ステップ5—構成の計画と適用

このセクションでは、Terraformプロジェクトを初期化し、クラウドにデプロイして、すべてが正しくプロビジョニングされていることを確認します。

プロジェクトインフラストラクチャが完全に定義されたので、デプロイする前に行う必要があるのは、Terraformプロジェクトを初期化することだけです。 これを行うには、次のコマンドを実行します。

  1. terraform init

次の出力が表示されます。

Output
Initializing the backend... Initializing provider plugins... - Finding digitalocean/digitalocean versions matching "~> 2.0"... - Finding latest version of hashicorp/external... - Installing digitalocean/digitalocean v2.10.1... - Installed digitalocean/digitalocean v2.10.1 (signed by a HashiCorp partner, key ID F82037E524B9C0E8) - Installing hashicorp/external v2.1.0... - Installed hashicorp/external v2.1.0 (signed by HashiCorp) Partner and community providers are signed by their developers. If you'd like to know more about provider signing, you can read about it here: https://www.terraform.io/docs/cli/plugins/signing.html Terraform has created a lock file .terraform.lock.hcl to record the provider selections it made above. Include this file in your version control repository so that Terraform can guarantee to make the same selections by default when you run "terraform init" in the future. Terraform has been successfully initialized! You may now begin working with Terraform. Try running "terraform plan" to see any changes that are required for your infrastructure. All Terraform commands should now work. If you ever set or change modules or backend configuration for Terraform, rerun this command to reinitialize your working directory. If you forget, other commands will detect it and remind you to do so if necessary.

これで、動的に生成された名前と付随するドメインを使用してDropletをDigitalOceanアカウントにデプロイできるようになります。

ドメイン名、SSHキーの指紋、および個人用アクセストークンを環境変数として定義することから始めます。これにより、Terraformを実行するたびに値をコピーする必要がなくなります。 強調表示された値を置き換えて、次のコマンドを実行します。

  1. export DO_PAT="your_do_api_token"
  2. export DO_DOMAIN_NAME="your_domain"

APIトークンは、DigitalOceanコントロールパネルにあります。

渡された変数値を使用してplanコマンドを実行し、Terraformがプロジェクトをデプロイするために実行する手順を確認します。

  1. terraform plan -var "do_token=${DO_PAT}" -var "domain_name=${DO_DOMAIN_NAME}"

出力は次のようになります。

Output
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # digitalocean_droplet.web will be created + resource "digitalocean_droplet" "web" { + 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) + locked = (known after apply) + memory = (known after apply) + monitoring = false + name = "web-1625908814" + price_hourly = (known after apply) + price_monthly = (known after apply) + private_networking = (known after apply) + region = "fra1" + resize_disk = true + size = "s-1vcpu-1gb" + ssh_keys = [ + "...", ] + status = (known after apply) + urn = (known after apply) + vcpus = (known after apply) + volume_ids = (known after apply) + vpc_uuid = (known after apply) } # digitalocean_record.www will be created + resource "digitalocean_record" "www" { + domain = "your_domain'" + fqdn = (known after apply) + id = (known after apply) + name = "@" + ttl = (known after apply) + type = "A" + value = (known after apply) } Plan: 2 to add, 0 to change, 0 to destroy. ...

緑の+で始まる行は、Terraformが後続の各リソースを作成することを示します。これはまさに発生するはずなので、構成をapplyできます。

  1. terraform apply -var "do_token=${DO_PAT}" -var "domain_name=${DO_DOMAIN_NAME}"

出力は以前と同じですが、今回は確認を求められる点が異なります。

Output
Plan: 2 to add, 0 to change, 0 to destroy. 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`

yesと入力すると、TerraformはドロップレットとDNSレコードをプロビジョニングします。

Output
digitalocean_droplet.web: Creating... ... digitalocean_droplet.web: Creation complete after 33s [id=204432105] digitalocean_record.www: Creating... digitalocean_record.www: Creation complete after 1s [id=110657456] Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

Terraformは、デプロイされたリソースをその状態で記録しました。 DNSレコードとドロップレットが正常に接続されたことを確認するには、ローカル状態からドロップレットのIPアドレスを抽出し、ドメインのパブリックDNSレコードと一致するかどうかを確認します。 次のコマンドを実行して、IPアドレスを取得します。

  1. terraform show | grep "ipv4"

ドロップレットのIPアドレスを受け取ります。

Output
ipv4_address = "your_Droplet_IP" ...

次のコマンドを実行して、パブリックAレコードを確認できます。

  1. nslookup -type=a your_domain | grep "Address" | tail -1

出力には、Aレコードが指すIPアドレスが表示されます。

Output
Address: your_Droplet_IP

それらは、本来あるべきものと同じです。つまり、ドロップレットとDNSレコードが正常にプロビジョニングされたことを意味します。

次のステップで変更を行うには、次のコマンドを実行して、デプロイされたリソースを破棄します。

  1. terraform destroy -var "do_token=${DO_PAT}" -var "domain_name=${DO_DOMAIN_NAME}"

プロンプトが表示されたら、yesと入力して続行します。

このステップでは、インフラストラクチャを作成し、それをDigitalOceanアカウントに適用しました。 次に、Terraformプロビジョナーを使用してプロビジョニングされたドロップレットにApacheWebサーバーを自動的にインストールするように変更します。

ステップ6—プロビジョナーを使用してコードを実行する

次に、remote-execプロビジョナーを使用してカスタムコマンドを実行することにより、デプロイされたドロップレットにApacheWebサーバーのインストールをセットアップします。

Terraformプロビジョナーは、作成されたリモートリソース(remote-execプロビジョナー)またはコードが実行されているローカルマシン(local-execプロビジョナーを使用)で特定のアクションを実行するために使用できます。 プロビジョナーに障害が発生した場合、ノードは現在の状態で tainted としてマークされます。これは、次の実行時にノードが削除および再作成されることを意味します。

プロビジョニングされたドロップレットに接続するには、Terraformはドロップレットに設定されたものの秘密SSHキーを必要とします。 秘密鍵の場所を渡す最良の方法は変数を使用することなので、variables.tfを開いて編集します。

  1. nano variables.tf

強調表示された行を追加します。

〜/ apache-droplet-terraform / variables.tf
variable "do_token" {}
variable "domain_name" {}
variable "private_key" {}

これで、private_key という新しい変数がプロジェクトに追加されました。 ファイルを保存して閉じます。

次に、接続データとリモートプロビジョナー宣言をDroplet構成に追加します。 droplets.tfを開いて、次のコマンドを実行して編集します。

  1. nano droplets.tf

強調表示された行で既存のコードを拡張します。

〜/ apache-droplet-terraform / droplets.tf
data "digitalocean_ssh_key" "ssh_key" {
  name = "your_ssh_key_name"
}

resource "digitalocean_droplet" "web" {
  image  = "ubuntu-20-04-x64"
  name   = data.external.droplet_name.result.name
  region = "fra1"
  size   = "s-1vcpu-1gb"
  ssh_keys = [
    data.digitalocean_ssh_key.ssh_key.id
  ]

  connection {
    host        = self.ipv4_address
    user        = "root"
    type        = "ssh"
    private_key = file(var.private_key)
    timeout     = "2m"
  }

  provisioner "remote-exec" {
    inline = [
      "export PATH=$PATH:/usr/bin",
      # Install Apache
      "apt update",
      "apt -y install apache2"
    ]
  }
}

connectionブロックは、Terraformがターゲットドロップレットに接続する方法を指定します。 provisionerブロックには、inlineパラメーター内に、プロビジョニング後に実行されるコマンドの配列が含まれています。 つまり、パッケージマネージャーのキャッシュを更新してApacheをインストールします。 完了したら、保存して終了します。

秘密鍵パスの一時的な環境変数を作成することもできます。

  1. export DO_PRIVATE_KEY="private_key_location"

注:秘密鍵、およびTerraform内からロードするその他のファイルは、プロジェクト内に配置する必要があります。 Ubuntu 20.04または他のディストリビューションで設定されたSSHキーの詳細については、LinuxサーバーでSSHキーベースの認証を構成する方法チュートリアルを参照してください。

構成を再適用してみてください。

  1. terraform apply -var "do_token=${DO_PAT}" -var "domain_name=${DO_DOMAIN_NAME}" -var "private_key=${DO_PRIVATE_KEY}"

プロンプトが表示されたら、yesと入力します。 以前と同様の出力を受け取りますが、remote-execプロビジョナーからの長い出力が続きます。

Output
digitalocean_droplet.web: Creating... digitalocean_droplet.web: Still creating... [10s elapsed] digitalocean_droplet.web: Still creating... [20s elapsed] digitalocean_droplet.web: Still creating... [30s elapsed] digitalocean_droplet.web: Provisioning with 'remote-exec'... digitalocean_droplet.web (remote-exec): Connecting to remote host via SSH... digitalocean_droplet.web (remote-exec): Host: ... digitalocean_droplet.web (remote-exec): User: root digitalocean_droplet.web (remote-exec): Password: false digitalocean_droplet.web (remote-exec): Private key: true digitalocean_droplet.web (remote-exec): Certificate: false digitalocean_droplet.web (remote-exec): SSH Agent: false digitalocean_droplet.web (remote-exec): Checking Host Key: false digitalocean_droplet.web (remote-exec): Connected! ... digitalocean_droplet.web: Creation complete after 1m5s [id=204442200] digitalocean_record.www: Creating... digitalocean_record.www: Creation complete after 1s [id=110666268] Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

これで、Webブラウザでドメインに移動できます。 デフォルトのApacheウェルカムページが表示されます。

Apache Web Server - Default Page

これは、Apacheが正常にインストールされ、Terraformがすべてを正しくプロビジョニングしたことを意味します。

デプロイされたリソースを破棄するには、次のコマンドを実行し、プロンプトが表示されたらyesと入力します。

  1. terraform destroy -var "do_token=${DO_PAT}" -var "domain_name=${DO_DOMAIN_NAME}" -var "private_key=${DO_PRIVATE_KEY}"

これで、Apache Webサーバーをドロップレットにデプロイし、目的のドメインのDNSレコードを設定する単純な構造の小さなTerraformプロジェクトが完了しました。

結論

Terraformプロジェクトを構造化するための、複雑さに応じた2つの一般的なアプローチについて学習しました。 単純な構造化アプローチに従い、remote-execプロビジョナーを使用してコマンドを実行し、ドメインのDNSレコードを含むApacheを実行するDropletをデプロイしました。

参考までに、このチュートリアルで作成したプロジェクトのファイル構造は次のとおりです。

.
└── tf/
    ├── versions.tf
    ├── variables.tf
    ├── provider.tf
    ├── droplets.tf
    ├── dns.tf
    ├── data-sources.tf
    └── external/
        └── name-generator.py

定義したリソース(ドロップレット、DNSレコードと動的データソース、DigitalOceanプロバイダーと変数)は、このチュートリアルの最初のセクションで概説した単純なプロジェクト構造に従って、それぞれ独自の個別のファイルに保存されます。

Terraformプロビジョナーとそのパラメーターの詳細については、公式ドキュメントにアクセスしてください。

このチュートリアルは、Terraformシリーズでインフラストラクチャを管理する方法の一部です。 このシリーズでは、Terraformの初めてのインストールから複雑なプロジェクトの管理まで、Terraformの多くのトピックを取り上げています。