コンテンツにスキップ

webacl pattern

概要

webacl patternは、AWS WAFリソースを作成するモジュールです。 デプロイを行うことができる対象は以下になります。

  • Amazon CloudFront(以下、CloudFrontとする)
  • Application Load Balancer(以下、ALBとする)
  • Amazon API Gateway

AWS WAFを利用することで、前述した各エンドポイントに対する様々な条件(Statement)によるアクセス制御を行うことが可能になります。 詳細はAWS公式のドキュメントをご参照ください。

AWS WAFは具体的なStatementを定義するルールグループと複数のルールグループをまとめたWebACLで構成されます。 ルールグループは利用用途に応じて様々な定義パターンが想定されることから、本patternではWebACLの作成のみを行います。 そのため、本patternを利用する際は事前にルールグループを作成しておく必要があります。

想定する適用対象環境

webacl patternは、Runtime環境で使用されることを想定しています。

依存するpattern

webacl patternは、WAFを適用する対象によって事前に実行する必要のあるpatternが変化します。

  • CloudFrontでWAFを利用したい場合
    • 事前に実行の必要なpatternはありません
  • ALBなどでWAFを利用したい場合
    • WAFを適用したいリソースを事前に作成しておく必要があります
    • ALBの場合、Eponaでは以下のpatternが該当します
pattern名 利用する情報
public_traffic_container_service pattern WAFの適用対象となるALB

⚠️ ルールグループはAWS WAFを利用したいリージョン(CloudFrontで利用したい場合はGlobal)に作成しておく必要があります。

⚠️ CloudFrontでWAFを利用したい場合は本patternでWebACLを作成した後にCloudFrontを作成する(または設定変更を行う)必要があります。

構築されるリソース

このpatternでは、以下のリソースが構築されます。

リソース名 説明
WebACL AWS WAFを構成する、ルールグループをまとめたリソース
Amazon Kinesis Data Firehose ストリーミングデータをリアルタイムにS3等のデータストアに出力するサービス
S3バケット AWS WAFのログを保存するバケット
IAM Role Amazon Kinesis Data Firehoseがログ保存用のS3バケットへ書き込みを行うための権限を付与するロール
IAM Policy Amazon Kinesis Data Firehoseがログ保存用のS3バケットへ書き込みを行うためのポリシー定義

モジュールの理解に向けて

CloudWatchによるモニタリング

Amazon CloudWatchを利用することで、WebACLやルールグループにマッチしたアクセスの件数をモニタリングできます。 詳細はAWS公式のドキュメントをご参照ください。

Kinesis Data Firehoseによるロギング

AWS WAFのログは通常直近3時間までしか保存されませんが、 Amazon Kinesis Data Firehoseを利用することでAWS WAFのログをAmazon S3などに出力できます。 詳細はAWS公式のドキュメントをご参照ください。

⚠️ 本patternを利用する場合、Amazon Kinesis Data Firehoseの出力先はS3で固定となります。 その他へ出力したい場合は別途作成や設定変更をしてください。

⚠️ ロギング機能は本来オプション機能ですが、本patternを利用する場合は有効化が必須になっています。 これは今後のバージョンアップで任意指定可能になる予定です。

各種リソースへのWebACLの関連付け

AWS WAFを各種リソースで利用する際は、作成したWebACLを利用したいリソースに関連付けることで行います。 本patternではresource_arn変数にALBやAmazon API GatewayのARNを記載して実行することで関連付けを行えます。 ただし、APIの都合上、CloudFrontへ関連付ける場合のみ同様の方法で関連付けることはできません。これは本patternの対象外の操作となります。

CloudFrontで利用したい場合は、WebACLを作成後にCloudFrontを作成するか、すでに作成済みのCloudFrontの設定を変更する必要があります。 これはcacheable_frontend patternを利用することでも行なえます。

なお、各種リソースへWebACLを関連付けた後にWebACLやルールグループの設定を変更した場合、再度関連付けを行う必要はありません。

CloudFrontで利用するWebACLを作成する際の注意点

AWS Management ConsoleからCloudFrontで利用するWebACLを作成する際は、WebACLやルールグループをGlobalリージョンへ作成する必要があります。 これをTerraformで行うためには以下の2点を行ってください。

  • バージニア北部(us-east-1)リージョンを指定して各種リソースを作成する
  • scopeCLOUDFRONTを指定する

具体的なコードの記載方法は以下のサンプルコードをご参照ください。

ℹ️ CloudFront以外で利用する際は特にリージョン指定不要です。

サンプルコード

webacl patternを使用したサンプルコードを、以下に記載します。

provider "aws" {
  alias  = "global"     # 任意の文字列
  region = "us-east-1"  # バージニア北部
}

# Regex pattern setsの作成
resource "aws_wafv2_regex_pattern_set" "this" {
  provider = aws.global

  name  = "sample-regex-pattern-set"
  # CloudFrontで利用する場合はscopeにCLOUDFRONTを指定する
  # ALBで利用する場合はscopeにREGIONALを指定する
  scope = "CLOUDFRONT"

  regular_expression {
    regex_string = "/admin_page"
  }
}

# WebACLへ適用するルールグループの作成
resource "aws_wafv2_rule_group" "this" {
  provider = aws.global

  name     = "sample-regex-pattern-rule_group"
  # CloudFrontで利用する場合はscopeにCLOUDFRONTを指定する
  # ALBで利用する場合はscopeにREGIONALを指定する
  scope    = "CLOUDFRONT"
  capacity = 200

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

    action {
      block {}
    }

    statement {
      regex_pattern_set_reference_statement {
        arn = aws_wafv2_regex_pattern_set.this.arn
        field_to_match {
          uri_path {}
        }

        text_transformation {
          priority = 2
          type     = "NONE"
        }
      }
    }

    visibility_config {
      cloudwatch_metrics_enabled = true
      metric_name                = "sample-regex-pattern-rule-metirc"
      sampled_requests_enabled   = true
    }
  }

  visibility_config {
    cloudwatch_metrics_enabled = true
    metric_name                = "sample-regex-pattern-rule_group-metric"
    sampled_requests_enabled   = true
  }
}

# 作成したルールグループを適用したWebACLを作成
module "webacl" {
  source = "git::https://gitlab.com/eponas/epona.git//modules/aws/patterns/webacl?ref=v0.2.6"

  providers = {
    aws = aws.global
  }

  default_action = "allow"
  name           = "sample-webacl"
  # CloudFrontで利用する場合はscopeにCLOUDFRONTを指定する
  # ALBで利用する場合はscopeにREGIONALを指定する
  scope          = "CLOUDFRONT"
  # CloudFrontで利用する場合はresource_arnの指定は不要
  # ALBで利用する場合はpublic_traffic_container_service pattern で作成したALBのARNを参照
  # resource_arn   = data.terraform_remote_state.container_service_backend.outputs.public_traffic_container_service.load_balancer_arn
  rule_groups = [
    {
      arn                        = aws_wafv2_rule_group.this.arn
      override_action            = "none"
      cloudwatch_metrics_enabled = true
      sampled_requests_enabled   = true
    }
  ]

  web_acl_cloudwatch_metrics_enabled = true
  web_acl_sampled_requests_enabled   = true

  s3_logging_bucket_name     = "epona-sample-firehose-bucket"
  create_logging_bucket      = true
  logging_prefix             = "waf_log/"
  logging_compression_format = "GZIP"

  tags = {
    Owner              = "john"
    Environment        = "runtime"
    RuntimeEnvironment = "development"
    ManagedBy          = "epona"
  }
}

作成されるリソース構成

以下の構成図で示す「webacl pattern構築リソース」部分が作成されます。

リソース構成図

関連するpattern

webacl patternに関連するpatternを、以下に記載します。

pattern名 説明
cacheable_frontend Runtime環境へのフロントエンド配信環境を構築する
public_traffic_container_service Runtime環境へのロードバランサーおよびコンテナサービス環境を構築する

ログの集約

webacl patternでは、WAFのログをAmazon S3に出力します。

このログは、datadog_log_trigger patternを使用することでDatadogに集約できます。

入出力リファレンス

Requirements

Name Version
terraform ~> 0.14.10
aws >= 3.37.0, < 4.0.0

Inputs

Name Description Type Default Required
default_action WebACLに設定するデフォルトアクション(allow or block string n/a yes
name 作成するリソースに付ける名前 string n/a yes
s3_logging_bucket_name ロギングに使用するバケットの名前 string n/a yes
scope CloudFront用かリージョンアプリケーション用かの指定(CLOUDFRONT or REGIONAL string n/a yes
create_logging_bucket 新規にS3バケットを作成するか既存のバケットを使用するかを指定するフラグ(trueでバケットを新規に作成) bool true no
logging_compression_format S3に配置するログの圧縮フォーマット(無圧縮(null) or GZIP or ZIP or Snappy string null no
logging_prefix S3に配置する際にパスに付与するPrefix string null no
resource_arn WAFを関連付けるリソースのARN(ここでのCloudFrontの指定は不可) string null no
rule_groups WebACLに関連付けるルールグループ(List形式で複数指定可、記載順に適用される)
rule_groups = [
{
arn = "dummy" # WebACLに設定するルールグループのARN(作成するWebACLと同一のリージョンに作成済みのルールグループのみ指定可)
override_action = "none" # none: 元々のルールグループのアクションをそのまま適用する。count: 一致したWebリクエストのカウントのみを行うようにする。
cloudwatch_metrics_enabled = false # このルールグループのCloudWatchによる件数モニタリングを有効化する
sampled_requests_enabled = false # このルールグループのルールに一致した過去3時間分のWebリクエストの保存を有効化する
}
]
list(map(any)) [] no
s3_logging_bucket_force_destroy destroy時、データがあったとしても強制的にS3バケットを削除する bool false no
tags このモジュールで作成されるリソースに付与するタグ map(string) {} no
web_acl_cloudwatch_metrics_enabled WebACLのCloudWatchによる件数モニタリングを有効化する bool true no
web_acl_sampled_requests_enabled ルールに一致した過去3時間分のWebリクエストの保存を有効化する bool true no

Outputs

Name Description
webacl_arn 作成されたWebACLのARN
webacl_traffic_log_bucket ログ出力用のS3バケット名
webacl_traffic_log_bucket_id ログ出力用のS3バケットのID

※ このドキュメントはクリエイティブコモンズ(Creative Commons) 4.0 の「表示—継承」に準拠しています。

※ このドキュメントに記載されている会社名、製品名は、各社の登録商標または商標です。

© 2021 TIS Inc.