Skip to content

CloudfrontDistributionBuilder

Bases: AbstractAWSResourceBuilder['CloudfrontDistributionBuilder', CloudfrontConfig]

AWS CDK builder for CloudFront distribution with multi-origin support.

Orchestrates the creation of a comprehensive CloudFront distribution supporting multiple origin types including S3 buckets for static content, Application Load Balancers for dynamic content, and VPC origins for private services. Provides global content delivery with SSL termination, WAF integration, and Route53 DNS management for production-ready web applications.

The builder creates: - CloudFront distribution with global edge caching - Multiple origins with path-based routing behaviors - SSL certificate integration (us-east-1 requirement) - Route53 A record for domain routing - CloudWatch logging configuration - WAF Web ACL integration for security - Origin Access Control for S3 bucket security

Source code in mare_aws_common_lib/builders/cloudfront_builder.py
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
class CloudfrontDistributionBuilder(AbstractAWSResourceBuilder["CloudfrontDistributionBuilder", CloudfrontConfig]):
    """AWS CDK builder for CloudFront distribution with multi-origin support.

    Orchestrates the creation of a comprehensive CloudFront distribution supporting
    multiple origin types including S3 buckets for static content, Application Load
    Balancers for dynamic content, and VPC origins for private services. Provides
    global content delivery with SSL termination, WAF integration, and Route53 DNS
    management for production-ready web applications.

    The builder creates:
    - CloudFront distribution with global edge caching
    - Multiple origins with path-based routing behaviors
    - SSL certificate integration (us-east-1 requirement)
    - Route53 A record for domain routing
    - CloudWatch logging configuration
    - WAF Web ACL integration for security
    - Origin Access Control for S3 bucket security
    """

    _resource_type : AWSResourceType = AWSResourceType.CLOUDFRONT

    def reset(self) -> None:
        """Reset builder state and clear configuration data.

        Initializes the builder for a new build cycle by clearing all
        configuration data and resetting internal state to default values.
        """
        super().reset()
        self._route53_config: Dict[str, Any] = {}
        self._builder_config: Dict[str, Any] = {}

    def set_route53_config(self, config: Dict[str, Any]) -> 'CloudfrontDistributionBuilder':
        """Configure Route53 DNS settings for the CloudFront distribution.

        Sets the hosted zone and domain configuration required for creating
        DNS records that route traffic to the CloudFront distribution edge locations.

        Args:
            config: Route53 configuration containing hosted_zone_id and domain_name

        Returns:
            Builder instance for method chaining
        """
        self._route53_config = config
        return self

    def set_builder_config(self, config: Dict[str, Any]) -> 'CloudfrontDistributionBuilder':
        """Configure core CloudFront distribution settings and origins.

        Sets the main configuration including origins, SSL certificates, WAF settings,
        and logging configuration for the CloudFront distribution deployment.

        Args:
            config: CloudFront configuration with origins, certificates, and security settings

        Returns:
            Builder instance for method chaining
        """
        self._builder_config = config
        return self

    def build(self, scope: Construct) -> cloudfront.Distribution:
        """Build the complete CloudFront distribution infrastructure.

        Creates and configures the CloudFront distribution with all specified origins,
        behaviors, security settings, and DNS integration. Establishes global content
        delivery with proper caching policies and origin routing for multi-tier applications.

        Args:
            scope: CDK construct scope for resource creation

        Returns:
            CloudFront distribution instance for the deployed service

        Raises:
            ValidationError: If configuration validation fails
            ValueError: If required configurations are missing
        """
        super().build()

        origins_cfg: Dict[str, CloudfrontOrigin] = self._config.origins
        name_default_origin: str = "default"

        # We make the assumption that we always have static files to expose in an S3 bucket
        path, static_file_behavior, default_root_object = self._get_static_files_origin(
            origins_cfg[name_default_origin])

        # Create CloudFront distribution
        self._distribution = cloudfront.Distribution(
            scope,
            self._get_cfn_logical_id("distr"),
            default_behavior=static_file_behavior,
            comment=f"Distribution for {self._application_helper.get_project().lower()} with S3 origin and backend origin",
            enable_logging=True if self._config.logs_bucket else False,
            # enable_logging=False,
            domain_names=[self._config.route53.domain_name],
            certificate=self._get_ssl_certificate(scope),
            default_root_object=default_root_object,
            price_class=cloudfront.PriceClass.PRICE_CLASS_ALL,
            enabled=True,
            web_acl_id=self._config.web_acl_id,
            publish_additional_metrics=self._config.activate_additional_metrics,
            log_bucket=self._config.logs_bucket,
            log_file_prefix="cloudfront-logs/" if self._config.logs_bucket else None,
            log_includes_cookies=False
        )

        # Iterate over each origin configuration
        for origin_name, origin_cfg in origins_cfg.items():
            if origin_name != name_default_origin:
                origin_type = origin_cfg.origin_type
                if origin_type == "LOAD_BALANCER":
                    self._add_lb_origin(origin_cfg)
                elif origin_type == "VPC_ORIGIN":
                    self._add_vpc_origin(origin_cfg)
                else:
                    print(f"Unknown origin type: {origin_type}")

        # self._distribution.node.add_dependency(
        #     origins_cfg[name_default_origin].bucket
        # )
        # self._distribution.node.add_dependency(
        #     self._config.logs_bucket
        # )
        # self._add_logs_bucket()

        # Create the route53 A record for the specified domain name pointing to the cloudfront distribution
        self._create_route53_a_record(scope)

        # Store the distribution id in the store parameter in order to be available to other stacks
        self._application_helper.store_parameter(scope,
                                                 "CLOUDFRONT_DISTRIBUTION_ID",
                                                 self._distribution.distribution_id)

        # Store the distribution domain name in the store parameter in order to be available to other stacks
        self._application_helper.store_parameter(scope,
                                                 "CLOUDFRONT_DISTRIBUTION_DOMAIN",
                                                 self._distribution.domain_name)

        return self._distribution

    # def _add_logs_bucket(self):
    #     """Configure CloudFront access logging to S3 bucket.

    #     Adds logging configuration to the CloudFront distribution using CloudFormation
    #     property overrides to enable access log collection with proper bucket domain
    #     name resolution and prefix configuration for log organization.
    #     """
    #     if self._config.logs_bucket is not None:
    #         cfn_distribution = self._distribution.node.default_child
    #         cfn_distribution.add_property_override("DistributionConfig.Logging", {
    #             "Bucket": self._config.typed.logs_bucket.bucket_domain_name,
    #             "IncludeCookies": False,
    #             "Prefix": "cloudfront-logs/"
    #         })

    def _add_lb_origin(self, origin_cfg: LoadBalancerOriginConfig):
        """Add Application Load Balancer origin with dynamic content behavior.

        Creates a CloudFront behavior for ALB-based origins with caching disabled
        for dynamic content, HTTPS-only viewer protocol, and configurable timeout
        settings for API and application server integration.

        Args:
            origin_cfg: Load balancer origin configuration with path and timeout settings
        """
        self._distribution.add_behavior(
            path_pattern=origin_cfg.path,
            origin=origins.LoadBalancerV2Origin(
                origin_cfg.alb, 
                origin_id=origin_cfg.name, 
                read_timeout=Duration.seconds(origin_cfg.timeout)
            ),
            cache_policy=CachePolicy.CACHING_DISABLED,
            origin_request_policy=cloudfront.OriginRequestPolicy.ALL_VIEWER,
            viewer_protocol_policy=cloudfront.ViewerProtocolPolicy.HTTPS_ONLY,
            allowed_methods=cloudfront.AllowedMethods.ALLOW_ALL

        )

    def _add_vpc_origin(self, origin_cfg: VpcOriginConfig) -> tuple[str, cloudfront.BehaviorOptions]:
        """Add VPC origin with private network integration behavior.

        Creates a CloudFront behavior for VPC-based origins enabling private
        network access through VPC origin configuration with ALB integration,
        caching disabled for dynamic content, and secure HTTPS communication.

        Args:
            origin_cfg: VPC origin configuration with path and timeout settings

        Returns:
            Tuple containing path pattern and behavior configuration
        """
        self._distribution.add_behavior(
            path_pattern=origin_cfg.path,
            origin=origins.VpcOrigin(
                origins.VpcOrigin.with_application_load_balancer(origin_cfg.alb),
                origin_id=origin_cfg.name, 
                read_timeout=Duration.seconds(origin_cfg.timeout)
            ),
            cache_policy=CachePolicy.CACHING_DISABLED,
            origin_request_policy=cloudfront.OriginRequestPolicy.ALL_VIEWER,
            viewer_protocol_policy=cloudfront.ViewerProtocolPolicy.HTTPS_ONLY,
            allowed_methods=cloudfront.AllowedMethods.ALLOW_ALL
        )

    def _get_static_files_origin(self, origin_cfg: S3OriginConfig) -> tuple[str, cloudfront.BehaviorOptions, str]:
        """Configure S3 bucket origin for static content delivery.

        Creates the default behavior for S3-based static content with Origin Access
        Control for security, optimized caching for performance, and HTTPS redirect
        for secure content delivery. Serves as the fallback origin for the distribution.

        Args:
            origin_cfg: S3 origin configuration with bucket and path settings

        Returns:
            Tuple containing path, behavior options, and default root object
        """
        bucket: s3.Bucket = origin_cfg.bucket
        path: str = origin_cfg.path
        default_root_object: str = origin_cfg.default_root_object

        behavior: cloudfront.BehaviorOptions = cloudfront.BehaviorOptions(
            origin=origins.S3BucketOrigin.with_origin_access_control(bucket, origin_id=origin_cfg.name),
            viewer_protocol_policy=cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
            cache_policy=CachePolicy.CACHING_OPTIMIZED
        )
        return path, behavior, default_root_object

    def _create_route53_a_record(self, scope: Construct) -> None:
        """Create Route53 A record pointing to the CloudFront distribution.

        Creates an alias A record that routes DNS queries for the configured
        domain to the CloudFront distribution edge locations for global content
        delivery and improved performance.

        Args:
            scope: CDK construct scope for resource creation
        """
        route53.ARecord(
            scope,
            self._get_cfn_logical_id("alb-alias"),
            zone=self._get_route53_hosted_zone(scope),
            record_name=self._config.route53.domain_name,
            target=route53.RecordTarget.from_alias(targets.CloudFrontTarget(self._distribution))
        )

    def _get_route53_hosted_zone(self, scope: Construct) -> route53.HostedZone:
        """Retrieve Route53 hosted zone reference for DNS record management.

        Creates a reference to the existing Route53 hosted zone for creating
        DNS records that route traffic to the CloudFront distribution.

        Args:
            scope: CDK construct scope for resource reference

        Returns:
            Route53 hosted zone reference
        """
        return route53.HostedZone.from_hosted_zone_attributes(
            scope,
            self._get_cfn_logical_id("hosted-zone"),
            hosted_zone_id=self._config.route53.hosted_zone_id,
            zone_name=self._config.route53.domain_name
        )

    def _get_ssl_certificate(self, scope: Construct) -> acm.ICertificate:
        """Retrieve SSL certificate reference for CloudFront HTTPS termination.

        Creates a reference to the existing ACM certificate located in us-east-1
        region as required by CloudFront for global SSL/TLS termination at edge
        locations worldwide.

        Args:
            scope: CDK construct scope for resource reference

        Returns:
            ACM certificate reference for HTTPS configuration
        """
        ssl_certificate = acm.Certificate.from_certificate_arn(
            scope,
            self._get_cfn_logical_id(f"{self._application_helper.get_target_env()}-ssl-certificate"),
            # The app is deployed in the is eu-west-1 region, but the certificate is hosted in us-east-1, hence ce enforce the us-east-1 region instead of {Aws.REGION} for the arn
            certificate_arn=f"arn:aws:acm:us-east-1:{Aws.ACCOUNT_ID}:certificate/{self._config.ssl_certificate_id}"
        )
        return ssl_certificate

    def _set_config(self) -> None:
        """Validate and set the CloudFront configuration from builder inputs.

        Combines the builder configuration with Route53 parameters to create a
        validated CloudfrontConfig instance, ensuring all required fields and
        validation rules are satisfied for successful deployment.

        Raises:
            ValidationError: If the combined configuration fails validation
        """
        try:
            self._config = CloudfrontConfig(**{
                **self._builder_config,
                "route53": self._route53_config
            })
        except ValidationError as e:
            self._log_validation_error(e, CloudfrontConfig)
            raise

    def _control_consistency(self) -> None:
        """Validate builder state and configuration consistency.

        Performs pre-build validation to ensure all required configurations
        are present and the builder state is consistent for successful
        CloudFront distribution deployment with proper DNS integration.

        Raises:
            ValueError: If Route53 configuration is missing
            ValidationError: If configuration validation fails
        """
        super()._control_consistency()

        if not self._route53_config:
            raise ValueError("Route 53 configuration must be set before building")

        self._set_config()

Attributes

_resource_type = AWSResourceType.CLOUDFRONT class-attribute instance-attribute

Functions

_add_lb_origin(origin_cfg)

Add Application Load Balancer origin with dynamic content behavior.

Creates a CloudFront behavior for ALB-based origins with caching disabled for dynamic content, HTTPS-only viewer protocol, and configurable timeout settings for API and application server integration.

Parameters:

Name Type Description Default
origin_cfg LoadBalancerOriginConfig

Load balancer origin configuration with path and timeout settings

required
Source code in mare_aws_common_lib/builders/cloudfront_builder.py
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
def _add_lb_origin(self, origin_cfg: LoadBalancerOriginConfig):
    """Add Application Load Balancer origin with dynamic content behavior.

    Creates a CloudFront behavior for ALB-based origins with caching disabled
    for dynamic content, HTTPS-only viewer protocol, and configurable timeout
    settings for API and application server integration.

    Args:
        origin_cfg: Load balancer origin configuration with path and timeout settings
    """
    self._distribution.add_behavior(
        path_pattern=origin_cfg.path,
        origin=origins.LoadBalancerV2Origin(
            origin_cfg.alb, 
            origin_id=origin_cfg.name, 
            read_timeout=Duration.seconds(origin_cfg.timeout)
        ),
        cache_policy=CachePolicy.CACHING_DISABLED,
        origin_request_policy=cloudfront.OriginRequestPolicy.ALL_VIEWER,
        viewer_protocol_policy=cloudfront.ViewerProtocolPolicy.HTTPS_ONLY,
        allowed_methods=cloudfront.AllowedMethods.ALLOW_ALL

    )

_add_vpc_origin(origin_cfg)

Add VPC origin with private network integration behavior.

Creates a CloudFront behavior for VPC-based origins enabling private network access through VPC origin configuration with ALB integration, caching disabled for dynamic content, and secure HTTPS communication.

Parameters:

Name Type Description Default
origin_cfg VpcOriginConfig

VPC origin configuration with path and timeout settings

required

Returns:

Type Description
tuple[str, BehaviorOptions]

Tuple containing path pattern and behavior configuration

Source code in mare_aws_common_lib/builders/cloudfront_builder.py
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
def _add_vpc_origin(self, origin_cfg: VpcOriginConfig) -> tuple[str, cloudfront.BehaviorOptions]:
    """Add VPC origin with private network integration behavior.

    Creates a CloudFront behavior for VPC-based origins enabling private
    network access through VPC origin configuration with ALB integration,
    caching disabled for dynamic content, and secure HTTPS communication.

    Args:
        origin_cfg: VPC origin configuration with path and timeout settings

    Returns:
        Tuple containing path pattern and behavior configuration
    """
    self._distribution.add_behavior(
        path_pattern=origin_cfg.path,
        origin=origins.VpcOrigin(
            origins.VpcOrigin.with_application_load_balancer(origin_cfg.alb),
            origin_id=origin_cfg.name, 
            read_timeout=Duration.seconds(origin_cfg.timeout)
        ),
        cache_policy=CachePolicy.CACHING_DISABLED,
        origin_request_policy=cloudfront.OriginRequestPolicy.ALL_VIEWER,
        viewer_protocol_policy=cloudfront.ViewerProtocolPolicy.HTTPS_ONLY,
        allowed_methods=cloudfront.AllowedMethods.ALLOW_ALL
    )

_control_consistency()

Validate builder state and configuration consistency.

Performs pre-build validation to ensure all required configurations are present and the builder state is consistent for successful CloudFront distribution deployment with proper DNS integration.

Raises:

Type Description
ValueError

If Route53 configuration is missing

ValidationError

If configuration validation fails

Source code in mare_aws_common_lib/builders/cloudfront_builder.py
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
def _control_consistency(self) -> None:
    """Validate builder state and configuration consistency.

    Performs pre-build validation to ensure all required configurations
    are present and the builder state is consistent for successful
    CloudFront distribution deployment with proper DNS integration.

    Raises:
        ValueError: If Route53 configuration is missing
        ValidationError: If configuration validation fails
    """
    super()._control_consistency()

    if not self._route53_config:
        raise ValueError("Route 53 configuration must be set before building")

    self._set_config()

_create_route53_a_record(scope)

Create Route53 A record pointing to the CloudFront distribution.

Creates an alias A record that routes DNS queries for the configured domain to the CloudFront distribution edge locations for global content delivery and improved performance.

Parameters:

Name Type Description Default
scope Construct

CDK construct scope for resource creation

required
Source code in mare_aws_common_lib/builders/cloudfront_builder.py
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
def _create_route53_a_record(self, scope: Construct) -> None:
    """Create Route53 A record pointing to the CloudFront distribution.

    Creates an alias A record that routes DNS queries for the configured
    domain to the CloudFront distribution edge locations for global content
    delivery and improved performance.

    Args:
        scope: CDK construct scope for resource creation
    """
    route53.ARecord(
        scope,
        self._get_cfn_logical_id("alb-alias"),
        zone=self._get_route53_hosted_zone(scope),
        record_name=self._config.route53.domain_name,
        target=route53.RecordTarget.from_alias(targets.CloudFrontTarget(self._distribution))
    )

_get_route53_hosted_zone(scope)

Retrieve Route53 hosted zone reference for DNS record management.

Creates a reference to the existing Route53 hosted zone for creating DNS records that route traffic to the CloudFront distribution.

Parameters:

Name Type Description Default
scope Construct

CDK construct scope for resource reference

required

Returns:

Type Description
HostedZone

Route53 hosted zone reference

Source code in mare_aws_common_lib/builders/cloudfront_builder.py
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
def _get_route53_hosted_zone(self, scope: Construct) -> route53.HostedZone:
    """Retrieve Route53 hosted zone reference for DNS record management.

    Creates a reference to the existing Route53 hosted zone for creating
    DNS records that route traffic to the CloudFront distribution.

    Args:
        scope: CDK construct scope for resource reference

    Returns:
        Route53 hosted zone reference
    """
    return route53.HostedZone.from_hosted_zone_attributes(
        scope,
        self._get_cfn_logical_id("hosted-zone"),
        hosted_zone_id=self._config.route53.hosted_zone_id,
        zone_name=self._config.route53.domain_name
    )

_get_ssl_certificate(scope)

Retrieve SSL certificate reference for CloudFront HTTPS termination.

Creates a reference to the existing ACM certificate located in us-east-1 region as required by CloudFront for global SSL/TLS termination at edge locations worldwide.

Parameters:

Name Type Description Default
scope Construct

CDK construct scope for resource reference

required

Returns:

Type Description
ICertificate

ACM certificate reference for HTTPS configuration

Source code in mare_aws_common_lib/builders/cloudfront_builder.py
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
def _get_ssl_certificate(self, scope: Construct) -> acm.ICertificate:
    """Retrieve SSL certificate reference for CloudFront HTTPS termination.

    Creates a reference to the existing ACM certificate located in us-east-1
    region as required by CloudFront for global SSL/TLS termination at edge
    locations worldwide.

    Args:
        scope: CDK construct scope for resource reference

    Returns:
        ACM certificate reference for HTTPS configuration
    """
    ssl_certificate = acm.Certificate.from_certificate_arn(
        scope,
        self._get_cfn_logical_id(f"{self._application_helper.get_target_env()}-ssl-certificate"),
        # The app is deployed in the is eu-west-1 region, but the certificate is hosted in us-east-1, hence ce enforce the us-east-1 region instead of {Aws.REGION} for the arn
        certificate_arn=f"arn:aws:acm:us-east-1:{Aws.ACCOUNT_ID}:certificate/{self._config.ssl_certificate_id}"
    )
    return ssl_certificate

_get_static_files_origin(origin_cfg)

Configure S3 bucket origin for static content delivery.

Creates the default behavior for S3-based static content with Origin Access Control for security, optimized caching for performance, and HTTPS redirect for secure content delivery. Serves as the fallback origin for the distribution.

Parameters:

Name Type Description Default
origin_cfg S3OriginConfig

S3 origin configuration with bucket and path settings

required

Returns:

Type Description
tuple[str, BehaviorOptions, str]

Tuple containing path, behavior options, and default root object

Source code in mare_aws_common_lib/builders/cloudfront_builder.py
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
def _get_static_files_origin(self, origin_cfg: S3OriginConfig) -> tuple[str, cloudfront.BehaviorOptions, str]:
    """Configure S3 bucket origin for static content delivery.

    Creates the default behavior for S3-based static content with Origin Access
    Control for security, optimized caching for performance, and HTTPS redirect
    for secure content delivery. Serves as the fallback origin for the distribution.

    Args:
        origin_cfg: S3 origin configuration with bucket and path settings

    Returns:
        Tuple containing path, behavior options, and default root object
    """
    bucket: s3.Bucket = origin_cfg.bucket
    path: str = origin_cfg.path
    default_root_object: str = origin_cfg.default_root_object

    behavior: cloudfront.BehaviorOptions = cloudfront.BehaviorOptions(
        origin=origins.S3BucketOrigin.with_origin_access_control(bucket, origin_id=origin_cfg.name),
        viewer_protocol_policy=cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
        cache_policy=CachePolicy.CACHING_OPTIMIZED
    )
    return path, behavior, default_root_object

_set_config()

Validate and set the CloudFront configuration from builder inputs.

Combines the builder configuration with Route53 parameters to create a validated CloudfrontConfig instance, ensuring all required fields and validation rules are satisfied for successful deployment.

Raises:

Type Description
ValidationError

If the combined configuration fails validation

Source code in mare_aws_common_lib/builders/cloudfront_builder.py
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
def _set_config(self) -> None:
    """Validate and set the CloudFront configuration from builder inputs.

    Combines the builder configuration with Route53 parameters to create a
    validated CloudfrontConfig instance, ensuring all required fields and
    validation rules are satisfied for successful deployment.

    Raises:
        ValidationError: If the combined configuration fails validation
    """
    try:
        self._config = CloudfrontConfig(**{
            **self._builder_config,
            "route53": self._route53_config
        })
    except ValidationError as e:
        self._log_validation_error(e, CloudfrontConfig)
        raise

build(scope)

Build the complete CloudFront distribution infrastructure.

Creates and configures the CloudFront distribution with all specified origins, behaviors, security settings, and DNS integration. Establishes global content delivery with proper caching policies and origin routing for multi-tier applications.

Parameters:

Name Type Description Default
scope Construct

CDK construct scope for resource creation

required

Returns:

Type Description
Distribution

CloudFront distribution instance for the deployed service

Raises:

Type Description
ValidationError

If configuration validation fails

ValueError

If required configurations are missing

Source code in mare_aws_common_lib/builders/cloudfront_builder.py
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
def build(self, scope: Construct) -> cloudfront.Distribution:
    """Build the complete CloudFront distribution infrastructure.

    Creates and configures the CloudFront distribution with all specified origins,
    behaviors, security settings, and DNS integration. Establishes global content
    delivery with proper caching policies and origin routing for multi-tier applications.

    Args:
        scope: CDK construct scope for resource creation

    Returns:
        CloudFront distribution instance for the deployed service

    Raises:
        ValidationError: If configuration validation fails
        ValueError: If required configurations are missing
    """
    super().build()

    origins_cfg: Dict[str, CloudfrontOrigin] = self._config.origins
    name_default_origin: str = "default"

    # We make the assumption that we always have static files to expose in an S3 bucket
    path, static_file_behavior, default_root_object = self._get_static_files_origin(
        origins_cfg[name_default_origin])

    # Create CloudFront distribution
    self._distribution = cloudfront.Distribution(
        scope,
        self._get_cfn_logical_id("distr"),
        default_behavior=static_file_behavior,
        comment=f"Distribution for {self._application_helper.get_project().lower()} with S3 origin and backend origin",
        enable_logging=True if self._config.logs_bucket else False,
        # enable_logging=False,
        domain_names=[self._config.route53.domain_name],
        certificate=self._get_ssl_certificate(scope),
        default_root_object=default_root_object,
        price_class=cloudfront.PriceClass.PRICE_CLASS_ALL,
        enabled=True,
        web_acl_id=self._config.web_acl_id,
        publish_additional_metrics=self._config.activate_additional_metrics,
        log_bucket=self._config.logs_bucket,
        log_file_prefix="cloudfront-logs/" if self._config.logs_bucket else None,
        log_includes_cookies=False
    )

    # Iterate over each origin configuration
    for origin_name, origin_cfg in origins_cfg.items():
        if origin_name != name_default_origin:
            origin_type = origin_cfg.origin_type
            if origin_type == "LOAD_BALANCER":
                self._add_lb_origin(origin_cfg)
            elif origin_type == "VPC_ORIGIN":
                self._add_vpc_origin(origin_cfg)
            else:
                print(f"Unknown origin type: {origin_type}")

    # self._distribution.node.add_dependency(
    #     origins_cfg[name_default_origin].bucket
    # )
    # self._distribution.node.add_dependency(
    #     self._config.logs_bucket
    # )
    # self._add_logs_bucket()

    # Create the route53 A record for the specified domain name pointing to the cloudfront distribution
    self._create_route53_a_record(scope)

    # Store the distribution id in the store parameter in order to be available to other stacks
    self._application_helper.store_parameter(scope,
                                             "CLOUDFRONT_DISTRIBUTION_ID",
                                             self._distribution.distribution_id)

    # Store the distribution domain name in the store parameter in order to be available to other stacks
    self._application_helper.store_parameter(scope,
                                             "CLOUDFRONT_DISTRIBUTION_DOMAIN",
                                             self._distribution.domain_name)

    return self._distribution

reset()

Reset builder state and clear configuration data.

Initializes the builder for a new build cycle by clearing all configuration data and resetting internal state to default values.

Source code in mare_aws_common_lib/builders/cloudfront_builder.py
40
41
42
43
44
45
46
47
48
def reset(self) -> None:
    """Reset builder state and clear configuration data.

    Initializes the builder for a new build cycle by clearing all
    configuration data and resetting internal state to default values.
    """
    super().reset()
    self._route53_config: Dict[str, Any] = {}
    self._builder_config: Dict[str, Any] = {}

set_builder_config(config)

Configure core CloudFront distribution settings and origins.

Sets the main configuration including origins, SSL certificates, WAF settings, and logging configuration for the CloudFront distribution deployment.

Parameters:

Name Type Description Default
config Dict[str, Any]

CloudFront configuration with origins, certificates, and security settings

required

Returns:

Type Description
CloudfrontDistributionBuilder

Builder instance for method chaining

Source code in mare_aws_common_lib/builders/cloudfront_builder.py
65
66
67
68
69
70
71
72
73
74
75
76
77
78
def set_builder_config(self, config: Dict[str, Any]) -> 'CloudfrontDistributionBuilder':
    """Configure core CloudFront distribution settings and origins.

    Sets the main configuration including origins, SSL certificates, WAF settings,
    and logging configuration for the CloudFront distribution deployment.

    Args:
        config: CloudFront configuration with origins, certificates, and security settings

    Returns:
        Builder instance for method chaining
    """
    self._builder_config = config
    return self

set_route53_config(config)

Configure Route53 DNS settings for the CloudFront distribution.

Sets the hosted zone and domain configuration required for creating DNS records that route traffic to the CloudFront distribution edge locations.

Parameters:

Name Type Description Default
config Dict[str, Any]

Route53 configuration containing hosted_zone_id and domain_name

required

Returns:

Type Description
CloudfrontDistributionBuilder

Builder instance for method chaining

Source code in mare_aws_common_lib/builders/cloudfront_builder.py
50
51
52
53
54
55
56
57
58
59
60
61
62
63
def set_route53_config(self, config: Dict[str, Any]) -> 'CloudfrontDistributionBuilder':
    """Configure Route53 DNS settings for the CloudFront distribution.

    Sets the hosted zone and domain configuration required for creating
    DNS records that route traffic to the CloudFront distribution edge locations.

    Args:
        config: Route53 configuration containing hosted_zone_id and domain_name

    Returns:
        Builder instance for method chaining
    """
    self._route53_config = config
    return self