💎

【Terraform】Cognito Managed Login にカスタムブランディングを適用する

に公開

TerraformのAWSプロバイダに aws_cognito_managed_login_branding が追加されていたので試してみました。

Terraform だけでこんな感じにログイン画面をスタイリングできます。

また多要素認証も完全にAWSマネージドで簡単に導入できます。

独自のスタイルを適用する

独自のスタイル を適用するには asset ブロックと settings を使用します。

Example

main.tf
resource "aws_cognito_managed_login_branding" "client" {
  client_id    = aws_cognito_user_pool_client.example.id
  user_pool_id = aws_cognito_user_pool.example.id

  asset {
    bytes      = filebase64("login_branding_asset.svg")
    category   = "PAGE_HEADER_BACKGROUND"
    color_mode = "DARK"
    extension  = "SVG"
  }

  settings = jsonencode({
    # Your settings here.
  })
}

asset ブロックについて

asset ブロックでは Managed Login 画面で表示するファビコンやロゴ等の画像ファイルを指定してアップロードします。

指定できる category は以下のとおりです。参照

category 許可された拡張子
FAVICON_ICO ico
FAVICON_SVG svg
EMAIL_GRAPHIC png, svg, jpeg
SMS_GRAPHIC png, svg, jpeg
AUTH_APP_GRAPHIC png, svg, jpeg
PASSWORD_GRAPHIC png, svg, jpeg
PASSKEY_GRAPHIC png, svg, jpeg
PAGE_HEADER_LOGO png, svg, jpeg
PAGE_HEADER_BACKGROUND png, svg, jpeg
PAGE_FOOTER_LOGO png, svg, jpeg
PAGE_FOOTER_BACKGROUND png, svg, jpeg
PAGE_BACKGROUND png, svg, jpeg
FORM_BACKGROUND png, svg, jpeg
FORM_LOGO png, svg, jpeg
IDP_BUTTON_ICON ico, svg

settings について

settings では JSON を指定できます。
公式のスキーマ定義がなかったので自作しました。

https://github.com/kazeusagi/cognito-branding-settings-schema-json

$scheme を指定するだけで補完が効きます。

your-branding.json
{
  "$schema": "https://raw.githubusercontent.com/kazeusagi/cognito-branding-settings-schema-json/refs/heads/main/schema.json"
}

JSON形式等の詳しいことは公式に書いてあります。

モジュール構築例

私の構築例を紹介します。
カスタムブランディングと多要素認証を設定しています。

ディレクトリ構成

modules
└─ cognito
    ├─ files
    │   ├─ assets
    │   │   ├─ BrandLogo.svg
    │   │   └─ favicon.ico
    │   └─ cognito_branding_settings.json
    ├─ main.tf
    ├─ outputs.tf
    └─ variables.tf

コード

variables.tf
variable "name" {
  description = "名前"
  type        = string
}

variable "domain" {
  description = "Cognitoのドメイン"
  type        = string
}

variable "certificate_arn" {
  description = "カスタムドメインを発行する際のACM証明書のARN"
  type        = string
}

variable "signin_callback_urls" {
  description = "許可されたサインイン後のコールバックURL"
  type        = list(string)
}

variable "signout_callback_urls" {
  description = "許可されたサインアウト後のコールバックURL"
  type        = list(string)
}
main.tf
# Pool
resource "aws_cognito_user_pool" "main" {
  name                     = "${var.name}-tf"
  auto_verified_attributes = ["email"] # emailで検証
  username_attributes      = ["email"] # emailをユーザー名として使用
  # WARN: schema定義は後から変更できません
  schema {
    attribute_data_type = "String"
    name                = "email"
    required            = true # 必須
    mutable             = true # 変更可
  }
  # 他要素認証
  mfa_configuration = "OPTIONAL"
  software_token_mfa_configuration {
    enabled = true
  }
  sign_in_policy {
    allowed_first_auth_factors = [
      "WEB_AUTHN",
      "PASSWORD",
      "EMAIL_OTP"
    ]
  }
  admin_create_user_config {
    allow_admin_create_user_only = false # ユーザーにサインアップを許可する
  }
  password_policy {
    minimum_length                   = 8  # 最小8文字
    temporary_password_validity_days = 3  # 一時パスワードの有効期限3日
    password_history_size            = 3  # 直近3回分のパスワードは再利用不可
    require_lowercase                = true
    require_numbers                  = true
    require_uppercase                = true
    require_symbols                  = false
  }

  lifecycle {
    prevent_destroy = true // リソースの削除防止
  }
}

# Domain
resource "aws_cognito_user_pool_domain" "main" {
  user_pool_id          = aws_cognito_user_pool.main.id
  domain                = var.domain
  certificate_arn       = var.certificate_arn
  managed_login_version = 2 # 1:HostedUI, 2:ManagedLogin
}

# Client
resource "aws_cognito_user_pool_client" "main" {
  name                                 = "${var.name}-client"
  user_pool_id                         = aws_cognito_user_pool.main.id
  callback_urls                        = var.signin_callback_urls
  logout_urls                          = var.signout_callback_urls
  supported_identity_providers         = ["COGNITO"]
  allowed_oauth_flows_user_pool_client = true
  explicit_auth_flows = [
    "ALLOW_USER_AUTH" # ユーザーが認証方式を選択できる
  ]
  allowed_oauth_flows = [
    "code" # 認証コード付与
  ]
  allowed_oauth_scopes = [
    "phone",
    "email",
    "openid",
    "profile"
  ]
}

# Managed Login Style
resource "aws_cognito_managed_login_branding" "main" {
  user_pool_id = aws_cognito_user_pool.main.id
  client_id    = aws_cognito_user_pool_client.main.id
  # use_cognito_provided_values = true # cognito のデフォルトスタイルを使用するか

  # 以下、ブランディングスタイル関連の設定
  # asset: LIGHT と DARK 両方を一度に適用するため dynamic ブロックを使用する
  dynamic "asset" {
    for_each = ["LIGHT", "DARK"]
    content {
      bytes      = filebase64("${path.module}/files/assets/favicon.ico")
      category   = "FAVICON_ICO"
      color_mode = asset.value
      extension  = "ICO"
    }
  }
  dynamic "asset" {
    for_each = ["LIGHT", "DARK"]
    content {
      bytes      = filebase64("${path.module}/files/assets/BrandLogo.svg")
      category   = "FORM_LOGO"
      color_mode = asset.value
      extension  = "SVG"
    }
  }

  # settings: $scheme の指定があるとエラーになるため削除してから設定
  settings = jsonencode(
    { for k, v in jsondecode(file("${path.module}/files/cognito_branding_settings.json")) :
      k => v if k != "$schema"
    }
  )
}
cognito_branding_settings.json
{
  "$schema": "https://raw.githubusercontent.com/kazeusagi/cognito-branding-settings-schema-json/refs/heads/main/schema.json",
  "components": {
    "favicon": {
      "enabledTypes": ["ICO"]
    },
    "pageBackground": {
      "image": {
        "enabled": false
      },
      "lightMode": {
        "color": "bde0feff"
      }
    },
    "form": {
      "lightMode": {
        "backgroundColor": "cdb4dbff"
      },
      "logo": {
        "enabled": true,
        "formInclusion": "OUT",
        "location": "CENTER",
        "position": "TOP"
      }
    }
  },
  "componentClasses": {
    "input": {
      "lightMode": {
        "defaults": {
          "backgroundColor": "a2d2ffff"
        }
      }
    },
    "divider": {
      "lightMode": {
        "borderColor": "8888ffff"
      }
    }
  }
}

おまけ

日本語化

Cognito のログインページの URL のクエリパラメータに lang を指定することで色々な言語で表示することができます。
日本語にしたい場合は、lang=ja を指定するだけです。助かる〜

指定できる言語は以下のとおりです。参照

言語 Code
ドイツ語 de
英語 en
スペイン語 es
フランス語 fr
バハサインドネシア語 id
イタリア語 it
日本語 ja
韓国語 ko
ポルトガル語(ブラジル) pt-BR
簡体字中国語 zh-CN
繁体字中国語 zh-TW
HCプロデューステックブログ

Discussion