Install CloudFront Integration using Terraform

๐Ÿ“˜

Before you start: Read the general CloudFront guide

This document only covers deploying the Fingerprint CloudFront proxy integration to your AWS account using Terraform. It assumes you use you have already read the general AWS CloudFront Proxy Integration v2 guide and completed the following steps:

  • Step 1: You have issued a proxy secret in the Fingerprint Dashboard (FPJS_PRE_SHARED_SECRET).
  • Step 2: You have defined the path variables for the integration (FPJS_BEHAVIOR_PATH, FPJS_AGENT_DOWNLOAD_PATH, FPJS_GET_RESULT_PATH)

If want to use CloudFormation instead of Terraform to install the integration, see Install CloudFront integration using CloudFormation.

๐Ÿšง

Limitations

This integration is exclusively supported for customers on the Enterprise Plan. Other customers are encouraged to use Custom subdomain setup or Cloudflare Proxy Integration.

Prerequisites

  • AWS Account.
  • Access to an IAM role in AWS with privileges to manage IAM roles, CloudFront distributions, Secrets Manager, Lambda Functions, and S3 Read Only access.
  • Terraform project using the AWS provider with the IAM role described above.
  • Terraform CLI.

Step 3: Add the Fingerprint Terraform module

Add the Fingerprint CloudFront integration Terraform module into your Terraform project.

  • Use the proxy secret created in Step 1 as fpjs_shared_secret.
  • Use the path variables defined in Step 2 as fpjs_get_result_path and fpjs_agent_download_path.
module "fingerprint_cloudfront_integration" {
  source = "fingerprintjs/fingerprint-cloudfront-proxy-integration/aws"

  fpjs_agent_download_path = "FPJS_AGENT_DOWNLOAD_PATH"
  fpjs_get_result_path     = "FPJS_GET_RESULT_PATH"
  fpjs_shared_secret       = "FPJS_PRE_SHARED_SECRET"
}

Run terraform init to install the module. The Terraform module source code is available on GitHub.

You can update the module by running terraform init -upgrade. Specify the version constraint according to your needs.

Step 4: Use Terraform module outputs in your CloudFront distribution

In this step, choose between using an existing CloudFront distribution or creating a new one. The module's GitHub repository contains example projects for both approaches.

A) Use an existing CloudFront distribution (recommended)

If your website is already running on CloudFront, you can use the same distribution and domain for the proxy integration. The proxy endpoints will be available on your chosen path such asyourwebsite.com/random-path/...

This is the recommended setup. Your website and the proxy function will be same-site, served from the same IP address or IP address range. Having the same or similar IP improves cookie lifetimes in Safari โ€” they will be stored in the browser for up to one year instead of 7 days.

  1. Add the following code to the definition of your CloudFront distribution.
  2. Replace FPJS_BEHAVIOR_PATH with the value you defined in Step 2.
resource "aws_cloudfront_distribution" "cloudfront_dist" {
  // Your existing CloudFront configuration

  # region Fingerprint CloudFront integration start

  origin {
    domain_name = module.fingerprint_cloudfront_integration.fpjs_origin_name
    origin_id   = module.fingerprint_cloudfront_integration.fpjs_origin_id
    custom_origin_config {
      origin_protocol_policy = "https-only"
      http_port              = 80
      https_port             = 443
      origin_ssl_protocols   = ["TLSv1.2"]
    }
    custom_header {
      name  = "FPJS_SECRET_NAME"
      value = module.fingerprint_cloudfront_integration.fpjs_secret_manager_arn
    }
  }

  ordered_cache_behavior {
    path_pattern = "FPJS_BEHAVIOR_PATH/*"

    allowed_methods          = ["GET", "HEAD", "OPTIONS", "PUT", "POST", "PATCH", "DELETE"]
    cached_methods           = ["GET", "HEAD"]
    cache_policy_id          = module.fingerprint_cloudfront_integration.fpjs_cache_policy_id
    origin_request_policy_id = module.fingerprint_cloudfront_integration.fpjs_origin_request_policy_id
    target_origin_id         = module.fingerprint_cloudfront_integration.fpjs_origin_id
    viewer_protocol_policy   = "https-only"
    compress                 = true

    lambda_function_association {
      event_type   = "origin-request"
      lambda_arn   = module.fingerprint_cloudfront_integration.fpjs_proxy_lambda_arn
      include_body = true
    }
  }

  #endregion
}

B) Create a new CloudFront distribution

If your website is not running on CloudFront, you can create a new CloudFront distribution just for the proxy integration and serve it from a subdomain of your website like metrics.yourwebsite.com.

This setup limits Safari cookie lifetime to 7 days. Because your website and the Lambda proxy function will likely have different IP ranges, Safari will apply the same cookie lifetime cap as for third-party CNAME cloaking. This is still an improvement over third-party cookies getting blocked entirely by Safari. But we recommend serving your website and the proxy integration using the same CloudFront distribution if possible (option A above).

  • Add the following code to create a CloudFront distribution with the Fingerprint Terraform module as the default cache behavior.
  • Configure the CloudFront distribution (for example price_class, viewer_certificate, restrictions, etc.) according to your needs.
resource "aws_cloudfront_distribution" "fpjs_cloudfront_distribution" {
  comment = "Fingerprint distribution (created via Terraform)"

  origin {
    domain_name = module.fingerprint_cloudfront_integration.fpjs_origin_name
    origin_id   = module.fingerprint_cloudfront_integration.fpjs_origin_id
    custom_origin_config {
      origin_protocol_policy = "https-only"
      http_port              = 80
      https_port             = 443
      origin_ssl_protocols   = ["TLSv1.2"]
    }
    custom_header {
      name  = "FPJS_SECRET_NAME"
      value = module.fingerprint_cloudfront_integration.fpjs_secret_manager_arn
    }
  }

  enabled = true

  http_version = "http1.1"

  price_class = "PriceClass_100"

  default_cache_behavior {
    allowed_methods          = ["GET", "HEAD", "OPTIONS", "PUT", "POST", "PATCH", "DELETE"]
    cached_methods           = ["GET", "HEAD"]
    cache_policy_id          = module.fingerprint_cloudfront_integration.fpjs_cache_policy_id
    origin_request_policy_id = module.fingerprint_cloudfront_integration.fpjs_origin_request_policy_id
    target_origin_id         = module.fingerprint_cloudfront_integration.fpjs_origin_id
    viewer_protocol_policy   = "https-only"
    compress                 = true

    lambda_function_association {
      event_type   = "origin-request"
      lambda_arn   = module.fingerprint_cloudfront_integration.fpjs_proxy_lambda_arn
      include_body = true
    }
  }

  restrictions {
    geo_restriction {
      restriction_type = "none"
    }
  }

  viewer_certificate {
    cloudfront_default_certificate = true
  }
}

Creating a subdomain for the new CloudFront distribution

If you use Terraform to manage your DNS records, you can also configure a subdomain for your proxy CloudFront distribution.

resource "aws_cloudfront_distribution" "fpjs_cloudfront_distribution" {
  # Same configuration as above

  viewer_certificate {
-   cloudfront_default_certificate = true
+   acm_certificate_arn = "<YOUR_SUBDOMAIN_CERTIFICATE_ARN"
+   ssl_support_method  = "sni-only"
  }
  
+ aliases = ["metrics.yourwebsite.com"]
}

+ resource "aws_route53_record" "cloudfront_terraform_new_distribution_record" {
+   zone_id = "<DOMAIN_ZONE_ID>"
+   name    = "metrics.yourwebsite.com"
+   type    = "CNAME"
+   ttl     = 300
+   records = [aws_cloudfront_distribution.fpjs_cloudfront_distribution.domain_name]
+ }

Step 5: Apply the the Terraform changes

  1. Run terraform plan to verify the planned configuration changes.
  2. Run terraform apply to apply the changes.

Step 6: Configure the client agent

Please see the main CloudFront proxy integration guide to Configure the client agent on your website or mobile application.

Updating the integration

Unlike the CloudFormation installation method, the Terraform installation of the CloudFront proxy integration does not include any mechanism for automatic updates.

  • The module does not include a Management lambda function or any related resources.
  • No need to configure automatic updates in the Fingerprint Dashboard.

To keep your integration up to date, please run terraform apply regularly.

๐Ÿšง

Update expectations

The underlying data contract in the identification logic can change to keep up with browser and device releases. Using the AWS CloudFront Proxy Integration might require occasional manual updates on your side. Ignoring these updates will lead to lower accuracy or service disruption.


Defining a permission boundary for the proxy function

If you need to, you can define the proxy function's permission boundary as an input of the Terraform module.


module "fingerprint_cloudfront_integration" {
  source = "fingerprintjs/fingerprint-cloudfront-proxy-integration/aws"

  fpjs_agent_download_path = "FPJS_AGENT_DOWNLOAD_PATH"
  fpjs_get_result_path     = "FPJS_GET_RESULT_PATH"
  fpjs_shared_secret       = "FPJS_PRE_SHARED_SECRET"
   
+ fpjs_proxy_lambda_role_permissions_boundary_arn = "arn:aws:iam::<YOUR_ACCOUNT_ID>:policy/YOUR_POLICY_NAME"
}

Make sure your permissions boundary allows the function to:

  • Access the Secret manager secret created for the integration (secretsmanager:GetSecretValue)
  • Create logs (logs:CreateLogStream, logs:CreateLogGroup, logs:PutLogEvents).

Example permission boundary definition:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "<YOUR_SID_HERE>",
      "Effect": "Allow",
      "Action": [
        "secretsmanager:GetSecretValue",
        "logs:CreateLogStream",
        "logs:CreateLogGroup",
        "logs:PutLogEvents"
      ],
      "Resource": [
        "arn:aws:secretsmanager:us-east-1:<ACCOUNT_ID>:secret:fingerprint-pro-cloudfront-integration-settings-secret-<ID-SUFFIX>",
        "arn:aws:logs:*:<ACCOUNT_ID>:log-group:*"
      ]
    }
  ]
}

What's next

To learn more about calculating AWS costs and monitoring your CloudFront integration, go back to the general CloudFront Proxy Integration guide.