HashiCorp の blog に、 Terraform 0.12 プレビューに関する投稿が今日(現地2018年7月12日 原題: HashiCorp Terraform 0.12 Preview: For and For-Each )にありました。例によって参考訳として共有させていただきます。以下どうぞ。

HashiCorp Terraform 0.12 Preview: For and For-Each

(Terraform 0.12 の主要な新機能に関する、連載3回めの投稿です)

Terraform 0.12 リリース につながる一環として、機能プレビューに関する一連のブログ投稿を公開します。今週の投稿は新しい繰り返し機能 for 式と for_each 式についてです。

Terraform 0.11 以前のバージョンでは、値やリソースの数を決める時、共通した設定上の問題があります。それは、固定した値ではなく、動的な表現が用いられている状況への対応です。全体的に繰り返しに関する問題は大きなものです。この問題を解決するため、Terraform 0.12 は機能性を改善するために、別の新しい機能を導入します。それが for 式と for_each ブロックです。また、私たちは更なる拡張を議論していますが、こちらは後ほど扱います。

リストとマップ変換の表記

リストとマップを扱う時、ある集まりにある各要素から新しい集まりを作り出すため、フィルタや変換が必要になるのは共通しています。Terraofrm 0.12 に先立ち、Terraform はこのような作業のために、formatlist(フォーマットリスト)という限定的な演算をサポートしています。これは個々の必要性に応じて補完(代入)する機能です。

Terraform 0.12 では for 式という新しい構造を導入しました。これはリストまたはマップの構成要素が、他のリストやマップの要素によって変換及びフィルタリングできるようにします。以下がこちらを使った例です:

# Terraform 0.12 向けの設定

variable "vpc_id" {
  description = "セキュリティ・グループを作成する場所の AWS VPC の ID"
}

variable "subnet_numbers" {
  description = "接続を許可する base_cidr_block のリストで、8ビット数のサブネット"
  default = [1, 2, 3]
}

data "aws_vpc" "example" {
  id = var.vpc_id
}

resource "aws_security_group" "example" {
  name        = "friendly_subnets"
  description = "フレンドリーなサブネットからのアクセスを許可"
  vpc_id      = var.vpc_id

  ingress {
    from_port = 0
    to_port   = 0
    protocol  = -1

    # subnet_numbers にある数値ごとに、サブネット CIDR プリフィックスを生成するため、
    # リクエストされた VPC の CIDR プリフィックスを展開します。
    # subnet_numbers のデフォルト値は上述の通りであり、VPC CIDR プリフィックスは 10.1.0.0/16 なので、
    # これをもとに作成されるのは: ["10.1.1.0/24", "10.1.2.0/24", "10.1.3.0/24"]
    cidr_blocks = [
      for num in var.subnet_numbers:
      cidrsubnet(data.aws_vpc.example.cidr_block, 8, num)
    ]
  }
}

前述の通り、 for 式で角括弧( [] )で囲むと、その結果はリストとなります。同様に、 for 式で中括弧( {} )で囲むとマップを正視します。例:

# Terraform 0.12 向けの設定

output "instance_private_ip_addresses" {
  # 結果は次のように、インスタンス ID が提供するプライベート IP アドレスをマップします:
  #  {"i-1234" = "192.168.1.2", "i-5678" = "192.168.1.5"}
  value = {
    for instance in aws_instance.example:
    instance.id => instance.private_ip
  }
}

また、オプションで if 条件を使っても入力コレクションをフィルタできます。そのため、入力にサブネット項目を含むアイテムだけを表示できます:

# Terraform 0.12 向けの設定

output "instance_public_ip_addresses" {
  value = {
    for instance in aws_instance.example:
    instance.id => instance.public
    if instance.associate_public_ip_address
  }
}

あとは、 for 式で形成するマップにはグループ化モード(grouping mode)があります。ここではマップのキーを、それぞれのキーをリストの中で識別するためのグループ・アイテムとしても使えます。このモードを有効にするには、値を記述した末尾に省略記号(...)を付けます:

# Terraform 0.12 向けの設定

output "instances_by_availability_zone" {
  # 結果はアベイラビリティ・ゾーンに対応するインスタンス ID をマップします。このように:
  #  {"us-east-1a": ["i-1234", "i-5678"]}
  value = {
    for instance in aws_instance.example:
    instance.availability_zone => instance.id...
  }
}

以上の例を通して見てきたように、数えられるリソースであれば、リストとしても振る舞えます。これにより aws_instance.example にあるすべてのインスタンスから、アベイラビリティ・ゾーンごとにグループ化して繰り返し処理できるようになります。

これらの新しい式、リストやマップ式によって、あらゆる引数に対する値を生成するために使えるようになります。また、Terraform 0.12 では、 list や map が許容されているのは module inputs も含んでおり、あらゆる場所で使えるようになります。

動的にネストするブロック(Dynamic Nested Block)

いくつかのリソース型(タイプ)では、設定の一部を繰り返して定義するため、ネストした(入れ子になった)設定ブロックを使います。Terraform 0.12 では新しい構造を導入し、ネストした設定ブロックの集まりを動的に構築します。

たとえば、 aws_autoscaling_group リソースはネスト化ブロックを使ってタグを宣言できます。これはあらゆる EC2 インスタンスに対して影響があるかもしれませんし、そうではないか分かりませんでした。以下の例は Terrafrom 0.12 より以前の構文です

# Terraform 0.11 以前向けの設定

resource "aws_autoscaling_group" "example" {
  # ...

  tag {
    key                 = "Name"
    value               = "example-asg-name"
    propagate_at_launch = false
  }

  tag {
    key                 = "Component"
    value               = "user-service"
    propagate_at_launch = true
  }

  tag {
    key                 = "Environment"
    value               = "production"
    propagate_at_launch = true
  }
}

これらのネスト化ブロックは静的なものであり、以前は動的な挙動の実装は難しいか不可能でした。動的なブロックを生成する手法は、細部の実装を使った手法がいくつかありましたが、代替策であり信頼性が足りないものでした、これは。Terraform がネスト化したブロックとみなすために、自由な記述を許していなかったからです。 Terraform 0.12 では特別な新しい動的ブロック構造を導入しました。これにより動的な設定をサポートし、業界一流の手法として利用できるようになりました。先ほどの例は、以下の Terraform 0.12 のものと同じです:

# Terraform 0.12 向けの設定

locals {
  standard_tags = {
    Component   = "user-service"
    Environment = "production"
  }
}

resource "aws_autoscaling_group" "example" {
  # ...

  tag {
    key                 = "Name"
    value               = "example-asg-name"
    propagate_at_launch = false
  }

  dynamic "tag" {
    for_each = local.standard_tags

    content {
      key                 = tag.key
      value               = tag.value
      propagate_at_launch = true
    }
  }
}

dynamic "tag" ブロックは、 あたかも tag ブロックが分割されているように振る舞うもので、リストまたはマップの各要素に for_each の引数が与えられます。これは dynamic が自身をネスト化したブロックとしている前提のため、コンテント・ブロックの中でもすべて同じ構文が利用できます。そのため、リテラル・タグのブロックと静的または動的なタグのブロックが有効ですので、前述で見てきたように、静的と動的なタグのブロックの両方を混在できます。これにより、任意で必要に応じた複雑な挙動も行えます。

for_each 引数はあらゆるリストやマップ式を受け入れます。そのため、他のリストとマップの値を任意に変換したものをベースに、先ほど説明したようなネスト化したブロックとして、この機能は for 式と一緒に使えます。

# Terraform v0.12 用の設定

variable "subnets" {
  default = [
    {
      name   = "a"
      number = 1
    },
    {
      name   = "b"
      number = 2
    },
    {
      name   = "c"
      number = 3
    },
  ]
}

locals {
  base_cidr_block = "10.0.0.0/16"
}

resource "azurerm_virtual_network" "example" {
  name                = "example-network"
  resource_group_name = azurerm_resource_group.test.name
  address_space       = [local.base_cidr_block]
  location            = "West US"

  dynamic "subnet" {
    for_each = [for s in subnets: {
      name   = s.name
      prefix = cidrsubnet(local.base_cidr_block, 4, s.number)
    }]

    content {
      name           = subnet.name
      address_prefix = subnet.prefix
    }
  }
}

Terraform は content ブロックの内部でも引数を扱えます。これは静的なブロックでも有効なのと同様であり、 for_each 式の値が分からない場合でもです。したがって、この手法を使うと何らかの実際の行動をとる前に、plan の時点で問題を引き起こす可能性があります。

私たちは、過度な抽象化と、動的な設定を必要以上に行わないのを推奨します。これらの動的な機能は再利用可能なモジュールの作成時に役立つでしょう。しかしながら、過度に動的な記述は、読みやすさとメンテナンス性を苦しくします。明確なのは不明確よりも優れていますし、間接的よりも直接的の方が優れています。

for_each リソース

これまでに見てきた動的なブロックを構成する要素には、 for_each 引数を用いて、リストやマップ上で繰り返し利用するアイディアがありました。これが目指すのは。リソースの引数として数をカウントするのに比べ、ネスト化したブロックを動的に作る手法の方が、より直感的かつ使いやすいためです。

Terraform 0.12 の開発期間中は、リストやマップの各要素をもとにしたリソース・インスタンスを便利にするため、 resourcedata ブロックで for_each を直接サポートするべく、基礎に向けた作業も続けています。残念ながら Terraform 0.12 の初期リリースでは、この機能を完全には実装できません。しかしながら、以降の派生リリースにおいて、マップによって与えられた要素をベースとした、同じタイプの複数リソース・インスタンスを動的に構築するのを簡単にしていきます。以下の例は 今後の Terraform 構文であり、0.12 初期のリリースには含みません。

# v0.12.0 のリリース後に計画

variable "subnet_numbers" {
  description = "アベイラビリティ・ゾーンに数字をマップし、各アベイラビリティ・ゾーンのサブネットのために使います"
  default     = {
    "eu-west-1a" = 1
    "eu-west-1b" = 2
    "eu-west-1c" = 3
  }
}

resource "aws_vpc" "example" {
  # ...
}

resource "aws_subnet" "example" {
  for_each = var.subnet_numbers

  vpc_id            = aws_vpc.example.id
  availability_zone = each.key
  cidr_block        = cidrsubnet(aws_vpc.example.cidr_block, 8, each.value)
}

新しいオブジェクト each には属性 each.keyeach.value があります。これは for_each 式の各要素に key (キー:鍵)と value (バリュー:値)でアクセスできるようにします。

for_each 引数がマップの場合、Terraform が認識する各インスタンスは数字のインデックスではなく、マップ要素のキー文字列にあるものと認識します。これは数字を繰り返してリスト作るような、現在のパターンを避けるためです。なぜなら、ここで扱うアイテムは、リストの処理途中でも追加・削除されてしまう可能性があり、後に続くインデックスがずれてしまう可能性が出てくるからです。

私たちは初期の Terraform 0.12 リリースに向けて、この機能を完全に実装しようとは考えていません。Terraform は引数名 for_eacheach 式を予約後としてみなすため、リソース型(タイプ)としては利用できません。つまり、この機能の実装が完了するのは後続のリリースであり、破壊的な変更は伴いません。

モジュール count と for_each

長い間にわたり、複数の同じモジュールの作成を簡単にするためには、module ブロック内で count メタ引数を使うのが望ましいとされていました。

再びとなりますが、私たちは Terraform 0.12 の開発に向けての基礎作りに取り組んでおり、今後のリリースで作業が完了する見込みです。module ブロックでは count と同様に、新しい for_each 引数を使えるようにします。これは、先ほどの resource ブロックで見たようなものと同じ挙動を目指します

この機能を既存のTerraform アーキテクチャ内に実装するのは、非常に複雑です。そのため、この機能をサポートするためには、より確実な作業が必要です。今後のリリースでの破壊的な変更を避けるため、0.12 では module の入力変数名 countfor_each を予約語として扱い、この機能の実装完了に備えます。

アップグレード・ガイド

新しい forfor_foreach の機能性導入にあたり、既存のリソースとモジュールに新しい予約語を導入します。これにより、 公式プロバイダ(official providers) として提供されているリソースに対しては、破壊的変更を引き起こさないことを確認しています。利用者で作成したモジュールで countfor_each を使っている場合は更新が必要です。

この投稿ではリソースとモジュールの繰り返しに関する将来的な機能性(Terraform 0.12 以降)について説明しました。破壊的な変更を伴いませんが、Terraform 0.12 以降のリリースにおいて、必要なキーワードのすべてを予約語とします。

既にある count 機能性は、これまで変わりません。しかし任意の for_each をサポートするには、根底にあるアーキテクチャの変更を伴いますが、多くの周辺仮題は解決されているでしょう。

次へ

こちらは Terraform 0.12 のプレビューに関する連続ブログ投稿の3回めです。

for 式と for_each は Terraform 0.12 で(ただし使用にあたっては特別な注意が必要)今夏にリリース予定です。Terraform 012 にアップグレードする方法については アップグレード手順 をご覧ください。こちらは Terraform 0.12 のリリースが近づくまで、継続的に更新します。何らかのフィードバックや懸念事項がありましたら、Terraform チームに公開メーリングリストを通してご連絡ください。

原文



HashiCorp の blog に、 Terraform 0.12 プレビューに関する投稿 が先日(2018年7月5日 原題: HashiCorp Terraform 0.12 Preview: First-Class Expressions )にありました。例によって参考訳として共有させていただきます。以下どうぞ。

HashiCorp Terraofrm 0.12 Preview: First-Class Expressions

(Terraform 0.12 の主要な新機能に関する、連載2回めの投稿です)

今夏後半にある Terraform 0.12 リリース の下準備となるよう、新機能に焦点を当てたブログ投稿を毎週行います。今週の投稿は優れた式(First-Class Expressions)です。

式の洗練(First-Class Expresisons)

Terraform が使用する式は、は異なるリソースとパラメータ化した設定の関係性を記述します。式が頻繁に使われるのは、リソース属性値の中です。

Terraform 0.12 より前、式の言語を扱うには、文字列で "${var.foo}" のように補完する必要がありました。

# Configuration for Terraform 0.11 以前の設定ファイル

variable "ami" {
}
variable "instance_type" {
}
variable "vpc_security_group_ids" {
  type = "list"
}

resource "aws_instance" "example" {
  ami           = "${var.ami}"
  instance_type = "${var.instance_type}"

  vpc_security_group_ids = "${var.vpc_security_group_ids}"
}

0.12 では、式の言語がメインの設定言語に統合されるため、動的な式を構文中で直接書けるようになりました。

# Terraform 0.12 用の設定ファイル

variable "ami" {
}
variable "instance_type" {
}
variable "vpc_security_group_ids" {
  type = "list"
}

resource "aws_instance" "example" {
  ami           = var.ami
  instance_type = var.instance_type

  vpc_security_group_ids = var.vpc_security_group_ids
}

Terraform バージョン 0.12 に先立ち、HCL パーサ(parser)は [...]{...} 配列による リストとマップ構文をサポートしましたが、式の中ではこの構文を利用できませんでした。古い HCL 実装このようになったのは、構造上および補完によるものが明らかでした。この制限に対応すべく、Terraform は文字列補完のリスト内で listmap 機能を使えるようにします。

# Terraform 0.11 以前の設定ファイル

resource "aws_instance" "example" {
  # …

  # 以下のリスト構造は静的なので動作します
  vpc_security_group_ids = ["${var.security_group_1}", "${var.security_group_2}"]

  # 以下は動作しません。 [...] 構文は補完言語で解釈されないからです
  vpc_security_group_ids = "${var.security_group_id != "" ? [var.security_group_id] : []}"

  # そのかわり、list() 関数の使用が必要です
  Instead, it's necessary to use the list() function
  vpc_security_group_ids = "${var.security_group_id != "" ? list(var.security_group_id) : list()}"
}

0.12 では、HCL 補完は構造と式が1つの言語となったため、先ほどの補完は、直感的かつ完結な表現となります。

# Terraform 0.12 用の設定ファイル

resource "aws_instance" "example" {
  # …

  vpc_security_group_ids = var.security_group_id != "" ? [var.security_group_id] : []
}

また、これは maps も同様であり、式のどこでも [...]構文が利用できます。0.12 では、直感的ではない設定は受け入れられません。

# Terraform 0.11 以前の設定ファイル

output "weird" {
  value = {
    foo = "foo"
  }
  value = {
    bar = "bar"
  }
}

JSON の情報モデルでは、入れ子ブロックが平らな構造になる必要があったため、以前の HCL は先の記述を value = [{foo = “foo”},{bar = “bar”}] と解釈しました。これはいくつかのタイプのブロックが繰り返すという、論理的な結果になりましたが、利用者にとってはしばし混乱を引き起こしました。他にもこのようにトリッキーな記法が多くあり、結果として設定ファイルにおけるデータ構造は、形状を一定のものに保てませんでした。

0.12 では、HCL はこの解決のために、属性とブロックを明確に区別します。上記にある「weird」(妙な)記述は、HCL ではエラーとして扱われます。これは属性の value を一度しか定義できないからです。適切にするには同じブロック型でまとめます。

# Terraform 0.12 用の設定ファイル

resource "aws_security_group" "example" {
  # …

  # "ingress" には等号記号(イコール)がないため、ブロックとして解釈されます
  ingress {
    # ..
  }

  ingress {
    # ..
  }
}

式の洗練(First-class expressions)は今夏後半に提供する Terraform 0.12 でリリース予定です。Terraform 0.12 にアップグレードするには、 アップグレード手順(英語)をお読みください。こちらのページは、Terraform 0.12 が近づくまでに継続的に更新予定です。

原文



HashiCorp の blog に、 Terraform 0.12 プレビューに関する投稿 が先日(2018年6月28日 原題: HashiCorp Terraform 0.12 Preview )にありました。例によって参考訳として共有させていただきます。以下どうぞ。

HashiCorp Terraofrm 0.12 Preview

(Terraform 0.12 の主要な新機能に関する、連載投稿です)

Terraform 0.12 は広範囲にわたる Terraform 言語改良に焦点をあてており、今夏後半にリリース予定です。Terraform 0.12 のリリースに先立って、次回の主要な改良を伴うリリースについてお知らせしますので、コミュニティは早々にフィードバックできます。

HCL の改良範囲には for ループ、条件式(conditional expression)の改善、null 許容型引数(nullable arguments)、JSON に対する正確な 1:1 対応(exact 1:1 mapping)などです。申し訳ありませんが、これら変更の結果、複数の破壊的な変更を伴います。私たちは一般公開され利用可能となっている膨大な Terraform 設定ファイルを解析しました。そして、これら破壊的な変更による影響があるのは、少ない数パーセントの利用者のみと信じています。来たるべき変更に対してコミュニティと対話できるように、更新ガイドを公開し、一連のブログを早々に投稿します。

HCL 改良

HCL とは、Terraform (だけでなく私たちのツールの大部分)の基礎をなす設定言語です。HCL は最初のリリースから4年間、ほとんどの変更がありませんでした。幅広い組織の設定用途として、本番環境(プロダクション)で使い始めた後、Terraform 利用者からすると多くの改良すべき点が目に付いてきました。HCL による制約の中、何年も使い続けるために多くの工夫をこなしますが、これは直感的ではない次善の策でした。

私たちはこれら HCL へのフィードバックに対して総体的に取り組むべく、1年前から広範囲にわたる開発項目で繰り返し取り組んできました。より堅牢に構築し、機能豊富な言語で Terraform の設定を記述し、解析し、処理する流れを簡単にするためです。私たちは今年の早々から、HCL に対する新しい機能を Terraform 0.12 で統合するように進めてきました。

Terraform 0.12 では言語の中核に対する改良に焦点をあて、非常に多くの新機能を導入します。Terraform 0.12 の changelog(訳者注:変更履歴を記録したファイル)に書かれるに至る直接的な利点に加えて、新しい HCL エンジンは今後の新機能をより柔軟に取り入れられるようになります。

著しい改良

以下は Terraform 0.12 から登場する HCL と Terraform に対する著しい改良の一覧です。一覧にある各機能の詳細については、別途それぞれを解説するブログ投稿を後日します。

  • 優れた条件式(First-class expressions) - 0.12 までの条件式では、 "${var.foo}" のようにダブル・クォーテーション・マーク(二重引用符)で囲む必要がありました。0.12 では、条件式は言語に取り込まれた状態(native part)であり、 ami = var.ami[1] のように直接利用できるようになります。
    • for 文(for epressions) - 繰り返し、リストのフィルタ、値の割り当て(map)のために for 文が使えます。リストやマップが予想される場所では、どこでもこの表記を利用できます。
  • 動的ブロック(Dynamic blocks) - aws_security_group にある rule のような子ブロックは、リストやマップとサポートしている反復型に基づき、動的に生成できます。
  • 汎用「範囲指定」表現(Generalized “Splat” expressions) - 特別な resource.*.field 記法が使えたのは count セットのリソースのみでした。今後は汎用的な記法として、あらゆるリストの値で利用できます。
  • 条件文の改良(Contitional improvements) - 条件式 ... ? ... : ... をあらゆる値の型でサポートし、結果を適切に評価ます。他の言語で見うけられるのと同じように機能します。
  • null 許容型引数(Nullable arguments) - 値がない場所を示すために、特別な値 null をあらゆるフィールドで割り当て可能です。これにより、Terraform は一次側(upstream)API コールからのフィールドを省略するため、処理によっては明確なデフォルト挙動の指定が重要になります。
  • inputs と outputs モジュールで豊富な型を扱える(Rich types in module inputs and outputs) - Terraform は input/outputs における基本的なリストとマップを Terraform 0.7 で導入しましたが、要素として使えるのは1つの値のみでした。Terraform 0.12 からは、あらゆる inputs とoutputs で(modules も含む)任意に複雑なリストとマップが利用できます。
  • テンプレート構文(Template syntax) - 文字列の値では、ループ用途として新しいテンプレート構文を利用できます。複雑な入れ子記法を使う必要はありあせん。例: %{ for instance in aws_instance.example ~}server ${instance.id}%{ endfor }
  • 正確な JSON 構文(Reliable JSON syntax) - Terraform 0.12 の HCL 設定ファイルは、JSON に対して正確に 1:1 となる対応をします。
  • 特別な値としての参照(References as first-class values) - リソースとモジュールに対する depends_on のような参照(リファレンス)で、任意の文字列を使えます。Terraform 0.12 では、リソース識別子(resoruce identifier)を aws_kms_grant.example のように(引用符を使わずに!)そのまま記述できます。これにより、私たちが提供する確認とエラーメッセージを改善できるようになります。同様に、リソースに対するリファレンスは、モジュールからの出力またはパラメータとして戻れるようになります。

来週以降、私たちはブログの投稿を通し、先ほど記述した各改良に対するより詳しい情報や付加情報を公開してきます。各投稿には記述例も含みますので、何が変わるのかだけでなく、Terraform 0.12 のアップグレードに関連する重要な情報を、より簡単に理解できるでしょう。

破壊的変更

紹介したこれらの変更に伴い、数々の破壊的な変更となります。ほとんどの利用者は Terraform 0.12 へのアップグレードにあたり、設定ファイルを変更する必要はありません。ですが、小数グループの利用者は、いずれ設定変更が必要になります。

私たちはTerraform 0.12 アップグレード・ガイドの公開に向けて作業を進めていますので、利用者の皆さんも Terraform 0.12 の準備を開始できます。アップグレード・ガイドは Terraform 0.12 をリリースするまで継続して変更する可能性があるため、ご注意ください。特に、私たちは自動的、もしくは破壊的な変更を完全に防ぐために取り組み続けます。

アップグレード・ガイドに加え、更新作業のすべてが手作業とならないよう、私たちは複数の破壊的な変更に対する自動化ツールに対応中です。設定ファイルの記述にあたっては、安全に実行できるよう、私たちは常に Terraform バージョンに対する制約 を推奨します。

次へ

私たちは次期 Terraform 0.12 の開票にとてもワクワクしています。機能の多くは何年にもわたりご要望いただいていたものですが、Terraform の設定を処理する基礎部分をリセットする必要がありました。新しい基礎ができれば、Terraform は以降のリリースで素早い改良や新機能のサポートをできる準備が整います。

これまで紹介した破壊的な変更に先立ち、私たちは謝罪を申し上げます。私たちは過去6ヶ月にわたり破壊的な変更が最小限になるようにしてきました。また、可能であれば影響が最小限になるよう取り組み続けます。さらに、将来的なリリースでは破壊的な変更が必要としないように、私たちは今回のリリースでは設定(configuration)の変更にも注力しています。

フィードバックや変更に対する提案を検討中であれば、どうか公開メーリングリストにご参加ください。あらゆる変更に対する議論ができれば嬉しく思います!

来週以降の機能プレビューに関するブログ投稿では、Terraform 0.12 の個々の改良に対する詳細な情報をご案内します!

原文



“HashiCorp Consul 1.2:Service Mesh” 概要

HashiCorp の blog に、 Consul 1.2のリリースと新機能に関する投稿 が先日ありました。新しくベータ機能として提供がはじまった Connect 機能や今後の展開についてが参考になるかと思い、例によって参考訳として共有させていただきます。以下どうぞ。

HashiCorp Consul 1.2: サービス・メッシュ(Service Mesh)

HashiCorp Consul 1.2 のリリース発表をとてもうれしく思います。このリリースでは Connect(コネクト) と呼ぶ重要な新機能をサポートします。この機能は、既存の全ての Consul クラスタをサービス・メッシュ(service mesh)ソリューションへと自動的に転換します。Connect により、TLS 暗号化の自動化と、同一性をベースとした認証によって、サービスとサービスとの間の通信を安全にします。

現在の Consul は、世界で 100 万を超えるマシン上で稼働しています。Consul 1.2 にアップグレードし、Connect を有効化したら、あらゆる既存のクラスタが即座にサービスメッシュ・ソリューションになるでしょう。そしてこれは物理マシン、クラウド、コンテナ、スケジューラなどを問わず、あらゆるプラットフォーム上で動作します。

最新のサービスメッシュを用いたサービスネットワーク機能

組織においてマイクロサービスの導入やクラウドを基盤とした動的なインフラを導入するには、サービスメッシュ(service mesh)が必要です。近年の実行環境は、極めて動的な性質を持ちます。そのため、こちらに対応するためには、旧来のホストを土台とする(host-based)ネットワーク・セキュリティを、最新のサービスを土台とする(service-based)セキュリティに置き換える必要があります。

サービスメッシュによって提供されるのは、高い可用性と、分散環境における重要な課題3つに対する解決策です:

今回のリリースまで、 Consul はディスカバリと設定の問題を解決するために、ディスカバリには DNS を、設定にはキーバリュー(ストア)を用いてきました。Connect が新たに解決するのは、分割(segmentation)のためです。3つの機能全てが同時に機能したら、あらゆるプラットフォーム上における完全なサービスメッシュ・ソリューションをもたらします。

Consul Connect

Connect は Consul における主要な新機能であり、TLS 自動暗号化と同一性を基盤とした(identity-based)認証により、安全なサービス間通信を提供します。今日発表した Connect 機能は、完全に自由(free)かつオープンソースです。Connect は Consul 1.2 においては公開ベータ機能として利用できます。

使い勝手のよさを考慮して Connect は構築されました。単なる設定オプションとして扱えるだけではありません。これに加え、1つの外部ラインを追加し、 Connect を基盤とした接続を採用するだけで、既存のあらゆるアプリケーションは自動的にサービスへの登録が可能となります。証明書の切り替えは自動的かつ無停止です。Connect に必要なのはバイナリ1つだけであり、これで全ての必要なサブシステムが使えます。今後は、更に他の機能も扱います。

利便性を高めるため、Connect は Consul に対して多くの新しい機能を提供します。この投稿の後半で機能の幾つかを御紹介しますが、まずは Consul で Connect を利用した場合の主な新機能を列挙します:

  • トラフィック暗号化(Encrypted Traffic) : 全てのトラフィックは共通の TLS を通し、 接続を確立します。これを確かなものとするため、全てのトラフィックを通信中に暗号化します。そのため、信頼性の低い環境においても、安全にサービスを展開(デプロイ)できるようになります。

  • 接続認証(Connection Authorization) : intentions でサービス・アクセス・グラフを作成し、サービス通信の許可(allow)・拒否(deny)をします。ファイアウォールで IP アドレスを使うのとは違い、Connect はサービスの論理名を使います。規模に関係なくルールを指定できるため、ウェブサーバは1つでも100でも構いません。intention の設定は UI 、CLI、API や HashiCorp Terraform から行えます。

  • プロキシ・サイドカー(Proxy Sidecars) : アプリケーションは軽量な proxy サイドカーのプロセスで、自動的にインバウンドとアウトバウンドの TLS 接続を確立します。これを、既存のアプリケーションに変更を加えることなく利用可能にします。Consul はプロキシ機能を内蔵して提供するため、Envoy のようなサードパーティによるプロキシは不要です。

  • ネイティブな統合(Native Integration): 性能が気になるアプリケーションは Consul Connect API でネイティブに統合できるため、最適な性能とセキュリティをプロキシせずに接続の確立と受け入れをします。

  • レイヤ4対レイヤ7(Layer 4 vs. Layer 7): レイヤ4では同一性が強制されます。Consul はレイヤ7機能と設定を置き換え可能なデータレイヤに委任します。サードパーティ製プロキシとも統合できますので、Consul 用のサービスディスカバリ、同一性、認証を学ぶのと同時に、Envoy のようなパスをベースとするルーティング、追跡(トレーシング)等の機能を扱えます。

  • 証明書管理(Certificate Management): Consul は認証局(CA)プロバイダを用い、証明書の生成と配布をします。Consul は CA システムを内蔵しているため、外部の依存性はありません。また HashiCorp Vault との統合により、他の PKI システムをサポートするように拡張できます。

  • 証明書のローテーション(Certificate Rotation): Connect は root と leaf 証明書の両方を自動的に切り替え可能です。root ローテーションは証明書を相互に署名し、ローテーション中も新しい証明書と古い証明書が共存できるため、サービスの中断はありません。また、この仕組みは新しい CA プロバイダを有効にするときも、シームレスな設定を可能とします。

  • SPIFFE を基盤とした識別(SPIFFE-based Ientities): Consul はサービス識別の仕様に SPIFFE を用います。そのため Connect サービスは他の SPIFFE 互換システムとの接続の確立や受け入れが可能です。

  • ネットワークとクラウドの独立(Network and Cloud Independent): Connect は標準の TLS over TCP/IP を用います。そのため、Connect はあらゆるネットワーク設定上で動作します。また、目指すサービスが動作しているオペレーティングシステムに到達するためには、 IP アドレスで伝えます。更に、複雑なオーバレイを用いることなく、サービスはクラウド間で相互に通信可能です。

自動プロキシ・サイドカー

アプリケーションでインバウンドとアウトバウンドの接続を確立するとき、プロキシ・サイドカーを使えばオリジナルのアプリケーションに対する変更は不要です。Connect を有効化するために1行の変更を加えるだけで、あらゆる登録サービスで Connect をベースとした接続を受け入れ可能になります。

{
  "service": {
    "name": "web",
    "port": 8080,
    "connect": { "proxy": {} }
  }
}

唯一の違いは「connect」で始まる行のみです。この1行の設定変更が存在するだけで、Consul はこのサービスに対するプロキシ接続を自動的に開始・管理します。プロキシするプロセスが対象サービスに相当します。動的に割り当てられるインバウンドの接続を受け入れ、TLS によって検証かつ認証された接続で、プロセスに対して標準的な TCP 接続でプロキシし返します。

上流(upstream)の依存関係では、更に数行の記述を追加したら、Connect の外にあるサービスに対するプロキシ接続のリスナーを設定できます。例えば、「web」サービスが「db」サービスと Connect を経由して通信する必要がある場合は次のようにします:

{
  "service": {
    "name": "web",
    "port": 8080,
    "connect": {
      "proxy": {
        "config": {
          "upstreams": [{
             "destination_name": "db",
             "local_bind_port": 9191
          }]
        }
      }
    }
  }
}

このプロキシ管理設定は、ローカルのみのポート 9191 のリスナーに対し、あらゆるリモートの「db」にプロキシするようにセットアップしています。「web」でこのローカルポートを使うように再設定したら、「web」と「db」間の全ての通信が暗号化かつ認証された状態で行われます。

以上の例を通しての注意点としては、元々のアプリケーション「web」は 変更しておらず、Connect を意識してないまま なのです。あらゆるアプリケーションが設定ファイルに対してわずか数行を追加するだけで、自動的に管理されたサイドカー・プロキシを用いる Connect をベースとした通信の受け入れ・確立が可能です。

より詳しく学ぶには、 プロキシに関する参照ドキュメント を御覧ください。アプリケーションが著しく高い性能を必要とする場合は、アプリケーションは Connect と ネイティブに統合 できます。そうしますと、サービスは全てをプロキシする必要はなくなります。

開発が簡単な接続

セキュリティ最適化のために、サービスは Connect をベースとした接続のみを受け入れるようにすべきです。しかしながら、導入のためには、開発やテスト段階において、サービスに対する接続の変更が必要となります。 Consul が提供する consul connect proxy コマンドを使えば、ローカルのプロキシを動かし、 サービスが Connect を経由して通信を確立できるようにします。

例として PostgreSQL サーバが動作しているシナリオを検討しましょう。このサーバは Connect を経由した通信のみ受け入れ可能です。そして、作業者がデータベースをメンテナンスするには、コマンドラインで psql を使い作業を試みるでしょう。作業者は consul connect proxy コマンドを使えば、ローカルマシン上での psql を経由して接続可能になります:

$ consul connect proxy -service mitchellh -upstream postgresql:9191
==> Consul Connect proxy starting...
    Configuration mode: Flags
               Service: mitchellh
              Upstream: postgresql => :9191
       Public listener: Disabled
...

そして、他のシェルで、通常の psql で接続できます:

$ psql -h 127.0.0.1 -p 9191 -U mitchellh mydb
>

-service フラグはソースを識別するのに使います。サービスを終了する必要はありませんが、対象サービスを登録可能な有効な ACL トークンを持っている必要があり、また、Consul は送信元(source)と送信先(destination)間で通信可能に設定しておく必要があります。

ローカルの開発とリモートサービスにおけるテストが、サービスメッシュにおいて共通のワークフローにする課題がありますが、これを Consul と Connect で極めて簡単にします。

intentions によるアクセス制御

サービス間のアクセス制御は “intentions” (意図)で設定可能です。intention は1つの送信元(source)と送信先(destination)の間を、許可(allow)と拒否(deny)のルールで指定します。intentions は UI、CLI、API 、Terraform で作成できます。

以下の例は、 db サービスに対して web からの全てのアクセスを許可(allow)します。

$ consul intention create -allow web db
Created: web => db (allow)

「web」サービスは「db」サービス間との通信が許可されています。 intention では -deny で更新したら、簡単に2つのサービス間の通信を無効化できます。

intention はサービス開発と ACL ルールの管理を設定によって分離できるため、担当者は特定のサービスに対する intention のみ変更できます。これによりセキュリティと分割(segmentation)のどちらもリアルタイムに近く動的な設定変更と管理が可能となります。

機能について更に詳しく

Consul 1.2 では重要な新機能をサポートできましたので、私たちはうれしく思います。機能に対する栄光と大きさを鑑み、Consul 1.2 では Connect はベータであるべきと考えています。今夏は Connect に対して更に熱心に取り組み、年末に至るまでにはベータのタグを外したいです。

また、近いうちに Connect に更なる機能性を追加します。これには新しい UI 拡張や、Envoy をプロキシとしてのサポートや、Nomad や Kubernetes との統合などです。Consul 1.2 における Connect は、ほんの始まりにすぎません。

Consul 1.2 のダウンロードは https://www.consul.io/ に移動します。

次のステップに進むため、更に学ぶには以下のページが役立ちます:

  • 機能のホームページ - Consul 内の Connect 専用のホームページがこちらです。機能の概要と、これから始めるためのガイドがあります。
  • Connect 導入ステップ - 導入ガイドでは Connect の導入ステップを経ながら、 Connect 概要を数分で見渡せます。
  • Connect 双方向チュートリアル - 双方向チュートリアルでは Connect 実行のために重要なステップを見ていきます。
  • Connect リファレンス・ドキュメント(参照文章) - Connect 用のリファレンス・ドキュメントには、どのように Connect が動作し、プロキシをし、ネイティブに統合し、証明書を管理するか等の詳細があります。Connect をデプロイする前に読んでおくのを推奨します。
  • Connect セキュリティ・チェックリスト(安全確認項目) - Connect のセキュリティに対する考え方は Consul とは異なります。より安全に扱うために、このチェックリストを使ったレビューと、読み込みと、Consul の脅威モデルの理解を推奨します。
  • Connect プロダクション・ガイド - プロダクション(本番向け)Connect 用の Consul クラスタの設定をするための完全ガイドです。完全に安全な設定をするために必要なステップの全てがあります。
  • Connect ホワイトボード・セッション - 創業者かつ共同 CTO の Armon Dadger が作成したビデオでは、ネットワーク管理、セキュリティ、性能における Connect の機能を紹介しています。

原文



本投稿は、 さくらインターネットアドベントカレンダー2017 の、5日目の投稿です。都合により一日遅れましたが、今回は Tectonic(テクトニック)についてご紹介します。なお、前日4日目の投稿は blp1526 さんによる「さくらのクラウドのサーバの tig ライクな TUI ツール 」です。6日目の投稿は、hitsumabushiさんによる「 さくらのクラウドでN百台を管理するためにterraformとansibleを使っている話 」です。

はじめに

Tectonic は Kubernetes だけでなく、クラスタを管理するときに役立つ様々な機能をサポートしているツールです。本投稿では Kubernetes の是非を論ずるのではなく、眼前の Kubernetes クラスタを管理する必要が出る場合、どのような選択肢が生まれ得るのかという実地検証の報告が主体です。あくまでも、一利用者の視点で情報を共有いたします。

もともとの投稿では「さくらのクラウド」上で Tectonic が動きますよ!という手順のご紹介を考えていました。結論から申しあげると、PoC(技術検証)レベルにおいては、さくらのクラウド上でもベアメタル・セットアップの手順で動いています(ただし、サポート対象外の模様)。

しかしながら、単にセットアップ手順をご紹介するよりも、Tectonic とは何かあらためて共有させて頂いた上で、後日のエントリにて改めてTectonic環境構築のために必要な Matchbox、Terraform、Ignition の解説、そして、評価環境構築のための手順を皆さまに公開することを予定しています。

また、本エントリは、 先日の発表 の補足の意味も兼ねています。

そもそも Tectonic とは?

Tectonic ( https://coreos.com/tectonic ) は、Container Linux などでお馴染み CoreOS 社が提供しているエンタープライズ対応の Kubernetes です。さらに、実運用で必要な Prometheus の監視設定や、Grafana ダッシュボードの監視設定なども自動的に行えます。どちらかというと Tectonic は Kubernetes のラッパー(wrapper)であり、Kubernetes だけでは足りないエンタープライズ向け機能を、広く知られているオープンソースを使いながら、導入を促している点です。

Tectonic はサイトの記述によりますと「CoreOS の自動化技術を用い、プライベートやパブリック・クラウド間での可搬性(ポータビリティ)を保てるようにしたツール」とあります。サポート対象のプラットフォームは、AWS、Azure のようなクラウド・プロバイダだけではなく、ベアメタル・マシンも含まれています。そして、単に Kubernetes を動かすだけでなく、Tectonicを通して etcd クラスタの管理や、ノード障害時に向けた HA 的な機能も備えられています(ただし、現時点では Tectonic の Provisioner ホスト=Matchbox 設置サーバの冗長化はサポートされていませんが、将来的には計画されています)。

つまり、プラットフォームがどこであろうとも Kubernetes が動作する環境を構築し、その上でコンテナ対応(クラウド・ネイティブ)アプリケーションを実行できるようにします。提供されている機能は、以下の通りです。

しかし、これだけでは Tectonic の機能が分かりづらいので、全貌を図に整理しました。

上図にあるように、物理またはクラウド上のサーバで Kubernetes クラスタを構築します。また、CoreOS 社のプロダクトではありますが、主要なコードやモジュール(Matchbox, Ignition 等)は GitHub 上で公開されており、必要があれば CoreOS 社の商用サポートも受けられます。

ノード管理の諸問題を解決してくれる

Tectonic のアーキテクチャは Rancher をはじめとして、既存のアプローチと一見すると似ているかもしれません。どちらも物理または仮想サーバ上でクラスタのをノード管理し、その上でコンテナを関する、あるいは、 Kubernetes クラスタの管理を GUI を通して行えるようにしています。

しかし方向性は明確に異なります(優劣ではありません)。

Tectonic は、あくまでも Kubernetes クラスタの大規模な自動運用であったり、セキュリティや監査など、大規模組織で求められる機能をまとめています。方向性としては、オープンソースで提供されている Kubernetes と、Kubernetes の運用・管理ツールとして広く知られている Prometheus および Grafana を始めから「何もせずに」使えるようにします。つまり、Kubernetes クラスタを運用するベストプラクティスが詰まっているのが Tectonic とも言えるでしょう。

一方、Rancher は何か動かしたいアプリケーションがあり、環境構築や管理に手間をかけなくない場合。あるいは、素早くサービス提供を進めたくて結果的にコンテナを効率的に使っていきたい場合に、手軽に Kubernetes クラスタを導入・管理・運用できる機能や、商用サポートを提供するものです。

おそらく、入口としての導入がしやすいのは Rancher に軍配が上がるでしょう。一方で、数百台規模以上のノードを効率的に管理する場合は、Tectonic のほうが必要な機能群が備わっているようにも見えます。また、Tectonic は既存のツールの組み合わせでもありますので、要素要素で Kubernetes ないし CNCF 関連エコシステムのツールやプロダクトとも連携しやすいとも言えるでしょう。

Tectonic は、ノード管理の煩雑さをなくしてくれる

実運用を考慮すると、どのようなツールであれ、クラスタを構成するノード(としてのサーバやインスタンス)の管理は頭の悩ましい問題です。たとえば、初期の環境構築であったり、ノード側の OS のセキュリティ対策です。

Tectonic はこの問題を解決するため、Matchbox というプロビジョニング用のサーバ機能と Terraform を連携し、自動的に CoreOS Container Linux のインストールと Kubernetes の自動プロビジョニングを行う仕組みを提供しています。

通常であれば、ノードごとに OS をゼロから構築し、 Kubernetes 用の環境をセットアップし、クラスタのワーカーとしての登録など諸作業が必要です。Tectonic であれば、必要なのは Terraform 用の変数設定ファイルに MAC アドレスの情報を記入し、terraform plan, apply を実行し、電源を入れるだけ。

概要の章まとめ

次回は、Tectonic を構成する要素のなかで、ノードのプロビジョニング(自動環境構築)に欠かせない Matchbox、Ignition、Terraform それぞれの役割詳細をお伝えします。



Terraform Recommended Practices 推奨手順

「Terraformって何がいいんですか?」と訊かれる度に答えていた内容が、とても良い感じにまとまっていましたので、ここで紹介します。2017年11月28日現在の Terraform Recommended Practices の参考訳です。

自動化や運用に興味がある方にとって参考となるのは、HashiCorp の Terraform に興味が無くても、成熟度に応じた自動化の段階分けと、各々の段階からどのように発展すべきかという手順です。手動→半自動→インフラのコード化(Infrastructure as Code)への進歩と、最終的には協調的インフラのコード化(Collaborative Infrastructure as Code)を目指して、バージョン管理や構成管理ツールと連携するにはどうしたらよいのか。あるいは、そこに Terraform や Terraform Enterprise がどのように関わっているのか、自分のインフラを見直すための切っ掛けになると思います。

なお Infrastructure as Code は、日本語で一般的に「コードとしてのインフラ」や「インフラのコード化」という表現が用いられています。英語の訳としては前者が相応しそうですが、技術的な意味合いから当翻訳では後者を採用しています。これは、「Collaborative Infrastructure as Code」という見慣れない言葉を「協調的インフラのコード化」と訳すにあたり、整合性を維持するためでした(コードとしての協調的なインフラ、だと語呂がよくない感じがしたためです)。

(ここから訳)

本ガイドが想定しているのは、Terraform の利用を小数の個人から、組織全体への拡大を目指しているエンタープライズ・ユーザです。

はじめに

HashiCorp が専門としているのは、 IT 組織がクラウド技術を採用するための支援です。基礎となっているのは、私たちのこれまでの取り組みです。私たちはプロビジョニング(訳者注;システム基盤となる計算資源やネットワークの自動構築や自動設定)に対するベストな手法が collaborative Infrastructure as code (協調的インフラのコード化) であると確信しています。そのためには Terraform をワークフローの中心として使い、皆さんの組織における異なるチーム、役割、アプリケーション、開発層における境界を Terraform Enterprise を使い管理します。

協調的インフラのコード化は多くの他の IT ベスト・プラクティス(バージョン管理の利用や、手動での更新防止など)に基づいています。そして、皆さんが私たちの推奨するワークフローを完全に導入するためには、その前にこれら基礎の導入が必要です。最先端のプロビジョニング・プラクティスを達成するとは、いくつかの明確な段階を進んでいく旅なのです。

本ガイドで説明するのは、私たちの推奨する Terraform 手順(プラクティス)と、どのようにそれらを導入するかです。ステップはツールを使い始める所から始まります。これは、手順での作業に依存している場合、特に注意を払うべき基礎についても扱います。

  • Part 1 : 推奨ワークフロー概要 は、Terraform Enterprise による協調的インフラのコード化・ワークフローの全体的な概要です。どのようにインフラを準備・管理し、私たちが情報をやりとりするかを扱います。

  • Part 2 : 現在のプロビジョニング手順を評価 は、皆さんのインフラをプロビジョニングする現状の手順、これを評価する手助けとなる一連の質問です。私たちはオペレーションの成熟に応じて4つの段階を定義しました。これは皆さんが正しい方向に進むのと、手順採用に必要となる基礎を理解するのに役立ちます。

  • Part 3 : プロビジョニング手順を発展するために は、4つの成熟度の段階を通し、プロビジョニング手順をどのように発展させるかを導きます。多くの組織において、既にこのプロセスの半分まで到達しているでしょう。パート2で学んだことを使い、この旅がどこに向かうかを決めます。

このパートは4つのページに分かれています。

Part 1 : 推奨ワークフロー概要

Terraform の目的とは、あらゆるインフラに1つのワークフローで自動構築(プロビジョニング)することです。このセクションでは、大きな組織を縦断して Terraform を扱うために、推奨する手順を紹介します。これが「collaborative infrastructure as code」(協調的インフラのコード化)と呼ぶ手順群です。

プロビジョニングの根本的な変化

プロビジョニング手順の改善を試みますと、誰もが2つの主な課題に直面します。それは、技術的な複雑さと、組織上の複雑さです。

 1. 技術的な複雑さ(Technical complexity) … 新しいリソースをプロビジョニングするには、インフラ事業者(プロバイダ)ごとに異なるインターフェースを使うため、日々のオペレーションにおいて、インターフェース間の差異に対する追加コストを負担させられます。扱うインフラ事業者が増え、多くの共同作業者が増えるほど、これらのコスト負担が増します。

Terraform が対処するのは、プロビジョニングにおけるワークロードから、この複雑さの分離です。リソース間の関連性を、インフラをコード化した設定ファイル群に定義します。そして、これらを1つの中心となるエンジンが読み込みます。それから、各インフラ事業者上のリソースを作成、変更、削除するために、多くの プロバイダ・プラグイン を利用できます。これらプラグインは IaaS (例:AWS、GCP、Microsoft Azure、OpenStack)や SaaS (例:Heroku)サービス群にアクセスできます。

つまり、Terraform が用いるのはリソース・レベルの抽象化ではなく、ワークフロー・レベルの抽象化モデルです。これにより、1つのワークフローでインフラを管理する手法を提供します。ここでは各事業者間で等価交換できないリソースを、一般的な概念として扱うのではなく、事業者ごとに固有のものとして扱います。

 2. 組織上の複雑さ(Organizational complexity) … インフラが拡大するにつれ、インフラを維持するためには多くのチームが必要となります。効率的な共同作業(コラボレーション)のために重要なのは、各チームを横断するインフラ所有権の権限委譲と、作業単位で並列に競合することなく権限を持たせることです。大規模アプリケーションでコンポーネントの権限委譲するのと同様の手法で、インフラの権限を委譲するのに Terraform と Terraform Enterprise が役立ちます。

大規模アプリケーションで権限を委譲するには、集団を徐々に小さく分割し、個々のチームが所有するマイクロサービスのコンポーネントに集約します。各マイクロサービスは API を提供します。そして、API に変更がない限り、お互いが機能的に依存しているのにかかわらず、マイクロサービス・チームは並列に変更を加えられるのです。

この手法と同様に、インフラのコードを、小さな Terraform 設定ファイルに分割可能です。設定は、チームごとに所有できる範囲を制限できます。これらの独立した設定ファイル群は output 変数 を使って情報を出力します。また、 remote state ステータス で、他のワークスペースにある出力データにアクセス可能です。これは、まるでマイクロサービスが API を経由して通信・接続しているように、 Terraform ワークスペースは remote state を通して接続できます。

Terraform の設定を緩やかに連携しますと、チームごとに開発とメンテナンスを委譲できるようになります。この効率性を達成するためには、コードとしてアクセス制限をする必要があります。バージョン管理システムには、誰がコードをコミットできるか制限できます。しかし、 Terraform は実際のインフラを扱うため、更に誰がコードを実行できるか制限する必要があります。

これこそが、Terraform Enterprise (TFE) が組織におけるプロビジョニングの複雑さを解決する手法です。つまり、Terraform の実行環境を集約することで、組織におけるアクセス制御を、全てのワークスペースを横断できるようサポート・実施します。並列な開発を可能にするためには、これがインフラ所有権を委譲する手助けとなります。

登場人物(ペルソナ)、責任、望ましいユーザ経験

スケールするインフラを管理する、4つの主な登場人物がいます。それぞれの役割で、異なる責任と課題があり、異なるツールと権限を Terraform Enterprise がサポートします。

セントラル IT(Central IT)

(訳者注;セントラル IT とは、大規模組織における情報技術を担うという意味の、専門用語。集約された情報システム部門に相当)

チームが責任を持つのは、共通のインフラ手順の定義、チームを横断するポリシーの執行、共有サービスの維持です。

セントラル IT の利用者は1つのダッシュボードを通して、全てのインフラの状態と整合性を閲覧できます。そのため、間違った設定や誤動作があれば、直ちに修正可能です。Terraform Enterprise は Terraform 実行時のデータと密に統合しています。また、Terraform Enterprise はワークスペース(workspace)における Terraform 概念と実行を包括するように設計しています。これにより、一般的なセントラル IT システムよりも、より統合されたワークフロー経験をもたらします。

組織アーキテクト(Organization Architect)

このチームが定義するのは、事業単位内部のチームが、グローバルなインフラをどのように分割・権限委譲するかです。また、このチームはワークスペース間の連携もできるようにするため、それぞれのワークスペースが公開すべき API の定義や、組織間にわたる変数やポリシーを策定します。

組織アーキテクトが欲しいのは、1つのダッシュボードを通して、全てのワークスペースの状態を表示し、ワークスペース間の連携状態をグラフ化することです。

ワークスペースの所有者(Workspace Owner)

複数の環境を横断する Terraform 設定ファイルを作成する所有者が、それぞれのワークスペースごとにいます。所有者が責任を持つのは各ワークスペースの正常性と、開発・UAT(ユーザ受け入れテスト)・ステージング・プロダクションというライフサイクル全体を通した管理です。所有者とは、各領域のプロダクションにおける変更を承認する主担当者です。

ワークスペース所有者が欲しいのは:

  • 1つのダッシュボードでコード化したインフラの全てのワークスペース状態を表示
  • 環境間に影響がある変更を、効率的に伝えるための手法
  • Terraform の設定ファイルで、環境間を横断して使う変数の設定用インターフェース

ワークスペース・コントリビュータ(Workspace Contributor)

ワークスペースにおけるコード化したインフラの設定ファイルを更新するには、コントリビュータが変更を実施します。通常、コントリビュータはプロダクションにおける変更を承認しません。しかし、開発・UAT・ステージングにおいては承認します。

ワークスペース・コントリビュータが欲しいのは、ワークスペース間の変更を実施して伝えるための、シンプルなワークフローです。ワークフロー・コントリビュータが編集できるのは、ワークスペースで共有する変数と、個人用に使う変数です。

大抵のワークスペース・コントリビュータは、Terraform の操作モデルとコマンドライン・インターフェースに慣れています。そのため、Terraform Enterprise のウェブ・インターフェースも迅速に採用できます。

推奨する Terraform ワークスペース構造

ワークスペースについて

Terraform Enterprise(以下 TFE )を組織で使う主な単位(ユニット)がワークスペース(workspace)です。ワークスペースとは、 Terraform が処理を実行するために必要な全ての集まりです。これは、実行する度に操作を追跡可能とするため、設定ファイルの変数と状態データ(state data)のために必要となるものです。また、Terraform 設定ファイル(通常はバージョン管理システムのリポジトリを使用)と変数も含みます。

Terraform オープンソース版では、ローカルのディスク上にある個々の状態ファイルがワークスペースに相当します。TFE は共有リソースの一貫性を保ちます。そのため、共有リソースに対するアクセス制御や、実行状態の監視などが可能になります。

環境ごと Terraform 設定ファイルごとに1つのワークスペース

ワークスペースは TFE で権限委譲を管理する主要なツールです。つまり、ワークスペースの構造は、皆さんの組織における権限構造と一致すべきでしょう。ベストな取り組みは、インフラ・コンポーネントの環境ごとに、1つのワークフローを使うことです。言い換えますと、 Terraform 設定ファイル数 × 環境の数 = ワークスペース数です。

これこそが環境を参照する他のツールとの明確な違いです。プロダクションやステージング環境の構築にあたり、全ての環境を1つの Terraform ワークスペースで管理すべきではありません。そうではなく、ワークスペースを小さくすることにより、権限委譲を簡単にします。また、環境が全く同じだとしても、全ての状況で同じ設定ファイルを使い回せません。例えば、ユーザ受け入れテストであれば、インフラに対する自社のセキュリティ基準をユーザには強制できないはずです。

ワークスペース名は、コンポーネントと環境の両方です。例えば、内部の請求アプリとネットワーク・インフラを関するための Terraform 設定ファイルがあるとしたら、ワークスペースの名前は以下のようになります。

  • billing-app-dev
  • billing-app-stage
  • billing-app-prod
  • networking-dev
  • networking-stage
  • networking-prod

ワークスペースの権限委譲

各ワークスペースは1つのインフラ・コンポーネントごとに1つの環境を持つため、ワークスペースごとにアクセス制御をし、コンポーネントの所有者への権限委譲と、環境を横断するコード統制を伝えられます。例えば、

  • 開発やステージングにおいて、Terraform の実行と変数の編集により、チームがコンポーネントを管理し始めるのを支援します。
  • コンポーネントの所有者又はシニア・コントリビュータは、プロダクションで Terraform を実行した後、他のコントリビュータの作業をレビュー可能になります。
  • セントラル IT と組織アーキテクトは、全てのワークスペースの権限を管理可能となり、作業ごとに何か必要なのかを確実にします。
  • コンポーネントに対する役割を持たないチームは、ワークスペースにアクセスできません。

TFE を効率的に使うには、ワークスペースと権限の分割を、皆さんの組織における権限分割と確実に一致する必要があります。もしもワークスペースの効率的な分割が難しければ、インフラのある領域がベールに包まれ、責任範囲が混乱し、不明瞭になってしまうでしょう。もしもそうであれば、コード化と所有権の境界を改善するために、糸をほぐす機会となるでしょう。

関連するワークスペース間で変更の周知 (Coming Soon)

今後のバージョンでは、TFE はワークスペースをまたがる周知用パイプラインを作成できます。

これまで説明してきたように、各ワークスペースは個々の環境ごとに Terraform 設定ファイルが与えられています。現時点では、コードの周知は手動で行う必要があります。進んだ環境にコードを切り替えるためには、以前の環境におけるコード実行に成功している必要があります。

いずれ、周知関連の設定もできるようになります。バージョン管理システムで直接コードを確認するのではなく、コードを受け入れるだけで、前の環境から新しい環境に切り替えられます。これにより、進んだ環境は正しいコードのみというのを保証します。

変数とポリシーの管理

Terraform Enterprise は変数を設定する複数の場所があり、階層的に相互に上書きできます。全ての階層レベルにおいて、 TFE は Vault に安全に変数を格納します。

Organization

あらゆるワークスペースで、組織レベルに応じたデフォルト変数を使えます。例えば組織においては、全てのリソースが使えるデフォルトの請求タグを指定できるでしょう。

これは階層の最も低いレベルです。続くレベルは上書き可能です。

Workspace

ワークスペースごとの変数です。大部分の変数はワークスペース・レベルに保管されます。これは、AMI ID やマシンのカウント、SSL 証明書等の保管に最も適している場所です。

User

個々のユーザに割り当てる変数です。全てのワークスペースで使うことができ、ワークスペース変数を上書きします。例えば、各ユーザに関連付けられた ARN に使えます。

次へ

これで Terraform Enterprise ワークフローの概要に詳しくなりましたので、皆さんの組織におけるプロビジョニング手順に進むときです。Part2 に続きます。

Part2 : 現在のプロビジョニング手順を評価

Terraform Enterprise は複数ある IT 手順の基礎に依存しています。Terraform Enterprise で協調的インフラのコード化を実装する前に、どの手順を既に使っているか、あるいは実装に何が必要かを理解する必要があります。

以下の本セクションはクイズやインビュー形式です。これまで見てきたように、組織で共通する成熟度に応じて、答えぶは複数の選択肢があります。メモ帳を手にして読み進めましょう。また、組織で自動化とコラボレーションを改善するために疑問があれば、あらゆることをメモしましょう。

このクイズには合格や不合格の基準点はありません。しかし最も重要なのは、皆さんの組織の答えを知ることです。どの IT 手順について最も注意を払うべきかが分かれば、現在の状態から推奨する手順に一直線で進むため、セクション 3 が役立つでしょう。

運用習熟における4つのレベル

運用の習熟度においてレベルが異なるため、それぞれの質問には複数の答えがあります。4つのレベルは以下の通りです。

  1. 手動(Manual)
    • インフラを UI 又は CLI でプロビジョニング
    • 設定変更の履歴を追えず、可視化もない
    • 制限や名前付けに対する適切な標準がない
  2. 半自動(Semi-automated)
    • インフラを UI/CLI 、インフラのコード化、スクリプト、構成管理ツールの組み合わせでプロビジョニング
    • 監査性(traceability)は制限があり、組織ごとに異なった記録手法を用いる
    • 組織ごとに記録手法が異なるため、ロールバックは大変
  3. インフラのコード化(Infrastructure as code)
    • Terraform OSS(オープンソース版)を使ってインフラをプロビジョニング
    • プロビジョニングとデプロイ手続きが自動化されている
    • インフラの設定は一貫性があり、必要である詳細な全てがドキュメント化されている(システム管理者の頭の中でサイロ化されていない)
    • ソースファイルはバージョン管理され、編集履歴がきろくされている。また、必要があれば古いバージョンにロールバックする。
    • Terraform コードのいくつかはモジュールに分割され、組織内における共通的な設計パターンの一貫性を促す
  4. 協調的インフラのコード化(Collaborative Infrastructure as code)
    • 組織内のユーザはお互いが競合せず、かつ、アクセス権限を明確に理解しながら、Terraform を使って安全にインフラをプロビジョニングできる
    • 組織内の上級ユーザは、インフラのテンプレートを標準化できる。また初心者は、組織におけるインフラのベストプラクティスに従いながら、これを利用できる
    • プロダクション環境のワークスペースを守るために、コミッターと承認者に対するワークスペース単位のアクセス制限が役立つ
    • 機能グループは直接 Terraform のコードを書けないが、Terraform Enterprise のユーザインターフェースを通してインフラ状態の可視化と変更を行える

このセクションを最後まで読めば、皆さんの運用習熟度がどの段階にあるか、明確に理解できるでしょう。セクション3では現在の段階から次に進むための推奨する手順を紹介します。

それぞれの質問に対する回答は、皆さんの組織におけるインフラのプロビジョニング、ワークフローの変更、運用モデル、セキュリティモデルの理解に役立ちます。

現在の手順を理解したら、Terraform Enterprise を実装するために、どの段階に進めば良いか認識できるでしょう。

現在の設定とプロビジョニング手順について

皆さんの組織では、インフラの設定とプロビジョニング手順を現在どのように行っていますか。自動化と一貫性のある手順こそが、インフラをより理解しやすく、信頼性があり、トラブルシューティングに費やす時間を減らすために役立ちます。

設定とプロビジョニングがどのレベルか評価するには、以下の質問が役立ちます。

Q1. 現在どのようにしてインフラを管理していますか?

  1. UI 又は CLI を通します。一度限りの作業に対しては、最も簡単な手法に思えるでしょう。しかし、繰り返し行う作業はエンジニアの時間を大きく消費します。また、変更の追跡や管理は困難です。

  2. コマンドライン・スクリプトの再利用を通してか、あるいは UI とインフラのコード化の組み合わせです。単なるその場限りの管理や繰り返し作業に比べ、より速く信頼できる手法です。しかし、一貫性とバージョン管理が欠如しているため、時間の経過とともに管理が困難になります。

  3. インフラのコード化ツール(Terraform、CloudFormation)を通して行います。インフラのコード化により、インフラはスケーラブルで(訳者注;拡大・縮小を柔軟に行える)、再利用性があり、バージョン管理されます。各オペレータの生産性を著しく向上します。また、適切に使えば、環境を横断した一貫性を保てるようになります。

  4. 汎用的な自動化フレームワーク(例:Jenkins + スクリプト / Jenkins + Terraform)を通して行います。これはツールを使いながらも管理ワークフローを集約するため、プロビジョニング・タスクを個々に作る必要はありません。

Q2. サービス・プロバイダのアカウントを、どのように管理しますか?

  1. 1つのアカウントを使う、平らな体制です。全てのインフラを同じアカウントでプロビジョニングします。

  2. 複数のアカウントを使う、平らな体制です。インフラのプロビジョニングには、アカウント環境ごとに異なるインフラ・プロバイダを使います。

  3. ツリー階層です。請求アカウント、監査、セキュリティ、ログ記録アカウント、プロジェクト/環境の用途ごとに、インフラのアカウントを使い分けています。

Q3. 異なる環境のインフラを、どのように管理しますか?

  1. 手動です。全てが手動であり、設定管理は行われていません。

  2. サイロ化しています。アプリケーション・チームごとに、独自の手法でインフラを管理します。あるチームは手動で、あるチームはインフラのコード化やカスタム・スクリプトを用います。

  3. 環境ごとに異なるコードに基づく、インフラのコード化です。インフラをコード化する設定ファイルは、異なるコードを元にしています。そのため、環境内に変更が加えられたとしても周知できず、ある環境の設定は他の環境から追跡できません。

  4. 1つのコードに基づき、環境ごとで違う変数を扱うインフラのコード化です。環境に依存しない全てのリソースを、同じコードでプロビジョニングします。また、変更の周知を確実に行うため、何をデプロイするのか予測可能となる手法です。

Q4. インフラの設定とコードを、どのようにしてチームで協力して共有しますか?

  1. 全くありません。インフラのコード化を行っていません。

  2. ローカルです。インフラの設定はローカルに保存し、メールやドキュメントやスプレッドシートを通して共有します。

  3. チケット管理システムです。変更リクエストや問題/インシデント・チケットによる日々のエントリを通して共有します。

  4. バージョン管理はありませんが、集約しています。コードを共有ファイルシステムに保管し、セキュリティ・グループで安全を保ちます。変更はバージョン管理されません。ロールバックを行える可能性があるのは、バックアップ又はスナップショットによる修復のみです。

  5. 設定ファイルの保管と共同作業をバージョン管理システム上(VCS)(Git リポジトリ、等)で行います。インフラ設定に関するチームの共同作業は VCS ワークフローを通して行います。また、これによりプロダクションに投入する前に、インフラの変更をレビュー可能にします。これが最も成熟した手法です。そのため、記録を保持しながら、異なる部署・異なるチームにおける可視化をもたらします。

Q5. インフラのコード化にあたり、再利用可能なモジュールを書いていますか?

  1. 全てが手動です。現時点ではインフラのコード化をしていません。

  2. モジュール化していません。インフラのコード化は行っていますが、設定ファイルの利用は一度限りがほとんどです。ユーザは通常コードの共有・再利用を行いません。

  3. チームはモジュールを内部で使いますが、他のチーム間では共有しません。

  4. モジュールを組織全体にわたって共有します。ソフトウェアのライブラリを共有するように、インフラの共通パターンをモジュールにするため、更新は1度だけで済み、それが組織全体の利益となります。

変更管理ワークフローについて

プロダクトやシステムにおいて、変更の調整や承認にあたり、変更管理(change control)は適切な工程です。変更管理工程のゴールに含むのは:

  • サービス途絶を最小化
  • ロールバックを減らす
  • 変更に関するコスト全体を削減
  • 不必要な変更を防ぐ
  • ユーザによる変更を、他のユーザに対して影響を与えることなく実施

変更管理ワークフローの習熟度を評価するために、以降の質問が役立ちます。

Q6. インフラに対する変更に対して、どのようにアクセス制御を管理していますか?

  1. アクセスに対する制限がされていないか、監査されていません。プラットフォーム・チームの誰もが柔軟に、全てのインフラを作成、変更、削除します。これにより、再利用できず管理が大変な、複雑なシステムになります。

  2. アクセスに対する制限はありますが、監査はします。これにより、何か事故がおきた後の追跡を容易にします。しかし、インフラの安定性を積極的に守ることはできません。

  3. サービス・プロバイダのアカウント・レベルに基づきアクセス制限を実施します。各チームのメンバが持つ管理権限は、環境ごとに責任範囲が異なるアカウントに基づいています。

  4. ユーザの役割(ロール)に基づきアクセス制限を実施します。全てのアクセスは、インフラのプロバイダ・レベルでユーザの枠割りに基づき制限されます。

Q7. 既存のインフラを変更するのに、どのような手順で行いますか?

  1. リモートマシンにログインし、手動で変更します。繰り返しの手動タスクは非効率であり、人的ミスを引き起こしがちです。

  2. ランタイム構成管理(Puppet、Chef、等)です。構成管理ツールは、信頼できて監査できるコードに基づき、素早く自動的に変更を行います。しかしながら、作成する成果物は毎回同じではありません。特定の設定ファイルのバージョンを使ったとしても、必ずしも 100% の再現性はありません。また、信頼してロールバックできるのは一部のみです。

  3. (イメージ、コンテナの)イミュータブル・インフラストラクチャ(Immutable Infrastructure=訳者注;固定されて変わらないインフラの意味、不変のインフラ)です。固定されたコンポーネントでデプロイされたものは、(個々に置き換えるのと比較して)全てを置き換え可能です。もしも一時的なレイヤ(ephemeral layers)と状態を格納するレイヤ(state-storing layers)間にある明確な境界を管理するのであれば、イミュータブル・インフラストラクチャこそがテスト、検証、ロールバックに最も簡単です。

Q8. アプリケーションをどのようにデプロイしますか?

  1. 手動(SSH、WinRM、rsync、robocopy、等)です。繰り返しの手動タスクは非効率であり、人的ミスを引き起こしがちです。

  2. スクリプト(Fabric、Capistrano、カスタム・スクリプト、等)です。

  3. 構成管理ツール(Chef、Puppet、Ansible、Salt、等)です。あるいは、ユーザデータ・スクリプトを経由して CloudFormation テンプレートや Terraform 設定ファイルに渡します。

  4. スケジューラ(Kubernetes、Nomad、Mesos、Swarm、ECS、等)です。

現在のセキュリティ・モデル

Q9. インフラサービス・プロバイダの認証情報(credential)をどのように管理しますか?

  1. ソースコードに決め打ちします。極めて安全ではありません。

  2. インフラ・プロバイダのロール(AWS では EC2 インスタンス role のように)を用います。サービス・プロバイダはマシンを識別できますので、実際の認証情報のコピーを使うことなく、API リクエストを用いてマシンに対する権限を付与できます。

  3. シークレット(訳者注;SSH鍵やパスワードのような、機密性の高い情報のこと)管理ソリューション(例:Vault、Keywhis、PAR)を用います。私たちはこの手法を推奨します。

  4. 有効期間の短いトークンを使います。これは最も安全な手法の1つです。一時的な認証情報を用いるため、迅速な無効化ができます。そして、攻撃を非常に困難にします。しかしながら、シークレット管理ソリューションを使うよりも、より複雑になりがちです。

Q10. インフラ・プロバイダで、ユーザとオブジェクト保管をどのように管理しますか?(ログイン、アクセスやロールの制限、等)

  1. 共通の adminスーパーユーザ アカウントをエンジニアで共有します。インフラ・プロバイダ・アカウントの抜け道となる可能性が増します。

  2. 個々のユーザ・アカウントです。これにより、認証情報の喪失を引き起こしても、復旧は簡単です。しかし、チームが成長するにつれ、規模の拡大がとても大変になります。

  3. LDAP やアクディブ・ディレクトリとの統合です。アカウントを共有するよりも安全です。しかし、プロバイダから自社ネットワークへの接続が適切に行われる状態を確保するためには、設計上の熟慮を追加する必要があります。。

  4. OAuth や SAML を通したシングル・サインオンです。インフラ・プロバイダにはトークンを基準としたアクセスを可能にします。認証のために、プロバイダが自社ネットワークに接続させる必要はありません。

Q11. 複数のユーザによるインフラ・プロバイダ環境の変更を、どのように追跡しますか?

  1. ログを記録していません。誰がいつ何を行ったかの記録がないため、監査やトラブルシューティングが非常に困難です。

  2. 手動の変更履歴です。共有ドキュメントにインフラの変更点をユーザが書き加えます。この手法は人的ミスを引き起こしがちです。

  3. 監査追跡サービスやログ管理サービス(CouldTrail、Loggy、Splunk、等)のために、全ての API コールを記録します。私たちはこの手法を推奨します。これにより、監査追跡がトラブルシューティングやセキュリティ評価においても確実に利用可能となります。

Q12. 元従業員のアクセスを無効化するには?

  1. 直ちに手動で行います。インフラのコード化を用いていない場合であれば、インフラ・プロバイダのコンソールを使い、手動で過去の従業員のアクセスを削除するのが、最も簡単かつ高速です。

  2. 後ほど、次期リリースの一部として対処します。もしもリリース手順が極めて連結している場合や、プロダクションに反映する前に、セキュリティの変更に変更諮問委員会(CAB; Change Advisory Board)のミーティングに諮る必要がある場合は、遅れがちです。

  3. 直ちにインフラのコード化のホットフィックスを書きます。これが最も安全かつ推奨する手法です。従業員がビルから退出する前に、アクセス権を削除します。

プロビジョニング手順の全体的な習熟度を評価

これら全ての質問に対する内容を検討したら、メモを振り返り、皆さんの組織全体の成熟度がどの段階にあるか評価しましょう。評価によっては、手順がほとんど手動ですか、半自動化ですか、インフラのコード化でしょうか、協調的インフラのコード化でしょうか。

現在の状態を心にとどめたまま、次のセクションに進みましょう。

次へ

現在の手順によって、厳しい表情になっているかもしれません。しかし、これからが改善するときです。

Part 3 プロビジョニング手順を発展するために

本セクションでは、組織における手動プロビジョニング手順を、協調的インフラのコード化に移行する手順を説明します。運用成熟度の各段階において、皆さんの組織が次の段階に進めるように手順を伝えます。最終的には、私たちの推奨するワークフローに到達します。

本セクションを複数のページに分割しました。そのため、既に実装を追えている手順があればスキップできます。Part 2 のメモを読み直し、運用習熟度がどのレベルにあるかを確認しましょう。

Part 3.1 : 手動から半自動に移行するには

インフラ構築を手動で( CLI や GUI ツールを使って)行う結果、インフラは検査が大変で、再構築が困難で、規模の変更が難しく、インフラに対する知識の共有も困難です。

現在、プロビジョニング手順の大部分が手動でしょうか。そうあれば、インフラで小さく管理可能なサブセットに対し、オープンソースの Terraform を使い始めるのが最初のゴールです。Terraform を使い小さな成功を重ねますと、プロビジョニングの成熟度は半自動の段階に進みます。そして、Terraform の利用を拡大しますと、スケールアップができるようになります。

1. Terraform のインストール

こちらの手順に従って Terraform OSS をインストールします(英語)

2. コードを書く

Terraform 設定ファイル を書きます。

3. 導入ガイドを読む

Terraform 導入ガイド を読み進めます。ページではリソースの 変更破棄 や、 リソースの依存関係 の働きなどを通して学びます。

4. 実際のインフラ・プロジェクトに導入

小さな実働中のプロジェクトを選び、そこへ Terraform を導入します。組織における次期プロジェクト一覧から、Terraform の概念実証となるプロジェクトを指定します。あるいは、既存のインフラを Terraform で再実装することも可能です。

プロジェクト選択の鍵は、範囲が限定され、明確な境界線があることです。例えば、AWS 上に新しいアプリケーションのインフラをプロビジョニングするケース。これにより、チームが機能や可能性に圧倒されるないために役立つでしょう。また、 プロジェクト例 から、他の選択肢を感じ取ることもできます。(スタート地点としては AWSの2層例 が良いでしょう )

この時点でのゴールは、構築は小さいながらも、信頼性の中心である Terraform で経験を積むことです。そして、組織内の他人にとっても利点があると証明できます。

次へ

この時点で、プロビジョニング手順の半自動段階に到達しました。リソースのプロビジョニング手や変更のために、組織の1人又は複数人が Terraform のコードを書けます。小規模ですが、インフラのサブセットをコードとして管理し始めることに意味があります。これは他のチームに対してデモを行う良いタイミングです。インフラをプロビジョニングするには、Terraform の設定を書いて実行するだけです。Terraform がいかに簡単かを見せましょう。

次は、更に複雑なインフラのコード化・ワークフローに移行するときです。

Part 3.2 : 半自動からインフラのコード化(Infrastructure as Code)に移行するには

ここでは半自動プロビジョニングとは、次の手順の少なくとも2つの組み合わせであると定義します。

  • Terraform でインフラのコード化
  • 手動の CLI 又は GUI プロセス
  • スクリプト

現在のプロビジョニング手順が以上の状況であれば、次のゴールは Terraform の利用を拡大し、手動の手順や命令的なスクリプトの利用を減らすことです。そして、インフラのコード化をより一貫性をもって使いやすくするために、基礎となる手法を採用することです。

メモ:まだインフラのコード化をインフラの一部でも採用していなければ、次に進む前に、前のセクションをお読みください。

1. バージョン管理の利用

もしも組織で バージョン管理システム(VCS; Version Control System)が使われていなければ、VCS を選択し、導入します。

おそらく最小の Git/Mercurial/SVN サーバを準備できるでしょう。しかし、私たちはより堅牢な協調的 VCS アプリケーションの導入を推奨します。API でのデータ音アクセスや、リポジトリやアカウントの管理が可能なものです。ここでは Bitbucket、GitLab、GitHub が有名なツールです。

既に VCS ワークフロー、レイアウト、アクセス管理手順を確立している場合は、素晴らしい! もしまだであれば、これらを決定する良い機会です(私たちは このアドバイス がスタート地点として相応しいと考えています )。どのような状況下で、誰が変更をマージ可能かを計画します。コードはインフラ全体を管理可能ですので、整合性と品質の維持は非常に重要です。

また、組織における期待を紙に書き出し、チーム間で幅広く共有しておきます。

VCS システムを選定したら、Terraform Enterprise はアクセスできます。現時点で、Terraform Enterprise による統合をサポートするのは GitHub、GitLab、Atlassian Bitbucket(Server と Cloud の両方)です。

2. Terraform コードを VCS リポジトリに置く

インフラのコードをバージョン管理に移行し始めましょう。新しい Terraform のコードは、全てバージョン管理かに置かれるべきです。つまり、既存の Terraform コードはバージョン管理外にあるため、移行を行います。これにより、組織内の誰でも特定の場所を見るだけで、変更の目的や履歴を追跡可能となります。

3. 初めてのモジュール作成

Terraform モジュール (module) は再利用可能な設定ファイルの単位(ユニット)です。これはインフラの部品を1つのパッケージとして管理可能にできます。そのため、主要な設定ファイルを、ワークスペースで何度でも呼び出し・書き込みできます。AWS 用にはオートスケーリング・グループを構成する Terraform モジュールの良い例があります。これは設定と、オートスケーリング・グループ、EC2 Elastic Load Balancer (ELB) を一まとめにします。もし既に Terraform モジュールを使っているのであれば、以下のベスト・プラクティスに従っているかどうかや、皆さんのモジュールを改善可能かどうか見落とさないでください。

次の図はモジュールを書くときに決める手助けとなります:

(フローチャートは提案中です。モジュールは構築パターンに応じて複数のリソースを再利用であるべきで、設定を削減したり、あるいは多くのリソース・タイプに応じてカスタムセットアップしたりします)

4. 知識の共有

Terraform のスキルを他のチームに展開します。そして、これまでのインフラ・チームのスキルを改良します。さらに、内部でのトレーニングや自習についても、検討するかもしれません。

5. ガイドラインの作成

Terraform のコードを書くガイドラインとして使うため、標準構築アーキテクチャを作成します。組織を横断して共有する場合は、モジュールの活用がベストです。そして、インフラを設計周辺で、誰もが持つ期待が共通している場合、その共有がより効果的です。IT アーキテクトは、皆さんの組織が必要とする標準的なアーキテクチャを構築できるように設計すべきでしょう。チーム間を横断する一貫性を保ちながら、高い可用性、柔軟性、障害復旧を考慮した構築を後押しします。

以下はクラウド・プロバイダごとに役立つ構築パターン例です:

6. 構成管理と Terraform を統合

もしも既に組織で構成管理ツールを導入している場合は、Terraform と連携すべきときです。 Terraform プロビジョナ を使えば、リソースの作成後に、設定管理を使った処理を引き渡せます。Terraform はインフラを取り扱うべきであり、他のツールはユーザ・データやアプリケーションを扱うべきです。

あるいは設定管理ツールを使っていない場合、厳密にはイミュータブル・インフラストラクチャではありません。そのため、設定管理ツールの導入を検討すべきでしょう。これは大きなタスクとなりうるのですが、インフラのコード化を採用するのと同じゴールに至るのです。つまり、アプリケーションの設定をより制御可能に、理解可能に、そしてチーム間を横断して再利用可能にするのです。

ここから始めるのであれば、 Chef クックブックを作成するチュートリアル を通して、ローカルの Vagrant でテスト可能です。また組織において 設定管理ツールの何がベストか を決めるのかに関する記事をお薦めします。

7. シークレットの管理

Terraform と Vault を連携するか、他のシークレット管理ツールを使います。サービス・プロバイダの認証情報のようなシークレットは、常に安全を保ち続ける必要があります。しかし、必要に応じて簡単に使えなくてはいけません。ベストな手法は、専用のシークレット管理ツールを用い、必要に応じて割り当てることです。私たちは HashiCorp Vault こそが多くの皆さんにとって最上の選択肢と考えますが、Terraform は他のシークレット管理ツールとも同様に連携可能です。

次へ

この時点で、組織は VCS で設定ファイルを管理し、インフラ管理の鍵となるのが Terraform となり、少なくとも1つ再利用可能な Terraform モジュールを手に入れました。半自動手順と比べ、皆さんの組織は一貫性のある言語とワークローを用いることにより、インフラ設定のより優れた可視化をもたらしました。

次は高度なワークフローが必要です。スケールと、多くの貢献者による権限を委譲可能であることです。

Part 3.3 : インフラのコード化から協調的インフラのコード化に移行するには

バージョン管理された Terraform 設定ファイルを用いることで、インフラ管理の鍵となる技術的な複雑さと一貫性のなさを解消できました。これで基本は抑えましたので、次は他の問題に取り組む準備が整いました。

次のゴールは以下の通りです:

  • チーム間を横断して Terraform の一貫したワークフローを採用
  • 中心となるエンジニアが Terraform コードを直接編集し、Terraform による利益を拡大
  • ユーザとチームに対して、インフラをプロビジョニングする権限の管理

皆さんが直面しているのは、次のレベルにある問題です。これに対処するため、私たちは Terraform Enterprise (TFE) を作りました。以下のセクションでは、より効率的に使うにはどうしたら良いかを紹介します。

メモ:まだ皆さんのインフラの重要な部分で Terraform を使っていないのであれば、以下のステップに進む前に、前のセクションをご覧ください。

1. TFE のインストールかサインアップ

Terraform Enterprise の導入には2つの選択肢があります。SaaS かプライベートへのインストールです。SaaS バージョンを選択する場合は、次のステップを省略できます。そうでなければ、 インストール・ガイド から始めましょう。Terraform は output の出力として TFE の URL を表示します。

2. TFE 実行環境を学ぶ

TFE ではどのように Terraform を使うのか、慣れていきましょう。Terraform OSS では、一般的に外部の VCS ツールを使い、ファイルシステム上にコードを置きます。それからコマンドラインか汎用 CI システムを使い、Terraform を実行します。

TFE は違います。VCS リポジトリとワークスペース(workspace)を直接関連付けます。そして、TFE の UI や API を使い、開始や実行状況を監視します。この運用モデルに慣れるには:

  • Terraform Enterprise で どのように Terraform の実行を設定し、処理するか のドキュメントを読む
  • 概念実証のワークスペースを作成し、Terraform コードを VSC リポジトリを関連付ける。必要に応じて変数を設定し、Terraform Enterprise で Terraform の処理をするとき、コード内で参照する。

3. 組織のワークスペース構造を設計

TFE では、各 Terraform 設定は個々のインフラ・コンポーネントごとに管理されるべきです。また、環境ごとに設定ファイルを設け、ワークスペースは分割されるべきです。言い換えれば、Terraform 設定数 × 環境数 =ワークスペース数です。ワークスペース名は「networking-dev」のような形式です。そのため、一目見るだけで、どのインフラと環境を管理しているのか分かります。

「インフラ・コンポーネント」定義は、皆さんの組織構造に依存します。与えられたワークスペースはアプリケーション、サーバ、あるいはグループに関連するサービスを管理するでしょう。つまり、あるエンジニアリング・チームがインフラをプロビジョンするかもしれません。あるいはビジネス全体で使うインフラの基本部分、このプロビジョニングを共有するかもしれません。

ワークスペースの構造は、皆さんのインフラに対する部門間の責任と一致するようにすべきです。おそらく、最終的には混合型となるでしょう。ネットワークのような複数のコンポーネントは共有し、インフラの基本部分はセントラル IT スタッフによって管理されます。つまり、各エンジニアリング・チームは各アプリケーションに関連する部分しか管理しません。

また、以下の点に注意してください。

  • ワークスペースによっては、他のワークスペースで使うためのデータを出力する
  • ワークスペースは設定ファイルごとに環境(app1-dev、app1-stage、app1-prod)を作るので、コード全体が適切かどうか確認された状態を維持すべく、順番通りに実行すべき

1つ目の連携として、ワークスペース間の連携とはコンポーネントごとに異なります。しかし同じ環境では、ワークスペース間の依存性グラフ(訳者注;ノードの集まりとエッジの集まりで構成されるデータ構造)を作成します。これにまず注意を払うべきです。2つ目の連携は、同じコンポーネントを使うワークスペース間でも、環境が異なる場合は、ワークスペース間のパイプラインを作成します。現時点の TFE には、これらの関連性を処理できませんが、近い将来これらの機能を取り込みます。そして、ワークスペース間の連携について理解しておけば、より簡単に扱えるようになります。

4. ワークスペースの作成

TFE でワークスペースを作成します。そして VCS リポジトリをワークスペースに割り当てます。各ワークスペースはそれぞれが Terraform のコードをバージョン管理システムから読み込みます。ワークスペースごとにリポジトリとブランチの指定が必要です。

私たちが推奨するのはアプリケーションやサービスの全ての環境で、同じリポジトリとブランチを使うことです。Terraform コードを書くとき、環境の差異を変数で扱えます。また、ワークスペースごとに適切な変数を割り当て可能です。しかし、既存のコードでは実践的ではない場合があります。マージ方針によってはワークスペースごとにブランチを分けている場合もあるからです。しかし、私たちはブランチを1つに集約するモデルがベストだと信じています。

VCS ブランチの変更により、マスタにマージすることで、ワークスペースを通したステージング環境、UAT 環境、完全なプロダクション環境を促します。

5. ユーザとチームの作成

皆さんの同僚は、一人一人が TFE ユーザを作成する必用があります。そして組織の導入においては、適切なチームへの追加も可能です。

TFE チームとは、ワークスペースに対する権限を与えられたユーザの一覧です。つまりTFE チームはインフラごとに責任を持っている担当者と一致すべきです。これは、組織図とは一致しない場合もありえますが、組織にわたる人々をどうするかに時間を費やすべきですし、会話すべきです。次の点にご注意ください:

  • あるチームは多くのワークスペースの管理が必要で、あるチームは1つか2つの権限のみ必要
  • チームによっては全てのワークスペースで同じ権限が不要。例えば、アプリケーション開発者はアプリの開発とステージング環境のみ読み書き権限が必要で、プロダクションは読み込みのみ。

協調的インフラのコード化導入で最も難しい部分が、権限を正確かつ完全に委譲するために、どのように管理するかです。

6. 権限の割り当て

チームに対してワークスペースの所有権と権限を割り当てます。各ワークスペースは3つのレベルの権限があります。ユーザやチームごとに、admin、read/write、read-onlyを割り当て可能です。Admin は効率的にワークスペースを所有し、対象ワークスペース上のユーザにする権限を変更可能です。

多くのワークスペースは、複数のチームに対して異なる権限を与えられます。

ワークスペース          チーム権限
----------------------- ------------------------------------
app1-dev                Team-eng-app1: Read/write
                        Team-owners-app1: Admin
                        Team-central-IT: Admin

app1-prod               Team-eng-app1: Read-only
                        Team-owners-app1: Read/write
                        Team-central-IT: Admin

networking-dev          Team-eng-networking: Read/write
                        Team-owners-networking: Admin
                        Team-central-IT: Admin

networking-prod         Team-eng-networking: Read-only
                        Team-owners-networking: Read/write
                        Team-central-IT: Admin

7. Terraform を使わないアクセスの制限

クラウド・プロバイダの UI や API によるアクセスを制限します。インフラのプロビジョニングにおいて、Terraform Enterprise は組織における優先インターフェースです。そのため、TFE を経由しない他のあらゆるアクセスを制限すべきです。ほとんど大部分のユーザは、インフラの変更を手動では行えないでしょう。Terraform ワークフローの組織同意に基づかないためです。

誰もが Terraform を経由することで、コードレビューの手順や TFE ワークスペース権限によって、インフラに対して誰が変更を加えたのか明確に記録できます。これにより、インフラの全てを理解しやすく生業可能になるのです。Terraform Enterprise は1つのワークフローを学ぶだけで、1つの安全なワークフローや、そのほか組織における監査可能なプロビジョニングのためのワークフローとなるのです。

次へ

この時点で、Terraform Enterprise を使った「協調的インフラのコード化」の導入に成功しました。1つのワークフローを使い、複数のプロバイダを横断するインフラをプロビジョニングできます。そして、共通したインターフェースを通し、皆さんの組織における標準的なアクセス制御やコードのプロモーションなどに役立つでしょう。

次はワークフローと手順の改善を進めましょう。

Part 3.4 : 協調的インフラのコード化の高度な改善

これでプロビジョニングに対する協調的インターフェースとワークフローを手に入れました。手順をより改善するためには、決まったフレームワークがあります。

以下の提案は、順番に行う必要はありません。そしてビジネスによっては全て実現する必要はないかもしれません。私たちは可能性を示すだけであり、皆さんが次に何をすべきか、自分自身に問うときのご参考になさってください。

  • 更に手順やリソースを TFE に移行します。TFE の導入に成功したら、まだ残っている手動・半自動のワークフローや手順を移行するチャンスです。私たちが提案するのは、インフラの実行維持に責任を持つ全てのチームにより、自動化の将来的な目標を明確にする発見(discovery)ミーティングの開催です。あるいは、セクション2で用いたガイドのメモをもとに、あるいは古い変更リクエストやインシデント・チケットも使えます。

  • イメージ作成のために HashiCorp Packer の採用。Packer はメンテナンス可能で再利用できるマシンイメージの構築に役立ちます。また Terraform の利便性を倍増できます。

  • Terraform 設定に Sentinel を適用し、ビジネスとコンプライアンスに準拠するように従います。

  • TFE のために監査ログを設定します。Terraform Enterprise プライベート・インストールは、デフォルトで CloudWatch にログを送れます。

  • インフラの監視と性能メトリクスを追加します。これにより、環境のプロモーションが安全になり、アプリケーションのパフォーマンスのセーフガードとなります。多くのツールが利用可能ですが、私たちが推奨するのはインフラ自身の管理と、ユーザ視点でのアプリケーション性能の監視の両方です。

  • TFE API を使います。TFE API を汎用 CI/CD ツールと連携し、あらゆるイベントを Terraform の実行トリガにできます。

原文



ここ数日の動きに関連して、 CoreOS の blog 投稿 で状況がよくまとめられていると思われた投稿がありました。参考情報として翻訳・共有いたします。内容間違い等ございましたら、ご指摘ください。

入れ替え可能なランタイム:containerdとCRI-Oと、Kubernetesユーザに与える影響

Pluggability(プラガビリティ ※1)とは Kubernetes のサクセス・ストーリー(成功談)の一部です。そして、Kubernetes ユーザ体験(user experience)を変えることなく、ストレージ、ネットワーク、スケジューラといった多くのレイヤを置換可能かつ改良可能なのを、コミュニティの皆さんにお約束するものです。今年の初め、 Kubernetes 上でのコンテナ実行をプラガブルにする手法として、Kubernetes プロジェクトはコンテナ・ランタイム・インターフェース(CRI; Container Runtime Interface)と呼ぶ API を作成しました。今週、Kubernetes CRI API を実装する2つのプロジェクトが成熟に向かいつつあります。 CRI-O はバージョン 1.0.0 に到達し、 containerd は 1.0.0-beta.2 ですが間もなくベータを外せる模様です。

(※1 訳者注;Pluggabilityとは、入れ替え可能な機能、の意味。システムなどが Pluggable、つまりプラグを差し替えるように、入れ替え可能なもの。ここではそのままにしました)

これらのリリースはプロダクション(本番環境)利用に向けての初期の通過点(マイルストーン)であり、プロジェクトに関わるチームの皆さんにお祝いを言わせてください。また、プロジェクト初期から今日に至るまでのほとんどの努力は、多くの人々にとって初めて知られることになるかもしれません。そこで、私たちは これらが Kubernetes エコシステムの中で使われるように至った経緯と背景をご紹介します。

もしも、皆さんが Kubernetes を日常でお使いであれば、ここで読むのを止めても構わないでしょう。CRI と Docker Engine、containerd、CRI-O のような様々な実装が目指すのは、ユーザに対する透明性と Kubernetes API から離れるのを、これまでの経験を変えずに実現するためです。これらの大部分は内部のシステム設計に関わる部分ですが、これらの 99% が同じ機能の実装です。似たような例としては、皆さんのノート PC 上における GNU sed 対 BSD sed です。そして、皆さんが CoreOS Tectonic (訳者注;CoreOS社が開発・サポートしている Kubernetes をベースとしたコンテナ管理プラットフォーム)ユーザであれば、デプロイと運用のために、私たちのフルスタックの自動運用と、クラウドおよびオンプレミスの柔軟なインストーラーにより、Kubernetes 内部の設定調整に時間をかけずに行える、ベストな選択肢であると自信をお持ちでしょう。

もしまた Kubernetes や CoreOS Tectonic を試していなければ、 Linux/Windows/macOS に対応した Tectonic Sandbox をお試しいただくか、 クラウド上で自由に お試しください。

コンテナ用語

Kubernetes コミュニティに対する各プロジェクトを扱う前に、まずは用語を簡単に復習しましょう。

  • コンテナ・イメージ(Container images) とは、アプリケーションに対する依存関係全てを、1つの名前のアセット(asset;もの、存在)にパッケージしたものです。これにより、多くのマシン間にコピーできます。これはサーバ上におけるモバイルアプリの考え方と同じです。つまり、アプリの中に全てが入っており、簡単にインストールできます。
  • コンテナ・ランタイム(Container runtimes) とは、Kubernetes エコシステムにおいて Kubernetes システムの内部コンポーネントです。このシステムは、コンテナ・イメージにパッケージ化されたアプリケーションをダウンロードし、実行します。コンテナ・ランタイムの例には containerd、CRI-O、Docker Engine、frakti、rkt があります。
  • オープン・コンテナ・イニシアティブ(OCI)ランタイム仕様(Runtime Specification) とは、コンテナ・ランタイムのスキーマ(仕様)を明確に定義したものです。具体的には userid、bind mount、カーネル名前空間(kernel namespaces)、コントロール・グループ(cgroups)であり、これらはコンテナ・イメージの実行時に作成されます。この仕様はコンテナ・ランタイムの相互運用性を保証するために重要ですが、インフラ管理者が日々で扱う領域ではありません。

ここ数年、コンテナは広範囲かつ急速に広まり、開発者とインフラ管理者らに有名になりました。そして、皆さんが必要としたのは長期にわたるフォーマット(仕様)の安定性と、内部ツールの互換性です。私たちは 2014年に提供を始めた appc から、コンテナ相互運用に関して業界との対話に努めてきました。以降、コンテナ業界の他社とオープン・コンテナ・イニシアティブ(OCI)を組織し、2年の取り組みの後、最近 イメージおよびランタイム仕様 v1.0 の発表に至りました。

containerd が生まれたのは、この努力の一部です。Docker Engine のコードを上書きした containerd は、スタンドアロン(訳者注;単体で動作する、の意味)なコンテナ・ランタイム・コンポーネントです。これは OCI 仕様に則った実装です。そして、OCI が開発したコンポーネントである CRI-O プロジェクトも同様であり、その目標とするのは Kubernetes のためのコンテナ・ランタイム・インターフェースの実装をゼロから行うことでした。そして今、 CRI-O と containerd のどちらもコンテナ・イメージをダウンロード可能であり、OCI ランタイム仕様を用いるコンテナをセットアップし、実行可能になりました。

コンテナ・ランタイムと Kubernetes での動作について

2016年後半にリリースされた Kubernetes 1.5 は、コンテナ・ランタイム・インターフェースを Kubernetes に実装した初めてのバージョンです。抽象化レイヤの基盤は、 Kubernetes プロジェクト SIG Node と、Google や CoreOS やその他の皆さんとの協力作業によるものです。そして、 Kubernetes と他のコンテナ・ランタイム間における API インターフェースを、コンテナ・ランタイム・インターフェース(CRI)として定義しました。2つの要素がゴールです。テストとしてこのインターフェースをモックとして使える API を導入すること。それと、 Docker Engine や CRI-O、rkt、containerd のようなコンテナ・ランタイムを Kubernetes において置き換え可能とすることです。

より詳細な情報については、CRI を Kubernetes で利用可能にするプロジェクトの コンテナ・ランタイム・インターフェースのブログ投稿 をご覧ください。

コンテナ・ランタイム・インターフェースの影響

containerd と CRI-O のようなプロジェクトの開発は興味深く、情報を追う価値がありました。これまでのところ、Kubernetes コミュニティに対する CRI の主な恩恵は、より優れたコードの体系化と、Kubelet 自身が扱う範囲のコード改善でした。得られたコードをもとに、従来よりも高い品質と全面的なテストの両方を得ました。

ほとんど全てのデプロイにおいて、まだしばらくは、私たちは Kubernetes コミュニティが Docker Engine を使い続けると予想しています。なぜならば、新しいコンテナ・ランタイムの導入により、既存の機能性を壊す可能性が潜在しており、既存の Kubernetes ユーザに対して新しい価値を直ちにもたらせないからです。

CRI の働きにより、Kubernetes 内部のコンテナ・ランタイムの入れ替えが簡単になりました。そして、エンド・トウ・エンドのテストも通過しています。これまでの3年、Kubernetes と Docker Engine 間にわたる多くの統合により、依存関係が作り出されました。想定しているのは、ディスクに対するログの保存場所、Linux コンテナ内部、コンテナ・イメージの保管、そして、その他の細かな相互関係です。

依存性に対する取り組みには、抽象化の調整と改良が必要であり、開発には時間を費やすでしょう。そして、containerd、CRI-O、あるいは他の CRI 実装がありますが、プロダクションのほとんどの場面で利用するにあたり、理論的に何がベストなものとしてあり続けるのか、Kubernetes コミュニティで何を変えて行くのかの議論が続くでしょう。

コンテナ・ランタイムの更なる選択肢? 問題ありません

皆さんが Kubernetes ユーザであれば、CoreOS が優れたコンテナ基盤へと案内・導入する手助けを続けますので、ご安心ください。これまで通り、一貫して行います。エコシステムに参加する新しい方には、CoreOS はエコシステムにおける成熟したコンテナ・ランタイムとして、Kubernetes 環境をプロダクションで使うには、Docker Engine と比較して安定性があると CoreOS は評価されています。コンテナ・ランタイムの代替は Kubernetes 利用者に対して大きな意味のある改良ですが、私たちは上位プロジェクトの決定を支持し、私たちはプロジェクトに対して CoreOS Tectonic プラットフォームの選択肢をサポートし続けます。

さらに、Tectonic を利用する皆さんに対して。Kubernetes プラットフォームで避けられない内部変更があったとしても、導入およびアップグレードを独自に自動的に処理できるよう、Tectonic プラットフォーム全体が設計されています。Kubernetes エコシステムでは、将来の Kubernetes リリースに向けて、どのコンテナ・ランタイムを選択するのか評価が続きます。ですが、 皆さんに対しては、柔軟性を発揮するのにベストであり、最も安全な選択肢であるべく Tectonic の準備が整っているのを申しあげます。

エンタープライズへの準備が整った Kubernetes を皆さんの現在の環境で動かすために、Tectonic が最も簡単なのは何故なのか、皆さん自身で確かめたい場合は、 Tectonic をダウンロード できますし、10ノードまでのクラスタをデプロイするまでは無料でご利用いただけます。あるいは、皆さんのノート PC 上で Tectonic を触ってみたい場合は、 Tectonic Sandbox が独自の機能や実験用環境として使えるでしょう。こちらは皆さんのマシン上で動作するものであり、ハードウェアの追加やクラウド・アカウントは不要です。

原文



概要

2017年10月17日、コペンハーゲン(デンマーク)で開催の DockerCon EU 基調講演で、Docker プラットフォームと moby プロジェクトで、 Kubernetes サポートの対応を開始する発表がありました。要点を纏めますと、

  • Docker は Kubernetes に対応します(moby love Kubernetes)
  • Docker for Mac/Winで Kubernetes 動きます(年内にベータ提供開始予定)
  • Swarm も従来通り続けます

関連して ブログも更新 されたので、ご理解の参考程度にと共有します。

Docker プラットフォームと Moby プロジェクトに Kubernetes が加わる

今日私たちは、 Docker プラットフォームが Kubernetes との連携をサポートする発表を行いました。これにより、Docker の利用者と開発者の皆さんは、コンテナ処理のオーケストレートのため、Kubernetes と Swarm の両方を選べます。 ベータ・アクセスのご登録 と、どのように私たちが Kubernetes を使えるようにしているかを詳細を学ぶため、ブログの投稿をご覧ください。

(各ブログの翻訳は、このページの後方にあります)

Docker はアプリケーションとインフラストラクチャ(システム基盤)に跨がるプラットフォームです。Docker 上でアプリケーションを構築すると、開発者や IT 運用者は自由と柔軟さを手に入れられます。 Docker はどこでも実行できますので、エンタープライズにおけるアプリケーションのデプロイを、オンプレミス上(IBMメインフレームだけでなく、エンタープライズ Linux と Windows も含みます)でもクラウドでも可能にします。アプリケーションをコンテナ対応(containerized)しておけば、再構築、再デプロイ、移動を簡単に行えます。それだけでなく、従来のオンプレミス環境とクラウド環境のどちらでも動作するようにセットアップできます。

Docker プラットフォームは多くのコンポーネントを4つのレイヤに構成します:

  • 業界標準コンテナ・ランタイムである OCI 規格を実装する containerd
  • ノード群を分散システムに変換する Swarm オーケストレーション
  • Docker コミュニティ・エディションは、開発者に対してコンテナアプリケーションを開発・移動するワークフローを簡単にします。ワークフローとは、アプリケーションの構成や、イメージ構築・管理などです。
  • Docker エンタープライズ・エディションは、プロダクションにおけるソフトウェアのサプライ・チェーン連携を安全に管理し、コンテナを実行します。

これら4つのレイヤは、オープンソースの Moby プロジェクトの一次コンポーネントで構成されます。

Docker の設計哲学とは、常に選択と柔軟性の提供であり、既存の IT システムと Docker を統合する利用者の皆さんにとって大切です。なぜならば、既にデプロイ済みのネットワーク、ログ記録、ストレージ、負荷分散、CI/CD システムと連携するように Docker が作られているからです。Docker が依存しているのは、業界標準プロトコルや論文、ドキュメント化されたインタフェースです。そして、これら全てにより、Docker エンタープライズ・エディションはデフォルトで実用的です。また、これら標準機能により、皆さんは既存のシステムや望ましいソリューションを利用するにあたり、認証済みのサードパーティ製のものへと置き換え可能なのです。

2016年、Docker はプラットフォームに SwarmKit プロジェクトから導入した オーケストレーションを追加 しました。そしてこれまでの1年、私たちは Swarm に対する多数の建設的なフィードバックをいただきました。セットアップが簡単で、スケーラブルであり、難しい設定を行わなくても安全です、と。

その一方で、Docker プラットフォームですべてをコンテナで管理する利用者の方からもフィードバックをいただきました。コンテナのスケジューリングのために Kubernetes のような他のオーケストレータを使いたいと。あるいは、既にサービスを Kubernetes 上で動作するように設計済みであったり、Kubernetes にこそ求めている機能がある場合にです。これこそが、私たちが Docker エンタープライズ・エディションと Docker for Mac と Windows におけるオーケストレーションのオプションに、(Swarm と並んで) Kubernetes 対応を追加した理由なのです。

さらに、Docker 利用者が Kubernetes オーケストレーションにネイティブ対応した、 Docker アプリケーションのデプロイが簡単になるように、革新的なコンポーネントに取り組んでいます。たとえば、 カスタム・リソース のような Kubernetes の拡張機構を使う場合や、API サーバとの連携レイヤについては、Docker が Kubernetes をサポートする将来のバージョンにより、 Docker Compose アプリケーションを Kubernetes ネイティブの Pod やサービスとしてでデプロイできるようになります。

次期バージョンの Docker プラットフォームでは、プロダクションが Kubernetes で動くようなアプリケーションを、開発者の皆さん自身ワークステーション上で構築・テスト可能となります。そして、運用担当は Docker エンタープライズ・エディションの全ての利点も得られるのです。安全なマルチ・テナンシー、イメージの検査、役割に応じたアクセス制御などを、プロダクションにおけるアプリ実行を Kubernetes あるいは Swarm でオーケストレートできるのです。

私たちが Docker との連携に取り組んでいる Kubernetes のバージョンは vanilla Kubernetes です。こちらは CNCF(訳者注;業界団体”クラウドネイティブ・コンピューティング・ファウンデーション”の略)が監督のもと、皆さんが扱いやすいものです。こちらからのフォークではなく、古いバージョンでもなく、包括および何らかを限定するものではありません。

Docker は昨年より Moby プロジェクトを通して、 Kubernetes の採用と貢献に取り組んできました。既にコンテナ・ランタイムとしての InfraKit 上にある containred と cri-containerd は、Kubernetes インストールにおける作成・管理とオーバレイ・ネットワーク機能用の libnetwork に対して取り組んでいます。サンプルおよび詳細については Moby プロジェクトのブログ投稿(英語) をご覧ください。

Docker と Kubernetes は系統を共有しています。いずれも同一のプログラミング言語であり、コンポーネントや貢献者やアイディアが重複しています。私たち Docker が期待しているのは、 Kubernetes サポートを私たちの製品に取り込み、また、オープンソース・プロジェクトにおいても取り組むことです。そして、私たちは Kubernetes コミュニティを待たずとも、コンテナやコンテナオーケストレーションをより協力かつ簡単に使えるようにします。

Kubernetes をサポートする Docker エンタープライズ(インフラをサポート)とコミュニティ・エディション(Mac と Windows 対応)のベータ版は、今年末に利用可能となります。 準備が整ったら通知を受けたい場合は、サインアップしてください

私たちは Docker におけるオーケストレーションのオプションとして Kubernetes に対応しますが、Swarm に対して取り組み(コミット)続けますし、お客さまや、スケールするプロダクションにおける、クリティカルなアプリケーションを実行する Swarm および Docker に依存している利用者の皆さんに対応し続けます。Docker がどのように Kubernetes を統合するのか詳細を知りたい場合は DockerCon EC の “What’s New in Docker” と “Gordon’s Secret Session” をご確認ください。

原文

Kubernetes 対応 Docker for Mac および Windows

今日、Docker プラットフォームにおける Kubernetes サポートに対する取り組みの1つとして、Docker コミュニティ・エディションの Mac および Windows 版で Kubernetes オプションの追加を発表します。DockerCon でプレビューを実演しており(Docker ブースで足を止めてください!)、ベータプログラムを 2017 年末に準備します。ベータの準備が整ったら通知を受けるにはサインアップしてください。

Docker CE の Mac および Windows で Kubernetes をサポートすると、利用者の皆さんはソフトウエアとサービスを、開発ワークステーションにおけるテストや CI/CD を通し、オンプレミスまたはクラウド上のプロダクションに至るまで、コンテナで管理できるようになります。

Docker for Mac と Windows は Docker 開発環境の調整で最も人気のある手法であり、毎日何十万人もの開発者がコンテナ対応アプリケーションの開発、テスト、デバッグに使われています。Docker for Mac と Window が人気なのは、インストールがシンプルであり、更新は自動的に行われ、macOS や Windows とそれぞれ密接に統合しているからです。

Kubernetes コミュニティは開発ワークステーションで限定的な Kubernetes をセットアップする良い手法を Minikube など(こちら自身も一部は Docker for Mac と Windows の前身である、docker-machine プロジェクトを元にしています)として提供しています。これらソリューションは一般的ですが、docker build → run → test を頻繁に繰り返す設定をするにはトリッキーであり、古い Docker バージョンに依存しています。

Docker for Mac と Windows における Kubernetes サポートが見えてきたので、開発者は docker-compose と Swarm をベースとしたアプリケーションの両方を構築し、Kubernetes 上へデプロイ可能なアプリケーション設計が簡単になります。そのため、ノート PC やワークステーション上で使うには最良の選択肢となるでしょう。全てのコンテナ・タスク(biuld だけでなく run や push )を、イメージ、ボリューム、コンテナが共通の同じ Docker インスタンス上で実行できます。そして、それらは最新かつ良い Docker プラットフォームのバージョンをベースとしているため、Kubernetes デスクトップ利用者に対して マルチステージ・ビルド のような拡張機能を扱えるようにします。

Docker に対する Kubernetes 取り組み成果の一部に、Kubernetes コンポーネントのカスタム・リソースを使う物や、API サーバ統合レイヤがあります。これらにより、Docker Compose アプリを Kubernetes ネイティブ Pot やサービスとしてシンプルにデプロイ可能となります。これらのコンポーネントは Docker EE と Docker CE for Mac と Windows でも提供していきます。

皆さんに Docker for Mac と Windows で Kubernetes が動いているのを早くお見せしたいです。DockerCon EU 17 の Docker ブースにお立ち寄りください。あるいは、ベータ版が利用可能になったときの通知の受け取りをお申し込みください。

原文



概要

HashiCorp の blog に「 HashiCorp Vagrant 2.0 」というブログが投稿されました。例によって翻訳しましたので、参考程度にどうぞ。概要は、Vagrant 1.0 のリリースから今に至るまで様々な改良を施し、昨日安定版としての 2.0 リリースに至ったという内容です。

HashiCorp Vagrant 2.0

HashiCorp Vagrant 2.0 を発表します。Vagrant は開発環境の構築および配布用ツールです。

開発環境のプロビジョニング(訳者注;システム環境の環境構築を自動的に行う動作)において、 Vagrant 2.0 はVirtualBox、VMware、Hyper-V、Docker、AWS、GCP などをサポートしています。Windows や macOS 上で仮想化できるだけでなく、他の多くの新しいオペレーティングシステムにも対応しました。Vagrant 2.0 は Vagrant Cloud と連携し、box を検索・利用できます。Vagrant 1.0 から今日に至るまでは長い道のりでした。サポートしていたのは VirtualBox のみでした。また、リリース以降のコミュニティは著しく成長しました。

Vagrant 2.0 は Vagrrant のウェブサイト からすぐにダウンロードできます。直近の Vagrant リリースに関する変更点の一覧は Changelog からご覧いただけます。

HashiCorp Vagrant

Vagrant は 2009 年から開発が始まり、開発環境とインフラストラクチャ(訳者注;OSを実行可能なシステムおよびネットワーク基盤)の自動デプロイに対して、瞬く間に頼りになるツールとなりました。プロダクション(本番環境)の鏡となる開発インフラの構築を、1つのワークフローで作成することが Vagrant の目的です。

20013 年に安定版(stable)として Vagrant 1.0 がリリースされました。Vagrant 1.0 はプロバイダ(訳者注;Vagrantにおける用語で、インフラを操作する API ドライバのこと)としてサポートしたのは VirtualBox のみでした。また、Linux ゲスト OS としてサポートしていたのは一部のみです。それに、サポートしていたのは単純な起動(up)/停止(destroy)のワークフローのみでした。Vagrant 1.0 以降、私たちは VMware と Docker といった複数のプロバイダに対するサポート追加や、Windows と macOS のようなゲストの追加、そしてスナップショットを含む複雑なワークフローを追加しました。これらの主な変更は何百もの改良とバグ修正によるものです。

Vagrant 登場以前の開発環境は、ほとんどが手作業での構築、エラー解決であり、時間を浪費しました。また、インフラの自動デプロイには、実際のマシンを作成・破棄するように、極めて長いフィードバック・サイクル(訳者注;試行錯誤の繰り返し)がありました。Vagrant は、これら両者のプロセスを1つのコマンドで行えるように変えたのです。

HashiCorp Product suite は、あらゆるアプリケーションをあらゆるインフラ上にプロビジョンし(訳者注;自動的なインストールや設定)、安全であり、接続し、実行できるものであり、Vagrant はその一部です。Vagrant で開発環境のプロビジョンが可能ですし、HashiCorp Packer で Vagrant イメージを構築できます。そして、HashiCorp Terraform でインフラを構築し、Vault でシークレット(訳者注;APIやSSH鍵などの機密データ・情報)管理を扱い、Nomad でワークロードのスケジュール(訳者注;どのノードまたはホスト上で、どのようなジョブまたはプロセスを実行するか決めること)をし、Consul でインフラを連結します。

コミュニティとチーム

私たちは Vagrant 2.0 を作り上げたコミュニティと Vagrant コアチームに感謝を申しあげます! HashiCorp Vagrant は過去7年で 750 人以上の貢献者がいらっしゃいます。何年もの間、貢献者の皆さんが機能を追加し、バグを修正し、Vagrant を前へと進めました。

Vagrant 互換性の領域が広がるにつれ、プロジェクトの維持にはコミュニティによる改善が不可欠でした。私たちのコミュニティには、あらゆる種類のプロバイダ、あらゆるオペレーティングシステム、あらゆるプロビジョナー等の専門家に溢れています。これらコミュニティのメンバーが協力し、多様性を持つツールとして作り上げたのが Vagrant なのです。

HashiCorp の Chirs Roberts が 2.0 に向けての変更を牽引しました。2016 年にプロジェクトの責任者となり、バージョン 2.0 に至るために不可欠である、重要な安定性に関する課題に取り組みました。Chris は Brian Cain および Justin Campbell と連携し、3人が一丸となって毎日 Vagrant の改善に取り組んでいます。

原文



概要

先日の 【参考訳】HashiCorp Terraform 0.10 に続き、数々の変更に伴う説明が書かれている Upgrading to Terraform 0.10 も重要だと思い、参考情報として翻訳しました(8月4日現在)。皆さまのアップグレードの手助けになればと思っています。

Terraform v0.10 へのアップグレード

Terraform v0.10 はメジャー・リリースです。従って、アップグレードにあたっては、検討が必要な複数の変更を伴います。当ガイドは、この検討の手助けとなるのを目指します。

ガイドの目的はアップグレードにあたり、一般的な懸念事項や課題解決に役立つ詳しい説明や背景を扱います。全ての変更項目は Terraform 変更履歴(Changelog) で常に網羅しています。このガイドを読み終えたら、リソースをプロバイダの利用に対して、変更履歴にある各項目の確認をお勧めします。

特にこのガイドでは v0.9 から v0.10 の変更に焦点をあてています。これまでのメジャー・リリースにも、それぞれに更新ガイドがあります。古いバージョンをお使いの場合は、必要に応じて各ガイドを直接ご覧ください。

プロバイダ・プラグインの分離

v0.10 現在、主となる Terraform 配布物(パッケージ)にはプラグインを同梱しません。そのかわり、プラグインは戸別配布となり、 terraform init コマンド で自動的にインストールします。

長期的には、この新しい手法はあらゆる皆さんに役立つでしょう。たとえば、特定のプロバイダをアップグレードして新機能に対応したいけれども、変更によって他プロバイダの互換性問題が心配な場合です。短期的には、配布パッケージが小さくなりますし、全く使わない多くのプロバイダをダウンロードする必要もありません。

また、プロバイダ・プラグインは Terraform 本体とは個別にバージョン管理されます。 バージョン制限(version constraints) を使えば、新しいメジャー・リリース(破壊的な変更を含む可能性)があったとしても特定のバージョンを利用し続けられます。

対策 :アップグレード後は、必要なプロバイダ・プラグインをインストールするために、各 Terraform 設定ファイルのある作業ディレクトリで terraform init を実行します。もしも自動処理で Terraform を使っている場合は、バージョン・コントロールから Terraform 設定をクローンした直後の手順として、こちらのコマンド実行が必要です。また、必要なモジュールのインストールが必要だったり、リモート・バックエンドの設定が必要になったりするでしょう。

対策 :「プロダクション」(本番環境)向けの設定にあたっては、 terraform init の出力で推奨される プロバイダのバージョン指定 の追加をご検討ください。この対策をしておけば、プラグインが将来的にバージョンアップしても、新しいメジャー・バージョンの自動インストールを防げます。

サードパーティ製のプロバイダ・プラグイン

プロバイダ・プラグインを分割しての初リリースで影響を受けるのは、HashiCorp がパッケージ化してリリースしているプロバイダに対してのみです。この方向性は、サードパーティ製プラグインの定期的サポートと似たような手法を目指しています。しかし、このような状態が一般的になる前に、私たちはインストールとバージョン管理の堅牢な仕組みを確保したいのです。

それまでの間、 サードパーティ製プロバイダをインストールする主な仕組み はサポートが続きます。サードパーティ製プロバイダのメンテナは、バイナリの名前による新しいバージョン管理メカニズムをオプションで取り入れることになるでしょう。例えば terraform-provider-名前-v0.0.1 の “0.0.1” にあたる部分を使う枠組みです。Terraform は セマンティックバージョン管理(semantic versioning) 手法をプロバイダが使っているとみなします。

しかしながら、現時点においてはサードパーティ製のプロバイダは自動的にバージョンを指定したインストールができません。 いずれ Terraform 0.10 は設定ファイルを通して指定されたバージョンをインストールするかどうか確認し、もしも指定されたバージョンが使えなければエラーがでるようになります。

対策 :直ちに対策は不要ですが、サードパーティ製プラグインのメンテナは、利用者が今後のバイナリ配布にあたってバージョン番号を使えるよう、オプションとしての検討を始めたら良いかもしれません。

-target を使った再帰的なモジュール対象

-target 引数で各モジュールの場所を指定すると、(必要な)リソースの全てをターゲット(対象)にできるでしょう。

 $ terraform plan -out=tfplan -target=module.example

このコマンドは、 0.10 までは指定したモジュールのリソース のみ を、直接の対象としていました。0.10 では挙動が変わり、コマンドの実行によって、 派生した モジュールも対象リソースとして含みます。

たとえばモジュール自身が module.example であれば、 先ほどのコマンドを実行すると、対象となるリソースは module.examplemodule.example.module.examplechild の両方です。

また、 リソース割り当て(resource addressing) 構文を使う Terraform の機能も使えます。ここでは terraform state と同じサブコマンドを含みます。

対策 :Terraform の自動処理で -target を使っている場合は、指定しているリソースに子モジュールがあったとしても、何ら動作上の問題がないのを確認します。 -target を使う場合は plan のレビューにあたり、作業にあたって必要なリソースのみインストールするのを、確実に確認してください。 -target を定常的に使うのは推奨しませんので、どうかご注意ください。これは例外的な利用であり、手動での介入なのです。

terraform apply のインタラクティブな承認

Terraform 0.10 から、plan 時にインタラクティブな確認による一時停止があれば、 terraform apply は新しいモードになり、plan 時に確認した項目のみ適用(apply)します。これは terraform plan を個々に実行可能な利便性を得るためですが、インタラクティブなコマンド入力がワークフローの簡素化に影響を与えてしまいます。

これまでのラッパー・スクリプトが期待通りに動かなくなるのを防止するため、0.10 ではこの機能は無効がデフォルトです。もし、こちらの挙動を使いたい場合は、特定の plan ファイルを指定せずに terraform apply 時に -auto-approve=false を指定します。

Terraform の将来的なバージョンでは、この挙動がデフォルトになるよう計画しています。そのため、ただちに対策は不要ですが、将来的な変更に備え、Terraform の自動化もしくはラッパーを用いている場合は、次の手法による調整を強く推奨します。

  • プロダクションのシステムに関わるインタラクティブではない自動処理では、 terraform plan -out=tfplan と、その後の(承認後の) terraform apply tfplan常に 分けるべきしょう。これは作業者が適用する(apply)前にレビュー(確認)する機会を設けるためです。

  • プロダクション以外 のシステムにおいて、plan ファイルのない自動処理で terraform apply を実行する場合、 -auto-approve=true をコマンドラインに追加するだけで、現在の 0.10 の挙動である自動承認がデフォルトで有効になります。

私たちは多くのチームがラッパー・スクリプトや自動化で Terraform をご利用されているのを把握しています。そのため、このような変更にあたり、移行期間を設けます。また、各チームには将来的な変更に備え、ツールを更新するための機会を確実に設けていただければと思います。

対策 :0.10 はデフォルトでは以前の挙動と同じため、今すぐの対策は不要です。しかしながら、Terraform をラップしているようなツールのメンテナは、自動処理をするか別のコマンドライン UI を使うかどうかにかかわらず、将来的なバージョンに備えて活用方法や -auto-approve=... フラグを使うかどうかの明確な決定を考慮すべきでしょう。

原文