🤷🏻‍♀️

TerraformでAWS環境を作る時にハマったこと

2022/02/27に公開

お仕事で、TerraformでAWS環境を作る機会をいただいています。
IaC自体を触るのがまだまだ慣れないですが、同じ失敗を繰り返さないために、ハマったところをメモとして残していこうと思います。
初歩的な認識誤りも多いかと思いますが、暖かく見守っていただけるとありがたいです😅

EC2インスタンス関係

IAMロールとインスタンスプロファイル

  • IAMロールをEC2インスタンスに紐つける時は、インスタンスプロファイル(aws_iam_instance_profile)のリソースが必要。
    • インスタンスプロファイルを新たに作って、そのnameを指定する。
    • IAMロール(aws_iam_role)のnameを指定してもダメだった。

NG例


resource "aws_instance" "temp-instance" {
  ami                         = data.aws_ami.instance_ami.id
  instance_type               = "t3.medium"
  subnet_id                   = aws_subnet.public_subnet_1a.id
  associate_public_ip_address = true
  # ↓↓↓↓↓ここでIAMロールのリソースのnameを指定してしまっている↓↓↓↓↓
  iam_instance_profile        = aws_iam_role.instance_iam_role.name 
  vpc_security_group_ids = [
    aws_security_group.instance_sg.id,
  ]

  # -------------------------省略-------------------------

}

修正後


# ↓↓↓↓↓IAMロールのリソース名を参照して、インスタンスプロファイルのリソースを作成する↓↓↓↓↓
resource "aws_iam_instance_profile" "temp_instance_profile" {
  name = aws_iam_role.instance_iam_role.name
  role = aws_iam_role.instance_iam_role.name
}

resource "aws_instance" "temp-instance" {
  ami                         = data.aws_ami.instance_ami.id
  instance_type               = "t3.medium"
  subnet_id                   = aws_subnet.public_subnet_1a.id
  associate_public_ip_address = true
  # ↓↓↓↓↓ここではインスタンスプロファイルのリソースのnameを指定する↓↓↓↓↓
  iam_instance_profile        = aws_iam_instance_profile.temp_instance_profile.name
  vpc_security_group_ids = [
    aws_security_group.instance_sg.id,
  ]

  # -------------------------省略-------------------------

}

エラー時のメッセージ

Error: Error launching source instance: InvalidParameterValue: Value (play-space-dev-instance-iam-role) for parameter iamInstanceProfile.name is invalid. Invalid IAM Instance Profile name

  • インスタンスプロファイルの名前が無効です、とのこと。
    • そもそもインスタンスプロファイルが理解できていなかったので反省。

参考リンク

沼から抜け出した後の感想

  • 構成要素をきちんと理解するの、大事。

WAFv2関係

WebACL内でルールグループ参照のstatementを使用する時

  • WAFv2のWebACL作成時、ルールグループ参照のstatementを使用する場合は、同じruleブロック内にoverride_actionのブロックが必須
    • override_actionの中身はnone{}またはcount{}
    • マネージドルールもルールグループであるため、同様にoverride_actionのブロックが必須

NG例


resource "aws_wafv2_web_acl" "example" {
  name        = "${var.project}-${var.environment}-webacl"
  description = "Example web acl"
  scope       = "REGIONAL"

  default_action {
    block {}
  }

  rule {
    name     = "rule-1"
    priority = 1

    statement {
      # ↓↓↓↓↓ルールグループ参照のstatement↓↓↓↓↓
      rule_group_reference_statement {
        arn = aws_wafv2_rule_group.example.arn
      }
    }

    visibility_config {
      cloudwatch_metrics_enabled = false
      metric_name                = "wafv2-rule-group-metric"
      sampled_requests_enabled   = false
    }

    # !!!!!ruleブロック内にoverride_actionの指定をしていない!!!!!
  }

  rule {
    name     = "rule-2"
    priority = 2

    statement {
      # ↓↓↓↓↓マネージドルールもルールグループなので、ここもルールグループ参照のstatement↓↓↓↓↓
      managed_rule_group_statement {
        name        = "AWSManagedRulesAmazonIpReputationList"
        vendor_name = "AWS"
      }
    }

    visibility_config {
      cloudwatch_metrics_enabled = false
      metric_name                = "wafv2-rule-group-managed-ipreputationlist-metric"
      sampled_requests_enabled   = false
    }

    # !!!!!ruleブロック内にoverride_actionの指定をしていない!!!!!
  }

  visibility_config {
    cloudwatch_metrics_enabled = false
    metric_name                = "wafv2-webacl-metric"
    sampled_requests_enabled   = false
  }

}

修正後


resource "aws_wafv2_web_acl" "example" {
  name        = "${var.project}-${var.environment}-webacl"
  description = "Example web acl"
  scope       = "REGIONAL"

  default_action {
    block {}
  }

  rule {
    name     = "rule-1"
    priority = 1

    statement {
      # ↓↓↓↓↓ルールグループ参照のstatement↓↓↓↓↓
      rule_group_reference_statement {
        arn = aws_wafv2_rule_group.example.arn
      }
    }

    # ↓↓↓↓↓ruleブロック内にoverride_actionブロックを入れる↓↓↓↓↓
    override_action {
      count {}
    }

    visibility_config {
      cloudwatch_metrics_enabled = false
      metric_name                = "wafv2-rule-group-metric"
      sampled_requests_enabled   = false
    }
  }

  rule {
    name     = "rule-2"
    priority = 2

    statement {
      # ↓↓↓↓↓マネージドルールもルールグループなので、ここもルールグループ参照のstatement↓↓↓↓↓
      managed_rule_group_statement {
        name        = "AWSManagedRulesAmazonIpReputationList"
        vendor_name = "AWS"
      }
    }

    # ↓↓↓↓↓ruleブロック内にoverride_actionブロックを入れる↓↓↓↓↓
    override_action {
      count {}
    }

    visibility_config {
      cloudwatch_metrics_enabled = false
      metric_name                = "wafv2-rule-group-managed-ipreputationlist-metric"
      sampled_requests_enabled   = false
    }

  }

  visibility_config {
    cloudwatch_metrics_enabled = false
    metric_name                = "wafv2-webacl-metric"
    sampled_requests_enabled   = false
  }

}

エラー時のメッセージ

Error: Error creating WAFv2 WebACL: WAFInvalidParameterException: Error reason: You have used none or multiple values for a field that requires exactly one value., field: RULE, parameter: Rule

  • 正確に1つの値が必要な場所に、値が設定されていない、または複数の値が設定されている、とのこと。
    • なかなか直感的にわからず、結構ハマっておりました・・・

参考リンク

  • aws_wafv2_web_acl(Terraformのドキュメント)
    • ドキュメントに、ちゃんと以下の記載がありました・・・

      override_action - (Optional) The override action to apply to the rules in a WebACL. Required and used only for rule statements that reference a rule group, like rule_group_reference_statement and managed_rule_group_statement. See Override Action below for details.

沼から抜け出した後の感想

  • (Optional)と書いてあっても、必須の場合がありました。しっかりドキュメントを読んで実装しようと思います。

本記事は、今後もハマるたびに追記していく予定です。
今は一つの記事にしていますが、項目が増えてきたら分割も考えています。

私と同じところでハマる人が少しでも減りますように・・・!

Discussion