コンテンツにスキップ

Ansible

Ansibleは、インフラストラクチャの大規模管理を可能にするソフトウェアツールです。Ansibleはエージェントレスであり、機能するために必要なのは、ターゲットへのSSH接続とターゲットにインストールされたPythonだけです。

AnsibleはTerraformと連携して、Cloudflare Tunnelのセットアッププロセスを効率化します。このガイドでは、Terraformを使用してGoogle CloudにSSHサーバーをデプロイし、サーバーをインターネット上で利用可能にするローカル管理トンネルを作成します。Terraformは自動的に、サーバー上にcloudflaredをインストールおよび構成するAnsibleプレイブックを実行します。

前提条件

このガイドの手順を完了するには、以下が必要です:

1. Ansibleのインストール

Ansibleのインストール手順を参照してください。

2. (オプション) SSHキーのペアを作成

TerraformとAnsibleは、GCPサーバーに接続するために暗号化されていないSSHキーを必要とします。まだキーを持っていない場合は、以下の手順で生成できます:

  1. ターミナルを開き、次のコマンドを入力します:

    Terminal window
    ssh-keygen -t rsa -f ~/.ssh/gcp_ssh -C <username in GCP>
  2. パスフレーズの入力を求められたら、Enterを2回押して空白のままにします。Terraformは暗号化された秘密鍵をデコードできません。

2つのファイルが生成されます:gcp_ssh(秘密鍵を含む)とgcp_ssh.pub(公開鍵を含む)。

3. 設定ディレクトリを作成

  1. TerraformとAnsibleの設定ファイル用のフォルダーを作成します:

    Terminal window
    mkdir ansible-tunnel
  2. 新しいディレクトリに移動します:

    Terminal window
    cd ansible-tunnel

4. Terraform設定ファイルを作成

入力変数を定義

The following variables will be passed into your GCP and Cloudflare configuration.

  1. In your configuration directory, create a .tf file:

    Terminal window
    touch variables.tf
  2. Open the file in a text editor and copy and paste the following:

    # GCP variables
    variable "gcp_project_id" {
    description = "Google Cloud Platform (GCP) project ID"
    type = string
    }
    variable "zone" {
    description = "Geographical zone for the GCP VM instance"
    type = string
    }
    variable "machine_type" {
    description = "Machine type for the GCP VM instance"
    type = string
    }
    # Cloudflare variables
    variable "cloudflare_zone" {
    description = "Domain used to expose the GCP VM instance to the Internet"
    type = string
    }
    variable "cloudflare_zone_id" {
    description = "Zone ID for your domain"
    type = string
    }
    variable "cloudflare_account_id" {
    description = "Account ID for your Cloudflare account"
    type = string
    sensitive = true
    }
    variable "cloudflare_email" {
    description = "Email address for your Cloudflare account"
    type = string
    sensitive = true
    }
    variable "cloudflare_token" {
    description = "Cloudflare API token created at https://dash.cloudflare.com/profile/api-tokens"
    type = string
    sensitive = true
    }

変数に値を割り当てる

  1. In your configuration directory, create a .tfvars file:

    Terminal window
    touch terraform.tfvars

    Terraform will automatically use these variables if the file is named terraform.tfvars, otherwise the variable file will need to be manually passed in.

  2. Add the following variables to terraform.tfvars. Be sure to modify the example with your own values.

    cloudflare_zone = "example.com"
    cloudflare_zone_id = "023e105f4ecef8ad9ca31a8372d0c353"
    cloudflare_account_id = "372e67954025e0ba6aaa6d586b9e0b59"
    cloudflare_email = "user@example.com"
    cloudflare_token = "y3AalHS_E7Vabk3c3lX950F90_Xl7YtjSlzyFn_X"
    gcp_project_id = "testvm-123"
    zone = "us-central1-a"
    machine_type = "e2-medium"

Terraformプロバイダーを設定

インフラストラクチャをプロビジョニングするために使用されるプロバイダーを宣言する必要があります。

  1. 設定ディレクトリ内に.tfファイルを作成します:

    Terminal window
    touch providers.tf
  2. providers.tfに以下のプロバイダーを追加します。randomプロバイダーはトンネルの秘密を生成するために使用されます。

    terraform {
    required_providers {
    cloudflare = {
    source = "cloudflare/cloudflare"
    }
    google = {
    source = "hashicorp/google"
    }
    random = {
    source = "hashicorp/random"
    }
    }
    required_version = ">= 0.13"
    }
    # プロバイダー
    provider "cloudflare" {
    api_token = var.cloudflare_token
    }
    provider "google" {
    project = var.gcp_project_id
    }
    provider "random" {
    }

Cloudflareリソースを設定

以下の設定は、Cloudflareアカウントの設定を変更します。

  1. 設定ディレクトリ内に.tfファイルを作成します:

    Terminal window
    touch Cloudflare-config.tf
  2. Cloudflare-config.tfに以下のリソースを追加します:

    # トンネル用の64文字の秘密を生成します。
    # `random_password`を使用すると、結果は機密として扱われ、コンソール出力には表示されません。参照:https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password
    resource "random_password" "tunnel_secret" {
    length = 64
    }
    # GCP VM用の新しいローカル管理トンネルを作成します。
    resource "cloudflare_tunnel" "auto_tunnel" {
    account_id = var.cloudflare_account_id
    name = "Ansible GCP tunnel"
    secret = base64sha256(random_password.tunnel_secret.result)
    }
    # ssh_app.${var.cloudflare_zone}をトンネルにルーティングするCNAMEレコードを作成します。
    resource "cloudflare_record" "ssh_app" {
    zone_id = var.cloudflare_zone_id
    name = "ssh_app"
    value = "${cloudflare_argo_tunnel.auto_tunnel.id}.cfargotunnel.com"
    type = "CNAME"
    proxied = true
    }

GCPリソースを設定

以下の設定は、GCP仮想マシンの仕様を定義し、マシンにPython3をインストールします。Python3は、起動時にスタートアップスクリプトを実行する代わりに、AnsibleがGCPインスタンスを構成できるようにします。

  1. 設定ディレクトリ内に.tfファイルを作成します:

    Terminal window
    touch GCP-config.tf
  2. テキストエディタでファイルを開き、以下の例をコピーして貼り付けます。自分のGCPユーザー名とSSHキーのペアを挿入してください。

    # GCP VMのOSを選択します。
    data "google_compute_image" "image" {
    family = "ubuntu-minimal-2004-lts"
    project = "ubuntu-os-cloud"
    }
    # GCP VMインスタンスをセットアップします。
    resource "google_compute_instance" "origin" {
    name = "ansible-inst"
    machine_type = var.machine_type
    zone = var.zone
    tags = []
    boot_disk {
    initialize_params {
    image = data.google_compute_image.image.self_link
    }
    }
    network_interface {
    network = "default"
    access_config {
    // 一時IP
    }
    }
    scheduling {
    preemptible = true
    automatic_restart = false
    }
    // VMにPython3をインストールします。
    provisioner "remote-exec" {
    inline = [
    "sudo apt update", "sudo apt install python3 -y", "echo Done!"
    ]
    connection {
    host = self.network_interface.0.access_config.0.nat_ip
    user = "<username in GCP>"
    type = "ssh"
    private_key= file("<path to private key>")
    }
    }
    provisioner "local-exec" {
    // SSHキーとユーザーを指定する場合は、`--private-key <path to private key> -u var.name`を追加します。
    command = "ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -u <username in GCP> --private-key <path to private key> -i ${self.network_interface.0.access_config.0.nat_ip}, playbook.yml"
    }
    metadata = {
    cf-email = var.cloudflare_email
    cf-zone = var.cloudflare_zone
    ssh-keys = "<username in GCP>:${file("<path to public key>")}"
    }
    depends_on = [
    local_file.tf_ansible_vars_file
    ]
    }

Ansibleに変数をエクスポート

以下のTerraformリソースは、トンネルIDやその他の変数をtf_ansible_vars_file.ymlにエクスポートします。Ansibleはこのデータを使用して、サーバー上でcloudflaredを構成および実行します。

  1. 設定ディレクトリ内に新しいtfファイルを作成します:

    Terminal window
    touch export.tf
  2. export.tfに以下の内容をコピーして貼り付けます:

    resource "local_file" "tf_ansible_vars_file" {
    content = <<-DOC
    # Terraformからの変数値を含むAnsible vars_file。
    tunnel_id: ${cloudflare_argo_tunnel.auto_tunnel.id}
    account: ${var.cloudflare_account_id}
    tunnel_name: ${cloudflare_argo_tunnel.auto_tunnel.name}
    secret: ${random_id.tunnel_secret.b64_std}
    zone: ${var.cloudflare_zone}
    DOC
    filename = "./tf_ansible_vars_file.yml"
    }

5. Ansibleプレイブックを作成

Ansibleプレイブックは、Ansibleがデプロイする構成を宣言するYAMLファイルです。

  1. 新しい.ymlファイルを作成します:

    Terminal window
    touch playbook.yml
  2. テキストエディタでファイルを開き、以下の内容をコピーして貼り付けます:

---
- hosts: all
become: yes
# VMにトンネル変数をインポートします。
vars_files:
- ./tf_ansible_vars_file.yml
# VMで以下のコマンドを実行します。
tasks:
- name: cloudflaredのLinuxパッケージをダウンロードします。
shell: wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
- name: cloudflaredをデパッケージします。
shell: sudo dpkg -i cloudflared-linux-amd64.deb
- name: cloudflaredサービスディレクトリを作成します。
shell: mkdir -p /etc/cloudflared/
- name: cloudflaredの設定ファイルを作成し、トンネルのイングレスルールを定義します。
copy:
dest: "/etc/cloudflared/config.yml"
content: |
tunnel: "{{ tunnel_id }}"
credentials-file: /etc/cloudflared/cert.json
logfile: /var/log/cloudflared.log
loglevel: info
ingress:
- hostname: "ssh_app.{{ zone }}"
service: ssh://localhost:22
- service: http_status:404
- name: cloudflaredのトンネル認証情報ファイルを作成します。
copy:
dest: "/etc/cloudflared/cert.json"
content: |
{
"AccountTag" : "{{ account | quote }}",
"TunnelID" : "{{ tunnel_id | quote }}",
"TunnelName" : "{{ tunnel_name | quote }}",
"TunnelSecret" : "{{ secret | quote }}"
}
- name: トンネルをsystemdサービスとしてインストールします。
shell: cloudflared service install
- name: トンネルを開始します。
systemd:
name: cloudflared
state: started
enabled: true
masked: no

キーワードは、Ansibleが構成を実行する方法を定義します。上記の例では、vars_filesキーワードは変数定義が保存されている場所を指定し、tasksキーワードはAnsibleが実行するアクションを指定します。

モジュールは、完了すべきタスクを指定します。この例では、copyモジュールがファイルを作成し、その内容を埋め込みます。

6. 構成をデプロイ

構成ファイルを作成したら、Terraformを通じてデプロイできます。Ansibleのデプロイは、ansible-playbookコマンドが実行されるときにTerraformのデプロイ内で行われます。

  1. 設定ディレクトリを初期化します:

    Terminal window
    terraform init
  2. (オプション) 作成されるすべてのものをプレビューします:

    Terminal window
    terraform plan
  3. 構成をデプロイします:

    Terminal window
    terraform apply

GCPインスタンスとトンネルがオンラインになるまでに数分かかる場合があります。新しいトンネルは、Zero TrustNetworks > Tunnelsで確認できます。

7. 接続をテスト

新しいssh_app.<zone>ホスト名を介してGCPサーバーにSSH接続できるようになりました。接続方法については、SSHガイドを参照してください。