Demo Site
A fully functional end-to-end demo site:
- Github project: dinghydev/dinghy-example-cloudfront-sites
- Github
CI/CDworkflow: - Github
Drift Detectionworkflow: - deployed as: https://cloudfront-site-demo.dinghy.dev/
- app.tsx
- dinghy.config.yaml
- Overview
- All View
- Terraform
import { MoveToHere, Shape } from '@dinghy/base-components'
import {
AwsProvider,
GlobalLogBucket,
RegionalLogBucket,
S3Backend,
} from '@dinghy/tf-aws'
import { CloudfrontSites } from '@dinghy/tf-aws/cloudfrontSites'
export default function Stack() {
return (
<DinghyDevDemoSites>
<AwsProvider region='eu-west-1'>
<CloudfrontSites />
<Infrastructure />
</AwsProvider>
</DinghyDevDemoSites>
)
}
const DinghyDevDemoSites = (props: any) => <Shape {...props} />
const Infrastructure = (props: any) => {
return (
<Shape _distributed {...props}>
<S3Backend logEnabled />
<RegionalLogBucket />
<GlobalLogBucket />
<MoveToHere includes='AwsRoute53Zone' />
</Shape>
)
}
cloudfrontSites:
cloudfront-site-demo.dinghy.dev:
origins:
site_root:
target: 's3://dinghy-dev-demo-sites-origin'
redirectFromNames:
- '*.cloudfront-site-demo.dinghy.dev'
certVersions:
- '20260104'
custom_error_response:
- error_code: 403
response_code: 404
error_caching_min_ttl: 3600
response_page_path: /404.html


tf.json
{
"provider": {
"aws": [
{
"region": "eu-west-1",
"default_tags": {
"tags": {
"iac:stack-title": "Dinghy Dev Demo Sites",
"iac:stack-name": "dinghy-dev-demo-sites"
}
}
}
]
},
"terraform": {
"required_providers": {
"aws": {
"source": "aws",
"version": "6.22.0"
}
},
"backend": {
"s3": {
"bucket": "dinghy-dev-demo-sites-backend",
"key": "tfstates/app.tfstate",
"region": "eu-west-1"
}
}
},
"resource": {
"aws_cloudfront_distribution": {
"cloudfrontsitedemodinghydev_site": {
"default_cache_behavior": {
"allowed_methods": [
"GET",
"HEAD"
],
"cached_methods": [
"GET",
"HEAD"
],
"target_origin_id": "site_root",
"viewer_protocol_policy": "redirect-to-https",
"cache_policy_id": "658327ea-f89d-4fab-a63d-7e88639e58f6",
"function_association": []
},
"enabled": true,
"origin": [
{
"origin_id": "site_root",
"domain_name": "${aws_s3_bucket.cloudfrontsitedemodinghydev_site_root_bucket.bucket_regional_domain_name}",
"origin_path": "",
"origin_access_control_id": "${aws_cloudfront_origin_access_control.cloudfrontsitedemodinghydev_originaccesscontrol.id}"
}
],
"restrictions": {
"geo_restriction": {
"restriction_type": "none"
}
},
"viewer_certificate": {
"acm_certificate_arn": "${aws_acm_certificate.cloudfrontsitedemodinghydev_site_20260104_certificate.arn}",
"minimum_protocol_version": "TLSv1.2_2021",
"ssl_support_method": "sni-only"
},
"aliases": [
"cloudfront-site-demo.dinghy.dev"
],
"comment": "cloudfront-site-demo.dinghy.dev",
"custom_error_response": [
{
"error_caching_min_ttl": 3600,
"error_code": 403,
"response_code": 404,
"response_page_path": "/404.html"
}
],
"default_root_object": "index.html",
"logging_config": {
"bucket": "${aws_s3_bucket.awss3bucket_globallogbucket.bucket_domain_name}",
"prefix": "cloudfront-accesslog/cloudfrontsitedemodinghydev_site/"
},
"ordered_cache_behavior": [],
"tags": {
"Name": "Distribution: cloudfront-site-demo.dinghy.dev",
"iac:id": "cloudfrontsitedemodinghydev_site"
}
},
"cloudfrontsitedemodinghydev_redirect": {
"default_cache_behavior": {
"allowed_methods": [
"GET",
"HEAD"
],
"cached_methods": [
"GET",
"HEAD"
],
"target_origin_id": "site_root",
"viewer_protocol_policy": "redirect-to-https",
"cache_policy_id": "658327ea-f89d-4fab-a63d-7e88639e58f6",
"function_association": [
{
"event_type": "viewer-request",
"function_arn": "${aws_cloudfront_function.cloudfrontsitedemodinghydev_redirect_function.arn}"
}
]
},
"enabled": true,
"origin": [
{
"origin_id": "site_root",
"domain_name": "${aws_s3_bucket.cloudfrontsitedemodinghydev_site_root_bucket.bucket_regional_domain_name}",
"origin_path": "",
"origin_access_control_id": "${aws_cloudfront_origin_access_control.cloudfrontsitedemodinghydev_originaccesscontrol.id}"
}
],
"restrictions": {
"geo_restriction": {
"restriction_type": "none"
}
},
"viewer_certificate": {
"acm_certificate_arn": "${aws_acm_certificate.cloudfrontsitedemodinghydev_redirect_20260104_certificate.arn}",
"minimum_protocol_version": "TLSv1.2_2021",
"ssl_support_method": "sni-only"
},
"aliases": [
"*.cloudfront-site-demo.dinghy.dev"
],
"comment": "Redirect to cloudfront-site-demo.dinghy.dev",
"custom_error_response": [
{
"error_caching_min_ttl": 3600,
"error_code": 403,
"response_code": 404,
"response_page_path": "/404.html"
}
],
"default_root_object": "index.html",
"logging_config": {
"bucket": "${aws_s3_bucket.awss3bucket_globallogbucket.bucket_domain_name}",
"prefix": "cloudfront-accesslog/cloudfrontsitedemodinghydev_redirect/"
},
"tags": {
"Name": "Distribution: Redirect to cloudfront-site-demo.dinghy.dev",
"iac:id": "cloudfrontsitedemodinghydev_redirect"
}
}
},
"aws_route53_record": {
"cloudfrontsitedemodinghydev_arecord": {
"name": "cloudfront-site-demo.dinghy.dev",
"type": "A",
"zone_id": "${data.aws_route53_zone.dinghydev_zone.id}",
"alias": {
"name": "${aws_cloudfront_distribution.cloudfrontsitedemodinghydev_site.domain_name}",
"zone_id": "${aws_cloudfront_distribution.cloudfrontsitedemodinghydev_site.hosted_zone_id}",
"evaluate_target_health": false
}
},
"cloudfrontsitedemodinghydev_validation_cname": {
"name": "${one([\n for dvo in aws_acm_certificate.cloudfrontsitedemodinghydev_site_20260104_certificate.domain_validation_options :\n dvo if dvo.domain_name == \"cloudfront-site-demo.dinghy.dev\"\n]).resource_record_name}",
"type": "CNAME",
"zone_id": "${data.aws_route53_zone.dinghydev_zone.id}",
"allow_overwrite": true,
"records": [
"${one([\n for dvo in aws_acm_certificate.cloudfrontsitedemodinghydev_site_20260104_certificate.domain_validation_options :\n dvo if dvo.domain_name == \"cloudfront-site-demo.dinghy.dev\"\n]).resource_record_value}"
],
"ttl": 60
},
"star_cloudfrontsitedemodinghydev_arecord": {
"name": "*.cloudfront-site-demo.dinghy.dev",
"type": "A",
"zone_id": "${data.aws_route53_zone.dinghydev_zone.id}",
"alias": {
"name": "${aws_cloudfront_distribution.cloudfrontsitedemodinghydev_redirect.domain_name}",
"zone_id": "${aws_cloudfront_distribution.cloudfrontsitedemodinghydev_redirect.hosted_zone_id}",
"evaluate_target_health": false
}
},
"star_cloudfrontsitedemodinghydev_validation_cname": {
"name": "${one([\n for dvo in aws_acm_certificate.cloudfrontsitedemodinghydev_redirect_20260104_certificate.domain_validation_options :\n dvo if dvo.domain_name == \"*.cloudfront-site-demo.dinghy.dev\"\n]).resource_record_name}",
"type": "CNAME",
"zone_id": "${data.aws_route53_zone.dinghydev_zone.id}",
"allow_overwrite": true,
"records": [
"${one([\n for dvo in aws_acm_certificate.cloudfrontsitedemodinghydev_redirect_20260104_certificate.domain_validation_options :\n dvo if dvo.domain_name == \"*.cloudfront-site-demo.dinghy.dev\"\n]).resource_record_value}"
],
"ttl": 60
}
},
"aws_s3_bucket": {
"cloudfrontsitedemodinghydev_site_root_bucket": {
"bucket": "dinghy-dev-demo-sites-origin",
"tags": {
"Name": "Origin Bucket: cloudfront-site-demo.dinghy.dev site_root",
"iac:id": "cloudfrontsitedemodinghydev_site_root_bucket"
}
},
"awss3bucket_backend": {
"bucket": "dinghy-dev-demo-sites-backend",
"object_lock_enabled": true,
"tags": {
"Name": "dinghy-dev-demo-sites-backend",
"iac:id": "awss3bucket_backend"
}
},
"awss3bucket_regionallogbucket": {
"bucket": "dinghy-dev-demo-sites-logs-eu-west-1",
"tags": {
"Name": "Regional LogBucket",
"iac:id": "awss3bucket_regionallogbucket"
}
},
"awss3bucket_globallogbucket": {
"bucket": "dinghy-dev-demo-sites-logs-global",
"region": "us-east-1",
"tags": {
"Name": "Global LogBucket",
"iac:id": "awss3bucket_globallogbucket"
}
}
},
"aws_s3_bucket_logging": {
"cloudfrontsitedemodinghydev_site_root_bucketlogging": {
"bucket": "dinghy-dev-demo-sites-origin",
"target_bucket": "dinghy-dev-demo-sites-logs-eu-west-1",
"target_prefix": "s3-access-log/dinghy-dev-demo-sites-origin/"
},
"awss3bucket_regionallogbucket_logging": {
"bucket": "dinghy-dev-demo-sites-logs-eu-west-1",
"target_bucket": "dinghy-dev-demo-sites-logs-eu-west-1",
"target_prefix": "s3-access-log/dinghy-dev-demo-sites-logs-eu-west-1/",
"depends_on": [
"aws_s3_bucket.awss3bucket_regionallogbucket"
]
},
"awss3bucket_globallogbucket_logging": {
"bucket": "dinghy-dev-demo-sites-logs-global",
"target_bucket": "dinghy-dev-demo-sites-logs-global",
"target_prefix": "s3-access-log/dinghy-dev-demo-sites-logs-global/",
"region": "us-east-1",
"depends_on": [
"aws_s3_bucket.awss3bucket_globallogbucket"
]
}
},
"aws_s3_bucket_policy": {
"cloudfrontsitedemodinghydev_site_root_bucketpolicy": {
"bucket": "dinghy-dev-demo-sites-origin",
"policy": "{\"Version\":\"2008-10-17\",\"Id\":\"PolicyForCloudFrontPrivateContent\",\"Statement\":[{\"Sid\":\"AllowCloudFrontServicePrincipal\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"cloudfront.amazonaws.com\"},\"Action\":\"s3:GetObject\",\"Resource\":\"arn:aws:s3:::dinghy-dev-demo-sites-origin/*\",\"Condition\":{\"ArnLike\":{\"AWS:SourceArn\":[\"${aws_cloudfront_distribution.cloudfrontsitedemodinghydev_site.arn}\"]}}}]}"
},
"awss3bucket_regionallogbucket_policy": {
"bucket": "dinghy-dev-demo-sites-logs-eu-west-1",
"policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"logging.s3.amazonaws.com\"},\"Action\":\"s3:PutObject\",\"Resource\":\"arn:aws:s3:::dinghy-dev-demo-sites-logs-eu-west-1/*\"},{\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"logging.s3.amazonaws.com\"},\"Action\":\"s3:GetBucketAcl\",\"Resource\":\"arn:aws:s3:::dinghy-dev-demo-sites-logs-eu-west-1\"},{\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"delivery.logs.amazonaws.com\"},\"Action\":\"s3:PutObject\",\"Resource\":\"arn:aws:s3:::dinghy-dev-demo-sites-logs-eu-west-1/*\",\"Condition\":{\"StringEquals\":{\"aws:SourceAccount\":\"${data.aws_caller_identity.caller_identity.account_id}\"}}}]}"
}
},
"aws_s3_object": {
"cloudfrontsitedemodinghydev_site_root_404html": {
"bucket": "dinghy-dev-demo-sites-origin",
"cache_control": "max-age=3600, public, must-revalidate",
"content_type": "text/html; charset=UTF-8",
"source": "/dinghy/engine/workspace/demo/s3-files/dinghy-dev-demo-sites-origin/404.html",
"depends_on": [
"aws_s3_bucket.cloudfrontsitedemodinghydev_site_root_bucket"
],
"key": "/404.html",
"tags": {
"Name": "/404.html",
"iac:id": "cloudfrontsitedemodinghydev_site_root_404html"
}
},
"cloudfrontsitedemodinghydev_site_root_indexhtml": {
"bucket": "dinghy-dev-demo-sites-origin",
"cache_control": "max-age=3600, public, must-revalidate",
"content_type": "text/html; charset=UTF-8",
"source": "/dinghy/engine/workspace/demo/s3-files/dinghy-dev-demo-sites-origin/index.html",
"depends_on": [
"aws_s3_bucket.cloudfrontsitedemodinghydev_site_root_bucket"
],
"key": "/index.html",
"tags": {
"Name": "/index.html",
"iac:id": "cloudfrontsitedemodinghydev_site_root_indexhtml"
}
}
},
"aws_acm_certificate": {
"cloudfrontsitedemodinghydev_site_20260104_certificate": {
"domain_name": "cloudfront-site-demo.dinghy.dev",
"region": "us-east-1",
"subject_alternative_names": [],
"tags": {
"iac:id": "cloudfrontsitedemodinghydev_site_20260104_certificate",
"Name": "v20260104"
},
"validation_method": "DNS",
"lifecycle": {
"ignore_changes": [
"subject_alternative_names",
"domain_name"
]
}
},
"cloudfrontsitedemodinghydev_redirect_20260104_certificate": {
"domain_name": "*.cloudfront-site-demo.dinghy.dev",
"region": "us-east-1",
"subject_alternative_names": [],
"tags": {
"iac:id": "cloudfrontsitedemodinghydev_redirect_20260104_certificate",
"Name": "v20260104"
},
"validation_method": "DNS",
"lifecycle": {
"ignore_changes": [
"subject_alternative_names",
"domain_name"
]
}
}
},
"aws_cloudfront_origin_access_control": {
"cloudfrontsitedemodinghydev_originaccesscontrol": {
"name": "oac-cloudfrontsitedemodinghydev",
"origin_access_control_origin_type": "s3",
"signing_behavior": "always",
"signing_protocol": "sigv4"
}
},
"aws_cloudfront_function": {
"cloudfrontsitedemodinghydev_redirect_function": {
"code": "\n function handler(event) {\n var request = event.request;\n \n var newUrl = 'https://cloudfront-site-demo.dinghy.dev';\n var response = {\n statusCode: 301,\n statusDescription: 'Moved Permanently',\n headers: {\n 'location': { value: newUrl }\n }\n };\n return response;\n }",
"name": "cloudfrontsitedemodinghydev_redirect_function",
"runtime": "cloudfront-js-2.0",
"publish": true,
"lifecycle": {
"ignore_changes": [
"name"
]
}
}
},
"aws_s3_bucket_versioning": {
"awss3bucket_backend_versioning": {
"bucket": "dinghy-dev-demo-sites-backend",
"versioning_configuration": {
"status": "Enabled"
},
"depends_on": [
"aws_s3_bucket.awss3bucket_backend"
]
}
},
"aws_s3_bucket_ownership_controls": {
"awss3bucket_globallogbucket_ownership_controls": {
"bucket": "dinghy-dev-demo-sites-logs-global",
"rule": {
"object_ownership": "BucketOwnerPreferred"
},
"region": "us-east-1",
"depends_on": [
"aws_s3_bucket.awss3bucket_globallogbucket"
]
}
}
},
"data": {
"aws_route53_zone": {
"dinghydev_zone": {
"name": "dinghy.dev"
}
},
"aws_caller_identity": {
"caller_identity": {}
}
}
}