DigitalOceanでPackerとTerraformを使用してHashicorpVaultサーバーを構築する方法

提供:Dev Guides
移動先:案内検索

著者は、 Write for DOnations プログラムの一環として、 Free and Open SourceFundを選択して寄付を受け取りました。

序章

HashiCorpのVaultは、動的なクラウド環境にシークレットと機密データを安全に保存するためのオープンソースツールです。 強力なデータ暗号化、カスタムポリシーを使用したIDベースのアクセス、シークレットリースと失効、および常に記録される詳細な監査ログを提供します。 VaultはHTTPAPIも備えているため、Kubernetesなどの分散したサービス指向のデプロイでクレデンシャルを保存するための理想的な選択肢になります。

同じくHashiCorpによって開発されたPackerTerraformを一緒に使用して、Vaultのイメージを作成およびデプロイできます。 このワークフロー内で、開発者はPackerを使用して、イメージに含める必要のあるものを指定する単一の構成ファイルから、さまざまなプラットフォーム用の不変のイメージを書き込むことができます。 その後、Terraformは、作成されたイメージのカスタマイズされたインスタンスを必要な数だけデプロイします。

このチュートリアルでは、Packerを使用して、Vaultがインストールされたシステムの不変のスナップショットを作成し、Terraformを使用してその展開を調整します。 最終的には、Vaultを適切に展開するための自動化されたシステムが得られ、基盤となるインストールおよびプロビジョニングプロセスではなく、Vault自体の操作に集中できます。

前提条件

  • ローカルマシンにインストールされたPacker。 手順については、公式ドキュメントをご覧ください。
  • ローカルマシンにインストールされたTerraform。 これを実現するには、DigitalOceanチュートリアルでTerraformを使用する方法のステップ1に従います。
  • DigitalOceanアカウントの読み取りおよび書き込み権限を持つ個人用アクセストークン(APIキー)。 作成方法については、ドキュメントからパーソナルアクセストークンの作成方法にアクセスしてください。
  • デプロイされたVaultドロップレットでの認証に使用するSSHキー。ローカルマシンで利用可能であり、DigitalOceanアカウントに追加されます。 また、指紋も必要です。指紋を追加すると、アカウントのセキュリティページからコピーできます。 詳細な手順については、DigitalOceanのドキュメントまたはSSHキーの設定方法チュートリアルを参照してください。

ステップ1—パッカーテンプレートの作成

このステップでは、 template と呼ばれるPacker構成ファイルを作成します。このファイルは、Vaultがプリインストールされたイメージを構築する方法をPackerに指示します。 構成は、一般的に使用される人間が読める形式の構成ファイル形式であるJSON形式で記述します。

このチュートリアルでは、すべてのファイルを~/vault-orchestrationの下に保存します。 次のコマンドを実行して、ディレクトリを作成します。

mkdir ~/vault-orchestration

そこに移動します:

cd ~/vault-orchestration

PackerとTerraformの構成ファイルを別々のサブディレクトリに別々に保存します。 次のコマンドを使用してそれらを作成します。

mkdir packer terraform

最初にPackerを使用するため、次のディレクトリに移動します。

cd packer

テンプレート変数の使用

プライベートデータとアプリケーションシークレットを別の変数ファイルに保存することは、それらをテンプレートから除外するための理想的な方法です。 イメージを構築するとき、Packerは参照される変数をそれらの値に置き換えます。 シークレット値をテンプレートにハードコーディングすることは、セキュリティ上のリスクです。特に、チームメンバーと共有したり、GitHubなどの公開サイトに公開したりする場合はそうです。

それらをpackerサブディレクトリのvariables.jsonというファイルに保存します。 お気に入りのテキストエディタを使用して作成します。

nano variables.json

次の行を追加します。

〜/ vault-orchestration / packer / variables.json

{
    "do_token": "your_do_api_key",
    "base_system_image": "ubuntu-20-04-x64",
    "region": "fra1",
    "size": "s-1vcpu-1gb"
}

変数ファイルは、変数名をそれらの値にマップするJSONディクショナリで構成されています。 作成しようとしているテンプレートでこれらの変数を使用します。 必要に応じて、開発者向けドキュメントに従って、ベースイメージ、リージョン、およびドロップレットサイズの値を編集できます。

your_do_api_keyを、前提条件の一部として作成したAPIキーに置き換えてから、ファイルを保存して閉じることを忘れないでください。

ビルダーとプロビジョナーの作成

変数ファイルの準備ができたら、Packerテンプレート自体を作成します。

VaultのPackerテンプレートをtemplate.jsonという名前のファイルに保存します。 テキストエディタを使用して作成します。

nano template.json

次の行を追加します。

〜/ vault-orchestration / packer / template.json

{
     "builders": [{
         "type": "digitalocean",
         "api_token": "{{user `do_token`}}",
         "image": "{{user `base_system_image`}}",
         "region": "{{user `region`}}",
         "size": "{{user `size`}}",
         "ssh_username": "root"
     }],
     "provisioners": [{
         "type": "shell",
         "inline": [
             "sleep 30",
             "sudo apt-get update",
             "sudo apt-get install unzip -y",
             "curl -L https://releases.hashicorp.com/vault/1.8.4/vault_1.8.4_linux_amd64.zip -o vault.zip",
             "unzip vault.zip",
             "sudo chown root:root vault",
             "mv vault /usr/local/bin/",
             "rm -f vault.zip"
         ]
    }]
}

テンプレートでは、BuildersおよびProvisionersの配列を定義します。 ビルダーは、システムイメージの構築方法(タイプに応じて)とその保存場所をPackerに指示します。一方、プロビジョナーには、ソフトウェアのインストールや構成など、システムを不変のイメージに変換する前にPackerがシステムに対して実行する必要のある一連のアクションが含まれます。 プロビジョナーがないと、基本システムイメージはそのままになります。 ビルダーとプロビジョナーの両方が、さらにワークフローをカスタマイズするためのパラメーターを公開します。

最初にタイプdigitaloceanの単一のビルダーを定義します。つまり、イメージのビルドを注文すると、Packerは提供されたパラメーターを使用して、指定されたAPIキーを使用して、指定されたサイズの一時的なドロップレットを作成します。基本システムイメージと指定された領域。 変数をフェッチするための形式はテンプレート:User 'variable name'で、強調表示されている部分はその名前です。

一時的なドロップレットがプロビジョニングされると、プロビジョナーは指定されたユーザー名でSSHを使用してそれに接続し、ドロップレットからDigitalOceanスナップショットを作成して削除する前に、定義されたすべてのプロビジョナーを順番に実行します。

プロビジョナーのタイプはshellで、ターゲットに対して特定のコマンドを実行します。 コマンドは、文字列の配列としてinlineで指定するか、サイズが原因でテンプレートに挿入するのが面倒になる場合は、個別のスクリプトファイルで定義できます。 テンプレート内のコマンドは、システムが起動するまで30秒間待機してから、Vault 1.8.4をダウンロードして解凍します。 公式Vaultダウンロードページを確認し、コマンド内のリンクをLinux用の新しいバージョン(利用可能な場合)に置き換えてください。

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

テンプレートの有効性を確認するには、次のコマンドを実行します。

packer validate -var-file=variables.json template.json

Packerは、-var-file引数を介して変数ファイルへのパスを受け入れます。

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

OutputThe configuration is valid.

エラーが発生した場合、Packerはエラーが発生した場所を正確に指定するため、エラーを修正できます。

これで、Vaultがインストールされ、APIキーとその他のパラメーターが別のファイルで定義されたイメージを生成する作業テンプレートができました。 これで、Packerを呼び出してスナップショットを作成する準備が整いました。

ステップ2—スナップショットを作成する

このステップでは、Packer buildコマンドを使用して、テンプレートからDigitalOceanスナップショットを作成します。

スナップショットを作成するには、次のコマンドを実行します。

packer build -var-file=variables.json template.json

このコマンドは、完了するまでに少し時間がかかります。 これに似た多くの出力が表示されます。

Outputdigitalocean: output will be in this color.

==> digitalocean: Creating temporary RSA SSH key for instance...
==> digitalocean: Importing SSH public key...
==> digitalocean: Creating droplet...
==> digitalocean: Waiting for droplet to become active...
==> digitalocean: Using SSH communicator to connect: ...
==> digitalocean: Waiting for SSH to become available...
==> digitalocean: Connected to SSH!
==> digitalocean: Provisioning with shell script: /tmp/packer-shell464972932
    digitalocean: Hit:1 http://mirrors.digitalocean.com/ubuntu focal InRelease
 ...
==> digitalocean:   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
==> digitalocean:                                  Dload  Upload   Total   Spent    Left  Speed
==> digitalocean: 100 63.5M  100 63.5M    0     0   110M      0 --:--:-- --:--:-- --:--:--  110M
    digitalocean: Archive:  vault.zip
    digitalocean:   inflating: vault
==> digitalocean: Gracefully shutting down droplet...
==> digitalocean: Creating snapshot: packer-1635876039
==> digitalocean: Waiting for snapshot to complete...
==> digitalocean: Destroying droplet...
==> digitalocean: Deleting temporary ssh key...
Build 'digitalocean' finished after 5 minutes 6 seconds.

==> Wait completed after 5 minutes 6 seconds

==> Builds finished. The artifacts of successful builds are:
--> digitalocean: A snapshot was created: 'packer-1635876039' (ID: 94912983) in regions 'fra1'

Packerは、テンプレートの作成中に行ったすべての手順をログに記録します。 最後の行には、スナップショットの名前(packer-1635876039など)とそのIDが括弧で囲まれ、赤でマークされています。 次の手順で必要になるため、スナップショットのIDをメモします。

APIエラーが原因でビルドプロセスが失敗した場合は、数分待ってから再試行してください。

テンプレートに従ってDigitalOceanスナップショットを作成しました。 スナップショットにはVaultがプリインストールされており、システムイメージとしてDropletsを展開できるようになりました。 次のステップでは、このようなデプロイメントを自動化するためのTerraform構成を記述します。

ステップ3—Terraform構成の記述

このステップでは、Packerを使用して構築したVaultを含むスナップショットのDropletデプロイメントを自動化するためのTerraform構成を記述します。

以前に構築されたスナップショットからVaultをデプロイするための実際のTerraform構成を作成する前に、まずそのためにDigitalOceanプロバイダーを構成する必要があります。 次のコマンドを実行して、terraformサブディレクトリに移動します。

cd ~/vault-orchestration/terraform

次に、do-provider.tfという名前のファイルを作成します。このファイルには、プロバイダーを保存します。

nano do-provider.tf

次の行を追加します。

〜/ vault-orchestration / terraform / do-provider.tf

terraform {
  required_providers {
    digitalocean = {
      source = "digitalocean/digitalocean"
      version = "~> 2.0"
    }
  }
}

variable "do_token" {
}

variable "ssh_fingerprint" {
}

variable "instance_count" {
  default = "1"
}

variable "do_snapshot_id" {
}

variable "do_name" {
  default = "vault"
}

variable "do_region" {
}

variable "do_size" {
}

provider "digitalocean" {
  token = var.do_token
}

このファイルはパラメーター変数を宣言し、digitaloceanプロバイダーにAPIキーを提供します。 後でこれらの変数をTerraformテンプレートで使用しますが、最初にそれらの値を指定する必要があります。 そのために、Terraformは、Packerと同様に、変数定義ファイルでの変数値の指定をサポートしています。 ファイル名は.tfvarsまたは.tfvars.jsonで終わる必要があります。 後で-var-file引数を使用してそのファイルをTerraformに渡します。

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

テキストエディタを使用して、definitions.tfvarsという変数定義ファイルを作成します。

nano definitions.tfvars

次の行を追加します。

〜/ vault-orchestration / terraform /definitions.tfvars

do_token         = "your_do_api_key"
ssh_fingerprint  = "your_ssh_key_fingerprint"
do_snapshot_id   = your_do_snapshot_id
do_name          = "vault"
do_region        = "fra1"
do_size          = "s-1vcpu-1gb"
instance_count   = 1

your_do_api_key, your_ssh_key_fingerprint、およびyour_do_snapshot_idを、それぞれアカウントAPIキー、SSHキーのフィンガープリント、および前の手順でメモしたスナップショットIDに置き換えることを忘れないでください。 do_regionおよびdo_sizeパラメーターは、Packer変数ファイルと同じ値である必要があります。 複数のインスタンスを一度にデプロイする場合は、instance_countを目的の値に調整します。

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

DigitalOcean Terraformプロバイダーの詳細については、公式ドキュメントにアクセスしてください。

Vaultスナップショットの展開構成は、terraformディレクトリの下のdeployment.tfという名前のファイルに保存します。 テキストエディタを使用して作成します。

nano deployment.tf

次の行を追加します。

〜/ vault-orchestration / terraform / deployment.tf

resource "digitalocean_droplet" "vault" {
  count              = var.instance_count
  image              = var.do_snapshot_id
  name               = var.do_name
  region             = var.do_region
  size               = var.do_size
  ssh_keys = [
    var.ssh_fingerprint
  ]
}

output "instance_ip_addr" {
  value = {
    for instance in digitalocean_droplet.vault:
    instance.id => instance.ipv4_address
  }
  description = "The IP addresses of the deployed instances, paired with their IDs."
}

ここでは、vaultという名前のタイプdigitalocean_dropletの単一のリソースを定義します。 次に、変数値に従ってパラメーターを設定し、SSHキー(フィンガープリントを使用)をDigitalOceanアカウントからDropletリソースに追加します。 最後に、コンソールに新しくデプロイされたすべてのインスタンスのIPアドレスをoutputします。

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

デプロイメント構成で他のことを行う前に、ディレクトリをTerraformプロジェクトとして初期化する必要があります。

terraform init

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

OutputInitializing the backend...

Initializing provider plugins...
- Finding digitalocean/digitalocean versions matching "~> 2.0"...
- Installing digitalocean/digitalocean v2.15.0...
- Installed digitalocean/digitalocean v2.15.0 (signed by a HashiCorp partner, key ID F82037E524B9C0E8)

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.

ディレクトリをプロジェクトとして初期化するとき、Terraformは利用可能な構成ファイルを読み取り、出力に記録されているように、必要と思われるプラグインをダウンロードします。

これで、VaultスナップショットをデプロイするためのTerraform構成の準備が整いました。 これで、検証とドロップレットへの展開に進むことができます。

ステップ4—Terraformを使用したVaultのデプロイ

このセクションでは、validateコマンドを使用してTerraformの構成を確認します。 正常に検証されたら、applyして、結果としてドロップレットをデプロイします。

次のコマンドを実行して、構成の有効性をテストします。

terraform validate

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

OutputSuccess! The configuration is valid.

次に、planコマンドを実行して、構成に従ってインフラストラクチャをプロビジョニングするときにTerraformが何を試行するかを確認します。

terraform plan -var-file="definitions.tfvars"

Terraformは、-var-fileパラメーターを介して変数定義ファイルを受け入れます。

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

OutputTerraform 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.vault[0] will be created
  + resource "digitalocean_droplet" "vault" {
      + backups              = false
      + created_at           = (known after apply)
      + disk                 = (known after apply)
      + graceful_shutdown    = false
      + id                   = (known after apply)
      + image                = "94912983"
      + 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                 = "vault"
      + 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)
    }

Plan: 1 to add, 0 to change, 0 to destroy.

Changes to Outputs:
  + instance_ip_addr = (known after apply)
  ...

resource "digitalocean_droplet" "vault"行の先頭にある緑色の+は、Terraformが次のパラメーターを使用してvaultという新しいドロップレットを作成することを意味します。 これは正しいので、terraform applyを実行して計画を実行できるようになりました。

terraform apply -var-file="definitions.tfvars"

プロンプトが表示されたら、yesと入力します。 数分後、Dropletはプロビジョニングを終了し、次のような出力が表示されます。

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.vault[0] will be created
  + resource "digitalocean_droplet" "vault" {
    ...
    }

Plan: 1 to add, 0 to change, 0 to destroy.

Changes to Outputs:
  + instance_ip_addr = (known after apply)
...

digitalocean_droplet.vault[0]: Creating...
digitalocean_droplet.vault[0]: Still creating... [10s elapsed]
...
digitalocean_droplet.vault[0]: Creation complete after 44s [id=271950984]

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

Outputs:

instance_ip_addr = {
  "271950984" = "your_new_server_ip"
}

出力では、Terraformは実行したアクション(この場合はドロップレットを作成するため)をログに記録し、最後にパブリックIPアドレスを表示します。 次のステップで、これを使用して新しいドロップレットに接続します。

Vaultを含むスナップショットから新しいドロップレットを作成し、検証する準備が整いました。

ステップ5—デプロイされたドロップレットを確認する

このステップでは、SSHを使用して新しいドロップレットにアクセスし、Vaultが正しくインストールされていることを確認します。

Windowsを使用している場合は、KittyPuttyなどのソフトウェアを使用して、SSHキーでドロップレットに接続できます。

LinuxおよびmacOSマシンでは、すでに使用可能なsshコマンドを使用して以下に接続できます。

ssh root@your_server_ip

プロンプトが表示されたら、yesと答えます。 ログインしたら、次のコマンドを実行してVaultを実行します。

vault

次のような「ヘルプ」出力が表示されます。

OutputUsage: vault <command> [args]

Common commands:
    read        Read data and retrieves secrets
    write       Write data, configuration, and secrets
    delete      Delete secrets and configuration
    list        List data or secrets
    login       Authenticate locally
    agent       Start a Vault agent
    server      Start a Vault server
    status      Print seal and HA status
    unwrap      Unwrap a wrapped secret

Other commands:
    audit          Interact with audit devices
    auth           Interact with auth methods
    debug          Runs the debug command
    kv             Interact with Vault's Key-Value storage
    lease          Interact with leases
    namespace      Interact with namespaces
    operator       Perform operator-specific tasks
    path-help      Retrieve API help for paths
    plugin         Interact with Vault plugins and catalog
    policy         Interact with policies
    print          Prints runtime configurations
    secrets        Interact with secrets engines
    ssh            Initiate an SSH session
    token          Interact with tokens

exitと入力すると、接続を終了できます。

これで、新しくデプロイしたDropletが作成したスナップショットから作成され、Vaultが正しくインストールされていることを確認できました。

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

terraform destroy -var-file="definitions.tfvars"

結論

これで、TerraformとPackerを使用してHashicorpVaultをDigitalOceanDropletsにデプロイするための自動システムができました。 これで、必要な数のVaultサーバーをデプロイできます。 Vaultの使用を開始するには、初期化して、さらに構成する必要があります。 その方法については、公式ドキュメントにアクセスしてください。

Terraformを使用したその他のチュートリアルについては、TerraformコンテンツページおよびTerraformでインフラストラクチャを管理する方法シリーズをご覧ください。複雑なプロジェクト。