Terraform

Terraform ElastiCache Redis 6.x の差分出力回避

こちらのドキュメント記載の通り、ElastiCache Redis はバージョン6からOSS のメジャーリリースごとに一つのバージョンが提供され、マイナーバージョンは自動的に設定されるようです。

実際、コンソール画面でバージョンを選択しようとすると6.xとなります。


この影響のためかTerraformでRedis6を設定の際、予期せぬ差分が出力されてました。
その回避方法をメモっておきます。

スポンサーリンク

事象

tfファイルのengine_versionに6.xと記載すると、初回 apply 時(新規作成時)は正常に実行できるのですが、2回目以降の apply では以下のような差分が出力されてしまいます。

$ cat main.tf

...
resource "aws_elasticache_replication_group" "main" {
  engine                        = "redis"

  ### 6.xを指定
  engine_version                = "6.x"  
...
}
$ 
$ terraform apply
...
  # aws_elasticache_replication_group.main will be updated in-place
  ~ resource "aws_elasticache_replication_group" "main" {
...
        engine                        = "redis"

  ### 差分として検知されてしまう
      ~ engine_version                = "6.0.5" -> "6.x"  
...


そして、このまま yes ですすめるとエラーとなってしまいます。

  Enter a value: yes

aws_elasticache_replication_group.main: Modifying... [id=redis-main]

Error: error updating ElastiCache Replication Group (redis-main): error requesting modification: InvalidParameterCombination: No modifications were requested
	status code: 400, request id: xxxx-yyyy-zzz

  on main.tf line 71, in resource "aws_elasticache_replication_group" "main":
  71: resource "aws_elasticache_replication_group" "main" {

$

差分出力の回避方法

なにかのしがらみなどで、1つ目のAWSプロバイダのバージョンアップが適用できない人もいるかもなので、3つほど回避策を記載します。

AWSプロバイダのバージョンアップ

こちらのissueの通り、AWSプロバイダのv3.38.0で対応されました。

それ以降のVersionへアップデートします。

### バージョン確認。terraform.io/hashicorp/aws が v3.38以上であればOKです
$ terraform version
Terraform v0.13.5
+ provider registry.terraform.io/hashicorp/aws v3.37.0

...
$
$ cat provider.tf
terraform {
  required_version = "0.13.5"
  backend "local" {}

  required_providers {
    aws = {
      source = "hashicorp/aws"
   
  ### 3.38以上にします。
      version = ">= 3.38"
    }
  }
}

...


tfファイルでバージョンを設定した後、init で忘れずにプラグインをダウンロードします。

$ terraform init

Initializing provider plugins...
- Finding hashicorp/aws versions matching ">= 3.38.*"...
- Installing hashicorp/aws v3.42.0...
- Installed hashicorp/aws v3.42.0 (self-signed, key ID xxxxx)
...


で確認。OK!

$ terraform apply
...
aws_elasticache_replication_group.main: Refreshing state... [id=redis-main]

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

その他の回避方法

engine_versionをignore_changes

気軽にAWSプロバイダのバージョンアップできないような環境でしたら素直にignoreでしょうか。

resource "aws_elasticache_replication_group" "main" {
...
  engine_version                = "6.x"
...

  lifecycle {
    ignore_changes = [engine_version]
  }
}


engine_versionを直接記述

それかバージョンを明記しておきたければ、一度 6.x で新規作成した後であれば可能です。

$ cat main.tf
...
resource "aws_elasticache_replication_group" "main" {
  engine                        = "redis"

  ### バージョンを直接指定
  ### engine_version            = "6.x"
  engine_version                = "6.0.5"
...
}


新規作成の時点で、いきなりバージョンを明記すると(正しい挙動だとは思いますが)以下のように怒られます。。orz

$ terraform apply

Error: engine_version: Redis versions must match <major>.x when using version 6 or higher, or <major>.<minor>.<bug-fix>

  on main.tf line 76, in resource "aws_elasticache_replication_group" "main":
  76:   engine_version                = "6.0.5"


$

Tips

ちなみにこのAWSプロバイダのバージョンアップで、tfファイルのセキュリティグループの箇所の修正が必要になりました。(このissueが関連してる?)

こちらの公式ドキュメント記載の通り cidr_blocks とself を同時に設定してると、以下のようにエラーになるため(自分のケースでは)self を削除しました。

$ cat main.tf
...

resource "aws_security_group_rule" "ingress-443" {
  type      = "ingress"
  from_port = "443"
  protocol  = "tcp"
  to_port   = "443"

 ### cidr_blocks と selfの同時記載がエラー
  cidr_blocks  = ["10.0.1.0/24"]
  self         = false

...

}
$
$ terraform apply
...
Error: ConflictsWith

  on main.tf line 27, in resource "aws_security_group_rule" "ingress-443":
  27:   cidr_blocks       = ["10.0.1.0/24"]

"cidr_blocks": conflicts with self


Error: ConflictsWith

  on main.tf line 29, in resource "aws_security_group_rule" "ingress-443":
  29:   self      = false

"self": conflicts with cidr_blocks
...

$


今回は以上です〜ノシ

参考

アリガト━━━ヾ(´∀`)ノ━━━━♪

公式ドキュメント Redis 用 ElastiCache バージョン 6.x (拡張)
terraform-provider-aws Elasticache redis 6.x support