Terraformを学んだこと:第5部


地形形式





  • 第5部:テラバイトモジュールによるクリーナコード



  • 今まで、我々は機能terterform提供に焦点を当てた.サーバーの作成、ネットワーク設定の調整、ドメイン名の設定、bashスクリプトのリモート実行、ストレージユニットの作成、共有空間へのテラフォーム状態の移動.
    このポストでは、休憩を取るとどのように我々はクリーナーを書くことができます参照してください.DRY ER,再利用可能な地形形状コードここでの主なキーワードは「再利用可能」です.なぜなら、この投稿は主にterraformモジュールについてです.

    地形モジュール


    Modules are the key ingredient to writing reusable, maintainable, and testable Terraform code. [1]


    ディレクトリの下に格納されるどんなterraformコードも同じモジュールの中で考慮されるので、モジュールを簡単にモジュールを持つこと.同じ理由で、Terraformのモジュールが暗黙的であると言うことができます、そして、モジュールを作成する理由は少しの魔法です.
    ここまで作成したterraformファイルを見てみましょう.
  • provider.tf : 私たちの液滴に接続するために使用するSSH変数を定義します.ところで、provider.tf このファイルにはかなりうるさい名前です.我々はそれをリファクタリングします.
  • domain.tf : 我々の領域を我々の小滴に示して、そのcName記録を定めます.
  • space.tf : 我々の記憶装置を宣言します.それは、AWSのバケツとDigitalAudio Lingoのスペースです.
  • main.tf : は、プロバイダのバージョン、リモートバックエンド、および当社の最愛の液滴を含む残しているものをかなり設定します.
  • これらのファイルは全て同じディレクトリの下に作成しました.そういうわけで、それらはすべて同じterraformモジュールに属します.では、別のドメイン名でアクセスされる複数の液滴を作成するためにコードを再利用できるようにしましょう.このように、我々は、生産とステージング環境の両方をサポートするインフラストラクチャを持つことができます.我々は、物事を簡単にするには、この記事のバケットとリモート州のファイルを残している.
    我々が目指しているのは、生産とステージング環境の両方でインフラを作ることです.再利用可能なterraformモジュールを使って作成します.CodeBaseを変換した後、ディレクトリ構造は次のようになります.

    まず最初に一つのことをしましょう.versions.tf . 私はterraform v 0を使います.13そして、あなたはあなたを定義する必要がありますprovider requirements このバージョンから起動します.私のすべてversions.tf ファイルは同じです:
    terraform {
      required_providers {
        digitalocean = {
          source = "terraform-providers/digitalocean"
        }
      }
      required_version = ">= 0.13"
    }
    

    モジュールによるディレクトリ構造


    先に述べたように、各ディレクトリは別々のモジュールとして動作します.インフラを二つのモジュールに分けることにしました.domain and server . 私の環境のそれぞれは別のサーバーと別のドメインをサーバーに指すようになります.そういうわけで、私は下で各々のモジュールのためにディレクトリをつくりましたmodules .
    では始めましょうdomain モジュールです.コードをコピーしましたdomain.tf into modules/domain/main.tf :
    resource "digitalocean_domain" "domain" {
      name       = var.domain_name
      ip_address = var.server_ipv4
    }
    
    resource "digitalocean_record" "cname_www" {
      domain = digitalocean_domain.domain.name
      type   = "CNAME"
      name   = "www"
      value  = "@"
    }
    
    あなたは、内部の変化に気がつくべきですdigitalocean_domain リソース:値name and ip_address ハードコーディングされていません.

    モジュール入力


    だから私はvars.tf 私のモジュール変数を定義するファイル
    variable "domain_name" {
      description = "Domain name like yourdomain.com"
      type        = string
    }
    
    variable "server_ipv4" {
      description = "Server's IP address where the domain should point to"
      type        = string
    }
    
    今、私はこれらの変数を入力として使うことができますdomain モジュールです.我々が使うときはいつでもdomain モジュールは、両方の変数をこのリソースを作成する必要があります.それは私たちが異なったドメイン名でドメインを定義することができて、異なったサーバを指すIPアドレスを別々に分けることができるでしょう.
    さあ、に移りましょうserver モジュールです.再び、私は私の古いコードからコピーしましたmain.tf ファイルはこちら
    resource "digitalocean_droplet" "server" {
      image  = "ubuntu-20-04-x64"
      name   = var.server_name
      region = "ams3"
      size   = var.server_size
      ssh_keys = [
        var.ssh_fingerprint
      ]
    
      connection {
        host        = self.ipv4_address
        user        = "root"
        type        = "ssh"
        private_key = file(var.ssh_private_key)
        timeout     = "2m"
      }
    
      provisioner "remote-exec" {
        inline = [
          "export PATH=$PATH:/usr/bin",
          # install nginx
          "sudo apt-get update",
          "sudo apt-get -y install nginx"
        ]
      }
    }
    
    私はvars.tf ファイルをserver モジュール
    variable "server_name" {
      description = "The name of the server"
      type        = string
    }
    
    variable "server_size" {
      description = "The size of the server"
      type        = string
    }
    
    variable "ssh_fingerprint" {
      description = "Fingerprint of the SSH key that is allowed to connect to the server"
      type = string
    }
    
    variable "ssh_private_key" {
      description = "Private key of the SSH key that is allowed to connect to the server"
      type = string
    }
    
    ssh変数を渡すと、このモジュールでサーバ名とサーバサイズを設定できるようになります.それは、より小さなサイズでステージングサーバーを維持している間、より大きいサイズで生産サーバーをつくることができる方法です.
    我々は今、両方のdomain and server 環境で自分自身を作成するモジュール.始めましょうproduction . ここでは、モジュールを使用して環境を作成するように見えますproduction/main.tf :
    module "server" {
      source = "../modules/server"
    
      server_name     = "terraform-sandbox"
      server_size     = "s-1vcpu-1gb"
      ssh_fingerprint = var.ssh_fingerprint
      ssh_private_key = var.ssh_private_key
    }
    
    module "domain" {
      source = "../modules/domain"
    
      domain_name = "productiondomain.com"
      server_ipv4 = module.server.server_ipv4
    }
    
    コマンドライン引数として提供するために、ここでssh変数を渡すつもりです.ご覧の通り、名前とサイズを宣言しますserver モジュールです.同様に、我々は我々の名前を与えるdomain モジュールです.すべてのハードコード今.しかしserver_ipv4 引数domain モジュールはちょっと奇妙に見えます.

    モジュール出力


    何をmodule.server.server_ipv4 はモジュール出力の使用です.我々は孤立したdomain and server モジュールですがdomain 設定はserver 's IPアドレス.モジュール内の出力を定義することでモジュールの値にアクセスできます.内容はこちらmodules/server/outs.tf :
    output "server_ipv4" {
      value = digitalocean_droplet.server.ipv4_address
    }
    
    を定義するserver_ipv4 出力すると、digitalocean_droplet 資源ipv4_address 内部引数server インスタンス.同様に、この構造体に続いて出力にアクセスします.
    module.MODULE_NAME.OUTPUT_NAME
    
    この場合、
    module.server.server_ipv4
    
    この方法では、terraformはまずサーバを作成し、そのIPアドレスを使ってドメインを設定します.

    モジュールのローカル


    入力と出力から離れて、terraformは我々のCodeBaseを乾かすようにもう一つのデータ構造を提供します.入力と出力の代わりに、モジュール間でローカルを使用しません.それらの使用法は、ローカル言語の値をカプセル化するのに限られています.
    例えば、サーバイメージと領域をハードコーディングするのではなく、modules/server/vars.tf :
    locals {
      server_image = "ubuntu-20-04-x64"
      server_region = "ams3"
    }
    
    それから、我々は進んで、我々を利用することができますmodules/server/main.tf ファイル
    resource "digitalocean_droplet" "server" {
      image  = local.server_image
      name   = var.server_name
      region = local.server_region
      size   = var.server_size
      ssh_keys = [
        var.ssh_fingerprint
      ]
    
    # ...
    

    入力,出力,位置に関する一考察


    私はここで小さなメモを取りたかったです、そして、すべての3つの構造がモジュールに特有でないと言います.想像できるように、モジュールは暗黙の構造です.理論的な意味では、モジュールのコンテキストの外で入力、出力、およびlocalsを使うことができると言うなら、それは本当でしょう.テラフォームの各ディレクトリがモジュールであるので、各使用法は実質的にモジュールの使用法に該当するでしょう.
    [ 1 ] : Terraform Up & Running : Yevgeniy Brikmanによるコードとしてのインフラストラクチャの記述(第2版)
    カバー写真Andrej Lišakov
    ........................................................................................................................................................................................................................................................................................................................