この記事について
この記事は、「Relic Advent Calendar 2022」の18日目の記事です。
Meta(Facebook) 広告の Conversions API Gateway サーバに対して、複数のホスト名(ドメイン名)を割り当てる方法について紹介します。
想定読者:
- 既にConversions API Gatwewayを運用されていて、そこに複数のホスト名を割り当てたいと思っている方
- UNIX/Linux の基本的なコマンド操作に慣れている方
- AWS環境の基本的な操作に慣れている方
この記事を書いた背景
CAPI Gatewayの公式ドキュメントには、下記のように複数ドメインサポートがある旨の記載がありました。
Multi-Pixel and Multi-Domain Support for Meta Pixel
Conversions API Gateway supports multiple domains. For example, you can have multiple domains such as “domain.com” , “domain.co.uk”, “anotherdomain.com”. All of these domains could be configured within a single instance of Conversions API Gateway during deployment. Please review the setup guide for more details.
しかし、CAPI GatewayサーバのIPアドレスにドメインを割り当てただけだと、アクセスしてもNginx 404エラー画面が表示され、計測データ送信もできない状態でした。
また、管理画面上などに該当する設定項目が見当たらず、公式ドキュメントにも詳しい設定方法見当たりませんでした。
そこで、仕方なく実際にEC2インスタンス上で稼働するCAPI Gatwayシステムの状況を調べたところ、最低限設定可能な方法が見つかりました。この記事は、その記録です。
前提条件
Conversions API Gatewayの標準セットアップ手順は、既存のAWS環境に対して、EC2サーバインスタンスを追加する、というものです。
そのため、以降の設定方法はAWS環境上での動作を想定します。また、AWSアカウントのセットアップに関する説明は省略します。
また、 Conversions API GatewayのAppバージョンは、執筆時点で最新の v1.5.8 を前提としています。
複数ホスト名対応の動機
=> 端的にいうと、運用・管理費用の節約です。
CAPI Gatewayサーバは、AWS EC2 m5.large 以上のインスタンスを常時稼働させる必要があります。
個々のサイトのConversion計測リクエストがそこまで多くない場合に、1ドメイン1サーバの構成は非経済的なので、1サーバに集約したい、という判断です。
Conversions API Gateway (CAPI Gateway) とは
Meta (Facebook)広告コンバージョン計測用ピクセルからのイベントデータを受け取り、Meta計測サーバに転送します。サーバホスト名を適切に設定することで、サードパーティCookieの利用に制限のあるブラウザでも、計測データを取得することが可能になります。
公式ドキュメントより引用
コンバージョンAPIゲートウェイは、イベントマネージャのセルフサービス構成オプションです。コンバージョンAPIゲートウェイを使用すると、事業者は、専用の開発者リソースなしに、以下のベストプラクティスガイダンスを統合して、Metaピクセルや冗長設定のコンバージョンAPIによりイベントを送信できます。そのため、サードパーティパートナーやコーディングが不要になります。
CAPI Gatewayのアーキテクチャ概要
(出典: https://developers.facebook.com/docs/marketing-api/conversions-api/guides/gateway , 画像取得日: 2022-12-18)
CAPI Gatwayの実体
CAPI Gatewayの標準セットアップ手順 に従い、AWS CloudFormationのテンプレートをデプロイすると、CAPI Gateway Appの稼働するEC2サーバインスタンスが作成されます。
EC2インスタンスにログイン※して確認したところ、実体は microk8s (kubernetes) で管理されたマイクロサービスであることがわかりました。
※EC2インスタンスへのログイン設定について
EC2インスタンスには AWS SSM Session Manager agentがインストール済みのため、SSM関連の設定をすればそのままEC2コンソール画面からログイン可能です。
主な構成要素は、
- Ingress (Nginx)
- CAPI Gateway データ受信サーバ
- CAPI Gateway 管理画面 App
- DB (MySQL)
- Logging/Monitoring関連サービス
のようです。
この構成要素のうち、 Ingress サービス (Nginx) が、初期セットアップ時に指定したホスト名宛のリクエストしか受信しない設定となっています。
複数ホスト名(ドメイン名)でのアクセスを許可するため、この Ingress の設定を更新する手順を以下に記載します。
設定方法
CAPI Gateway (EC2) およびALB, Session ManagerなどのAWSインフラ設定が一通り完了している状態で、新規にドメインを追加する設定操作例です。
設定手順説明用パラメータ:
- Pixelタグ設置先ドメイン:
*.dev.example.com
- CAPI Gatewayに割り当てるホスト名:
capig.dev.example.com
1. EC2上のmicrok8s Ingress (Nginx) 設定の更新
-
CAPI Gateway EC2インスタンスにログイン (AWS EC2コンソール -> Session Manager など)
-
ドメイン追加スクリプト実行
$ cd /home/ubuntu $ ./add-capi-domain.sh dev.example.com
- "ingress.networking.k8s.io/capig-data-ingress-dev.example.com created" のようなメッセージが表示されれば作成成功です
詳細確認方法
microk8s kubectl describe
コマンドを実行し、下記のような表示が出れば、設定に成功しています。引数で与える対象ルール名は、 ingress capig-data-ingress-
+ 追加したドメイン名です。
$ microk8s kubectl describe ingress capig-data-ingress-dev.example.com
Name: capig-data-ingress-dev.example.com
Namespace: default
Address: 10.152.183.70
Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
Host Path Backends
---- ---- --------
*.dev.example.com
/capig capig:capig (10.1.141.111:8080)
/auth hub:ui (10.1.141.68:8080)
/static capig:capig (10.1.141.111:8080)
/.open-bridge capig:capig (10.1.141.111:8080)
/eventbus capig:capig (10.1.141.111:8080)
/events capig:capig (10.1.141.111:8080)
/events_ws capig:capig (10.1.141.111:8080)
/capi capig:capig (10.1.141.111:8080)
/tr capig:capig (10.1.141.111:8080)
/sdk capig:capig (10.1.141.111:8080)
/echo capig:capig (10.1.141.111:8080)
/testendpoint capig:capig (10.1.141.111:8080)
/token capig:capig (10.1.141.111:8080)
Annotations: meta.helm.sh/release-name: capig-dev.example.com
meta.helm.sh/release-namespace: default
nginx.ingress.kubernetes.io/configuration-snippet: more_set_headers "Access-Control-Allow-Origin: $http_origin";
nginx.ingress.kubernetes.io/cors-allow-methods: PUT, GET, POST, OPTIONS
nginx.ingress.kubernetes.io/enable-cors: true
nginx.ingress.kubernetes.io/proxy-body-size: 1024m
Events: <none>
スクリプトと関連ファイル
ドメイン追加スクリプト add-capi-domain.sh
#!/bin/sh
KUBECTL_CMD='microk8s kubectl'
TEMPLATE_FILE=${TEMPLATE_FILE:-template-ingress-capig.yml}
DOMAIN=$1
sed "s/%%BASE_DOMAIN%%/${DOMAIN}/g" ${TEMPLATE_FILE} | \
$KUBECTL_CMD apply -f -
k8sの管理コマンドである kubectl
を実行して、設定ファイルテンプレートの内容を適用する、というものです。
下記のような設定テンプレートファイルに、追加したいホスト名を埋め込むことで、ホスト名ごとの設定を追加します。
設定ファイルテンプレート例
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
meta.helm.sh/release-name: capig-%%BASE_DOMAIN%%
meta.helm.sh/release-namespace: default
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/configuration-snippet: |
more_set_headers "Access-Control-Allow-Origin: $http_origin";
nginx.ingress.kubernetes.io/cors-allow-methods: PUT, GET, POST, OPTIONS
nginx.ingress.kubernetes.io/proxy-body-size: 1024m
name: capig-data-ingress-%%BASE_DOMAIN%%
namespace: default
spec:
ingressClassName: cloudbridge-ingress-class
rules:
- host: "*.%%BASE_DOMAIN%%"
http:
paths:
- backend:
service:
name: capig
port:
name: capig
path: /capig
pathType: Prefix
- backend:
service:
name: hub
port:
name: ui
path: /auth
pathType: Prefix
- backend:
service:
name: capig
port:
name: capig
path: /static
pathType: Prefix
- backend:
service:
name: capig
port:
name: capig
path: /.open-bridge
pathType: Prefix
- backend:
service:
name: capig
port:
name: capig
path: /eventbus
pathType: Prefix
- backend:
service:
name: capig
port:
name: capig
path: /events
pathType: Prefix
- backend:
service:
name: capig
port:
name: capig
path: /events_ws
pathType: Prefix
- backend:
service:
name: capig
port:
name: capig
path: /capi
pathType: Prefix
- backend:
service:
name: capig
port:
name: capig
path: /tr
pathType: Prefix
- backend:
service:
name: capig
port:
name: capig
path: /sdk
pathType: Prefix
- backend:
service:
name: capig
port:
name: capig
path: /echo
pathType: Prefix
- backend:
service:
name: capig
port:
name: capig
path: /testendpoint
pathType: Prefix
- backend:
service:
name: capig
port:
name: capig
path: /token
pathType: Prefix
補足: CORS設定について
上記設定では、CORS設定(access-control-allow-*
)を意図的に追加しています。
これは、例えば dev.example.com の配下に、 www1.dev.example.com や www2.dev.example.com など複数の計測対象サイトがあるケースに対応しやすくするためです。
CORS設定を有効化することで、capig.dev.example.com のような計測対象サイトのsiblingsホスト名1つを使い回して利用することが可能となります。
逆に、もしCORS設定を追加しない場合、capig.www1.dev.example.com, capig.www2.dev.example.com のように、サイトごとにCAPI Gateway用のドメインを割り当てる必要があります。
関連: https://github.com/kubernetes/ingress-nginx/issues/8469
2. SSL/TLS証明書発行
ALBでHTTPSリクエストを受け付けられるように、CAPI Gateway サーバが稼働するAWSアカウントのACM上で、 *.dev.example.com ドメイン用のSSL証明書の登録 or 新規作成(DNS認証など)を行なってください。
3. DNSレコード設定
CAPI Gatewayサーバにリクエストが到達するように、 Pixelタグ設置先ドメインのDNS(AWS Route53など)の管理者の方に、下記レコード設定を依頼してください
- capig.dev.example.com -> CAPI Gateway Server IPアドレスの Aレコード
- AWS Route53の場合は、 ALBのDNS名のaliasを推奨 ( 例: capig-alb-xxxxxxxx.ap-northeast-1.elb.amazonaws.com )
- SSL/TLS証明書発行のための CNAME レコード(手順2でDNS認証のSSL/TLS証明書作成を選択した場合に必要です)
4. ALB へのSSL証明書設定
ACMに新規追加した証明書を, CAPI GatewayサーバのALBに設定してください。
EC2 -> LoadBalancers -> 対象ALB -> HTTP:443 Listener -> Certificates
-> Listener certificates for SNI -> Add certificate
5. 動作確認
ここまでの設定で、 CAPI Gatewayサーバ (例: capig.dev.example.com) にリクエストが送信可能な状態になっているはずです。
下記のようなコマンドを実行して疎通確認をしてください。
$ curl -i -X OPTIONS https://capig.dev.example.com
HTTP/2 204
date: Fri, 11 Nov 2022 08:35:02 GMT
access-control-allow-credentials: true
access-control-allow-origin: *
access-control-allow-methods: PUT, GET, POST, OPTIONS
access-control-allow-headers: DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization
access-control-max-age: 1728000
その他確認事項
本スクリプトによる設定結果について、その有効期間について確認しました。
確認結果:
- 本スクリプトによる設定結果は、EC2インスタンス再起動でも消失しない
- 本スクリプトによる設定結果は、CAPI Gateway の自動更新(v1系のマイナーアップデート)の実行後も消失しない
複数ホスト名対応後のCAPI Gateway構成イメージ
FutureWork
- Helm でのIngress (Nginx) 設定管理に移行
- CORS設定の
access-control-allow-origin
にホスト名を指定できるようにする
まとめ
構築済みのMeta Conversions API Gatewayサーバに対して、複数のホスト名(ドメイン名)を割り当てる方法について紹介しました。
動機はお金(の節約)です。