Provisioning Meta Conversions API Gateway on AWS Using Terraform

The standalone Meta Conversions API Gateway (CAPIG) provides an automated middle layer that intercepts browser Pixel traffic and mirrors it to Meta’s Graph API via server-side infrastructure without writing custom dataLayer code. While Meta offers an automated AWS CloudFormation one-click launcher, enterprise DevOps environments require declarative infrastructure-as-code (IaC) to adhere to strict corporate security controls, multi-AZ reliability, and automated CI/CD deployments.

Deploying CAPIG manually or via generic CloudFormation scripts frequently leads to production outages:

  1. VPC Subnet Misconfigurations: Running the container on public subnets without isolated NAT gateways exposes database volumes and monitoring ports to public port scanners.
  2. DNS & Certificate Renewal Locks: Automated Let’s Encrypt renewal jobs fail silently behind AWS Application Load Balancers (ALBs) if path routing rules intercept the .well-known/acme-challenge/ path.
  3. Redundant Infrastructure Spend: Running unthrottled EC2 t3.xlarge instances for low-to-medium event volumes wastes hundreds of dollars monthly in GCP/AWS computing credits—a cost leakage pattern comparable to the intraday query waste analyzed in our GA4 BigQuery intraday streaming optimization guide.

This technical playbook breaks down the exact AWS architecture required for Meta CAPIG, provides a production-grade Terraform script, and explains how to resolve SSL termination issues at the load balancer.

Architecture: Enterprise CAPIG Topology on AWS

Instead of provisioning a single EC2 instance with public IP assignments, enterprise deployments isolate the CAPIG application container inside private VPC subnets. All ingress traffic routes through an AWS Application Load Balancer terminating TLS via AWS Certificate Manager (ACM), while outbound events to Meta Graph API route through an egress NAT Gateway:

INFRASTRUCTURE BLUEPRINT

Enterprise Meta CAPIG Architecture on AWS

Isolated VPC execution with public ALB termination and secure NAT egress routing.

PUBLIC INGRESS LAYER (ALB)
ENDPOINT ROUTE
https://capig.brand.com/events
SECURITY CONFIGURATION
ACM Managed SSL/TLS (HTTPS:443) • WAF Rate Limiting
SECURE INGRESS DDoS Protected

Browser Pixel traffic lands on high-availability dual-AZ application load balancers with zero exposed EC2 ports.

INTERNAL FORWARD
PRIVATE COMPUTE CORE (EC2 / DOCKER)
CONTAINER HOST
EC2 t3.large • Private Subnet (No Public IP)
EGRESS DISPATCH
Outbound NAT Gateway ➔ Meta Graph API (graph.facebook.com)
ZERO-EXPOSURE CORE Isolated Data

Raw conversion payloads, hashed emails, and click IDs persist inside encrypted volumes without public interface risk.

If your architecture also tracks B2B offline deal milestones from Salesforce or HubSpot, this instance operates alongside the deduplication workflows detailed in our guide on how to deduplicate Meta CAPI conversions from HubSpot and Salesforce deals.

Step 1: Write the Declarative Terraform Deployment Module

Create a dedicated module file main.tf defining the VPC, ALB, security groups, and the official Meta CAPIG Amazon Machine Image (AMI):

Terraform

# main.tf - Meta Conversions API Gateway Deployment

terraform {
  required_version = ">= 1.5.0"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

variable "aws_region" {
  default = "us-east-1"
}

variable "environment" {
  default = "production"
}

# 1. Look up official Meta CAPIG Marketplace AMI
data "aws_ami" "meta_capig" {
  most_recent = true
  owners      = ["679593333241"] # Meta AWS Marketplace Owner ID

  filter {
    name   = "name"
    values = ["Conversions_API_Gateway_*"]
  }
}

# 2. Security Group for Public Application Load Balancer
resource "aws_security_group" "alb_sg" {
  name        = "capig-alb-sg-${var.environment}"
  description = "Allows public HTTPS ingress to CAPIG ALB"
  vpc_id      = aws_vpc.capig_vpc.id

  ingress {
    description = "HTTPS from web"
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

# 3. Security Group for Private EC2 Instance
resource "aws_security_group" "ec2_sg" {
  name        = "capig-ec2-sg-${var.environment}"
  description = "Allows ingress strictly from ALB"
  vpc_id      = aws_vpc.capig_vpc.id

  ingress {
    description     = "HTTP from ALB"
    from_port       = 80
    to_port         = 80
    protocol        = "tcp"
    security_groups = [aws_security_group.alb_sg.id]
  }

  ingress {
    description     = "Admin interface from ALB"
    from_port       = 443
    to_port         = 443
    protocol        = "tcp"
    security_groups = [aws_security_group.alb_sg.id]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

# 4. CAPIG Compute Instance (Private Subnet)
resource "aws_instance" "capig_node" {
  ami                  = data.aws_ami.meta_capig.id
  instance_type        = "t3.large"
  subnet_id            = aws_subnet.private_subnet_a.id
  vpc_security_group_ids = [aws_security_group.ec2_sg.id]
  ebs_optimized        = true

  root_block_device {
    volume_size           = 50
    volume_type           = "gp3"
    encrypted             = true
    delete_on_termination = true
  }

  tags = {
    Name        = "meta-capig-${var.environment}"
    Application = "MarketingTelemetry"
  }
}

This configuration provisions the core compute instance in an isolated private subnet, preventing direct public access while ensuring persistent storage volumes remain encrypted at rest.

Step 2: Handle ALB Listener Rules & ACM Certificates

Meta CAPIG contains an automated internal certificate generation tool for standalone instances. However, placing CAPIG behind an AWS Application Load Balancer requires offloading TLS termination to AWS Certificate Manager (ACM) to prevent SSL handshake collisions:

Terraform

# alb.tf - Ingress Routing Configuration

resource "aws_lb" "capig_alb" {
  name               = "capig-alb-${var.environment}"
  internal           = false
  load_balancer_type = "application"
  security_groups    = [aws_security_group.alb_sg.id]
  subnets            = [aws_subnet.public_subnet_a.id, aws_subnet.public_subnet_b.id]

  drop_invalid_header_fields = true
}

resource "aws_lb_target_group" "capig_tg" {
  name        = "capig-tg-${var.environment}"
  port        = 80
  protocol    = "HTTP"
  vpc_id      = aws_vpc.capig_vpc.id
  target_type = "instance"

  health_check {
    enabled             = true
    path                = "/healthcheck"
    protocol            = "HTTP"
    port                = "80"
    interval            = 30
    timeout             = 5
    healthy_threshold   = 2
    unhealthy_threshold = 3
    matcher             = "200"
  }
}

resource "aws_lb_listener" "https_forward" {
  load_balancer_arn = aws_lb.capig_alb.arn
  port              = "443"
  protocol          = "HTTPS"
  ssl_policy        = "ELBSecurityPolicy-TLS13-1-2-2021-06"
  certificate_arn   = var.acm_certificate_arn

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.capig_tg.arn
  }
}

If your primary domain traffic routes through Cloudflare edge caching, make sure your proxy cache policies do not store dynamic /events payload responses by implementing the bypass directives detailed in our guide on mitigating analytics telemetry loss from aggressive Cloudflare edge caching.

Step 3: Complete CAPIG DNS Routing & Pixel Pairing

Once terraform apply finishes:

  1. Copy the DNS endpoint of your Application Load Balancer (e.g., capig-alb-production-123456789.us-east-1.elb.amazonaws.com).
  2. Add a CNAME record in your DNS provider:
    • Host: capig.yourbrand.com
    • Target: Your ALB DNS endpoint
  3. Open your browser and navigate to [https://capig.yourbrand.com](https://capig.yourbrand.com).
  4. Create the Master Administrator credentials.
  5. In the CAPIG UI, select Connect Data Source and log into your Meta Business Manager.
  6. Select your target Pixel / Dataset ID.

CAPIG will automatically inject an egress gateway interceptor script. For engineering teams comparing this setup against containerized Node pipelines, consult our technical evaluation of Stape vs. AWS for Server GTM hosting to determine if dedicated CAPIG or custom sGTM containers better suit your tracking needs.

Frequently Asked Questions

What is the primary difference between Meta CAPIG and Server-Side GTM?

Meta CAPIG is a specialized, turnkey container managed and updated directly by Meta that only routes data to Meta’s endpoint by listening to browser pixel calls. Server-Side GTM is a general-purpose reverse proxy that transforms and distributes telemetry to multiple vendors (Google Analytics, LinkedIn CAPI, TikTok, Pinterest, and Meta) simultaneously.

Can Meta CAPIG run on smaller instance types than t3.large?

While Meta’s default CloudFormation template enforces t3.large or t3.xlarge, storefronts processing fewer than 10,000 daily events can safely run on t3.medium without memory exhaustion. However, scaling below 4GB of RAM can cause the local Docker container orchestrator to crash during batch uploads.

How does CAPIG handle event deduplication?

CAPIG intercepts the client-side Meta Pixel payload in the browser, extracts the client-generated event_id, and passes that identical identifier inside the mirrored server event. Meta’s Graph API reconciles both hits within a 48-hour window, automatically discarding redundant instances.


Publicaciones Similares

2 comentarios

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *