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
andfpjs_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.
- Add the following code to the definition of your CloudFront distribution.
- 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
- Run
terraform plan
to verify the planned configuration changes. - 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.
Updated 3 months ago