8
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

フューチャーAdvent Calendar 2023

Day 3

かゆいところに手が届く、Terraformの書き方 (configuration_aliasesの使い方)

Last updated at Posted at 2023-12-03

こんにちは。TIGの伊藤太斉です。
この記事はフューチャー Advent Calendar 2023の3日目の記事です。
さて、今年の私自身のIaC事情を振り返ってみると、だいたい半年くらいはAnsibleのみを主として読み解いたり、書いたりしていたので、Terraformerとして何かする、ということが結構抜け落ちていた1年でした。来年もTerraformやっていきたい所存です。
そんなブランクがある中でも4Qからはまた触り始めており、今は現在のプロジェクトの将来を見据えたTerraformのリファクタリングも自分の1つのバリューとしているわけですが、今回はそんななかで出てきたネタです。

はじめに結論

configuration_aliasesを使うことでモジュールを利用しているときも柔軟にプロバイダーを利用できる。

本題

今回はAWSを例として書いていきます。

マルチプロバイダーな使い方

Terraformでは、例えばAWSのプロバイダーを利用する時、最低限であれば以下のような書き方で済みます。

provider "aws" {
  region = "ap-northeast-1"
}

上記のように書くことでTerraformでどのクラウドサービスに対して、どのリージョンに対してリクエストを投げるか仕分けています。ここでリージョンを書かなくても、各リソースで定義することはできますが、毎回書くのは冗長かつ、ヒューマンエラーを招くことも考えると、あまり現実的ではないでしょう。
次に、投げるリージョンが2つ以上になる時は、上記のブロックを2つ以上設定し、2つ目以降にはaliasを指定して、呼び出すときにはここで指定した値を利用します。東京リージョン(ap-northeast-1)とバージニアリージョン(us-east-1)を利用する時の例で言うと以下の形です。

provider "aws" {
  region = "ap-northeast-1"
}

provider "aws" {
  alias  = "ue1"
  region = "us-east-1"
}

# 実際にリソースに定義する場合
resource "aws_hogehoge" "sample_resource" {
  provider = aws.ue1
  ...
}

さらに、複数の環境を管理している時は、環境ごとシークレット分けるケースもあります。シークレットはaws configureコマンドで設定し、このときに--profileの引数にプロファイル名を設定します。設定したシークレットをTerraformで利用する場合、以下のようにprofileに指定して書くことができます。

provider "aws" {
  profile = "profile-name"
  alias   = "ue1"
  region  = "us-east-1"
}

さて、この3つがプロバイダーを利用するときによく使うパラメータになりますが。モジュールで利用するときに、困ったことが私にありました。うまくプロファイル(権限)が使えない、と。
実際にどう埋めようかとしていた話ですが、モジュール定義側にてproviderに渡すパラメータをvariableにて変数化して、プロファイル名を渡す形式を取っていました。

# モジュール定義側
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  profile = var.profile
  alias   = "ue1"
  region  = "us-east-1"
}

variable "profile" {
  type = string
}

# モジュール呼び出し側
module "test" {
  source  = "some_dir"
  profile = "profile-name"
}

上記の書き方だと、権限が当たっていないエラーにかかりました。実際に試してはいないですが、モジュール定義側にプロファイル名をハードコードしたらできたかもしれません。ただ、モジュールはTerraformの再利用性を高めるために使われる重要な機能でもあり、プロファイルは環境ごと用意する前提があったので、別の方法を考えていました。
ひとまず、これまでの変数定義をまとめると、以下のようになります。

モジュール定義側 呼び出し側
region
alias
prifile 変数では定義できない

そこで、configuration_aliases

プロバイダー周りを中心に調べているときにconfiguration_aliasesに出会いました。公式の文を引用します。

To declare a configuration alias within a module in order to receive an alternate provider configuration from the parent module, add the configuration_aliases argument to that provider's required_providers entry. The following example declares both the mycloud and mycloud.alternate provider configuration names within the containing module:

モジュール内部でconfiguration_aliasesにエイリアスを定義しておくことで、代替する(エイリアスに載せる)ものを入れ込めるパラメータだそうです。
実際に先ほど書いたソースを直してみることにします。

# モジュール定義側
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
      configuration_aliases = [ aws.ue1 ]
    }
  }
}

# モジュール呼び出し側
module "test" {
  source = "some_dir"

  providers = {
    aws.ue1 = aws.ue1
  }
}

provider "aws" {
  profile = "profile-name"
  alias   = "ue1"
  region  = "us-east-1"
}

これで、プロファイルとリージョンを合わせて設定することができるようになりました。そのため、モジュール定義側で

  • providerを設定していないリソース→ap-northeast-1
  • providerを設定しているリソース→us-east-1

と使い分けができるようになりました。

余談) providersブロックを用いた別の使い方

上記では1つのモジュールに対して複数のリージョンを含めたいケースで利用しましたが、aws.ue1に対して利用するプロバイダーの情報を渡すのではなく、aws自体(デフォルトで使うプロバイダー)に設定を入れることができます。
何が良いかというと、モジュールのポータビリティがさらに向上するという点です。例えば以下のような書き方ができます。(参考)

# モジュール呼び出し側
## エイリアスをはっていないプロバイダーを利用する
module "test_ane1" {
  source = "some_dir"
}

## エイリアスをはったプロバイダーを利用する
module "test_ue1" {
  source = "some_dir"

  providers = {
    aws = aws.ue1
  }
}

provider "aws" {
  region  = "ap-northeast-1"
}

provider "aws" {
  alias   = "ue1"
  region  = "us-east-1"
}

上記で、呼び出すモジュールは同一ながらも、プロバイダーの情報を切り替えることで、別リージョンへ同一のモジュールを当てることができます。モジュールの中身にはある程度の考慮(命名のユニークさなど)はあるにせよ、TerraformもといIaCのメリットを享受できる記法だと思いました。

どんなときに使うか

使い方を知ったうえで、どんなところに使い所があるか考えましょう。
1つのモジュールで複数リージョン利用したい時はどんな時でしょうか?いくつか例を考えていきます。

バックアップを他リージョンで展開する場合

クラウド基盤とは言えど、実態として動いているのは物理サーバです。ここも含めてリージョン障害が起きたとき、サービス断になることは好ましくありません。そこで、クラウドでは地理的に明確に離れたリージョンへの展開を容易にすることで、DRを考えやすくしてくれます。
AWSではAWS Backupがマネージドで各種バックアップを取ってくれるサービスですが、これをマルチリージョンで展開するときにモジュール1つで起き上がってくれたらすごく便利です。

フロントの構成

フロントの構成では、CloudFrontを最前面に配置した上でバックエンドに各種LBを下げるパターンがよく使う方法でしょう。

まとめ

今回は自分自身すごく学びになったconfiguration_aliasesだけで記事を書いてみました。
無事痒いところに手が届いたのでぐっすり寝れる日々で、また良い年末を迎えられそうです。
Terraformはまだまだ便利になる機能がたくさん出てくるので、楽しみですね!

4日目は澁川さんの記事です。お楽しみにしてください!

8
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?