packages/aws-cdk-lib/aws-cloudfront/lib/vpc-origin.ts (109 lines of code) (raw):

import { Construct } from 'constructs'; import { CfnVpcOrigin } from './cloudfront.generated'; import { OriginProtocolPolicy, OriginSslPolicy } from '../'; import { IInstance } from '../../aws-ec2'; import { IApplicationLoadBalancer, INetworkLoadBalancer } from '../../aws-elasticloadbalancingv2'; import { ArnFormat, IResource, ITaggableV2, Names, Resource, Stack, TagManager, Token, ValidationError } from '../../core'; import { addConstructMetadata } from '../../core/lib/metadata-resource'; /** * Represents a VPC origin. */ export interface IVpcOrigin extends IResource { /** * The VPC origin ARN. * @attribute */ readonly vpcOriginArn: string; /** * The VPC origin ID. * @attribute */ readonly vpcOriginId: string; /** * The domain name of the CloudFront VPC origin endpoint configuration. */ readonly domainName?: string; } /** * VPC origin endpoint configuration. */ export interface VpcOriginOptions { /** * The HTTP port for the CloudFront VPC origin endpoint configuration. * @default 80 */ readonly httpPort?: number; /** * The HTTPS port of the CloudFront VPC origin endpoint configuration. * @default 443 */ readonly httpsPort?: number; /** * The name of the CloudFront VPC origin endpoint configuration. * @default - generated from the `id` */ readonly vpcOriginName?: string; /** * The origin protocol policy for the CloudFront VPC origin endpoint configuration. * @default OriginProtocolPolicy.MATCH_VIEWER */ readonly protocolPolicy?: OriginProtocolPolicy; /** * A list that contains allowed SSL/TLS protocols for this distribution. * @default - TLSv1.2 */ readonly originSslProtocols?: OriginSslPolicy[]; } /** * VPC origin endpoint configuration. */ export interface VpcOriginProps extends VpcOriginOptions { /** * The VPC origin endpoint. */ readonly endpoint: VpcOriginEndpoint; } /** * The properties to import from the VPC origin */ export interface VpcOriginAttributes { /** * The ARN of the VPC origin. * * At least one of vpcOriginArn and vpcOriginId must be provided. * * @default - derived from `vpcOriginId`. */ readonly vpcOriginArn?: string; /** * The ID of the VPC origin. * * At least one of vpcOriginArn and vpcOriginId must be provided. * * @default - derived from `vpcOriginArn`. */ readonly vpcOriginId?: string; /** * The domain name of the CloudFront VPC origin endpoint configuration. * @default - No domain name configured */ readonly domainName?: string; } /** * Represents the VPC origin endpoint. */ export abstract class VpcOriginEndpoint { /** * A VPC origin endpoint from an EC2 instance. */ public static ec2Instance(instance: IInstance): VpcOriginEndpoint { const endpointArn = Stack.of(instance).formatArn({ service: 'ec2', resource: 'instance', resourceName: instance.instanceId, }); return { endpointArn, domainName: instance.instancePrivateDnsName }; } /** * A VPC origin endpoint from an Application Load Balancer. */ public static applicationLoadBalancer(alb: IApplicationLoadBalancer): VpcOriginEndpoint { return { endpointArn: alb.loadBalancerArn, domainName: alb.loadBalancerDnsName }; } /** * A VPC origin endpoint from an Network Load Balancer. */ public static networkLoadBalancer(nlb: INetworkLoadBalancer): VpcOriginEndpoint { return { endpointArn: nlb.loadBalancerArn, domainName: nlb.loadBalancerDnsName }; } /** * The ARN of the CloudFront VPC origin endpoint configuration. */ abstract readonly endpointArn: string; /** * The domain name of the CloudFront VPC origin endpoint configuration. * @default - No domain name configured */ abstract readonly domainName?: string; } /** * A CloudFront VPC Origin configuration. * * @resource AWS::CloudFront::VpcOrigin */ export class VpcOrigin extends Resource implements IVpcOrigin, ITaggableV2 { /** * Import an existing VPC origin from its ID. */ public static fromVpcOriginId(scope: Construct, id: string, vpcOriginId: string): IVpcOrigin { return this.fromVpcOriginAttributes(scope, id, { vpcOriginId }); } /** * Import an existing VPC origin from its ARN. */ public static fromVpcOriginArn(scope: Construct, id: string, vpcOriginArn: string): IVpcOrigin { return this.fromVpcOriginAttributes(scope, id, { vpcOriginArn }); } /** * Import an existing VPC origin from its attributes. */ public static fromVpcOriginAttributes(scope: Construct, id: string, attrs: VpcOriginAttributes): IVpcOrigin { if (!attrs.vpcOriginArn && !attrs.vpcOriginId) { throw new ValidationError('Either vpcOriginId or vpcOriginArn must be provided in VpcOriginAttributes', scope); } const vpcOriginId = attrs.vpcOriginId ?? Stack.of(scope).splitArn(attrs.vpcOriginArn!, ArnFormat.SLASH_RESOURCE_NAME).resourceName; if (!vpcOriginId) { throw new ValidationError(`No VPC origin ID found in ARN: '${attrs.vpcOriginArn}'`, scope); } const vpcOriginArn = attrs.vpcOriginArn ?? Stack.of(scope).formatArn({ service: 'cloudfront', region: '', resource: 'vpcorigin', resourceName: vpcOriginId, }); class Import extends Resource implements IVpcOrigin { readonly vpcOriginArn = vpcOriginArn; readonly vpcOriginId = vpcOriginId!; readonly domainName = attrs.domainName; } return new Import(scope, id); } /** * The VPC origin ARN. * @attribute */ readonly vpcOriginArn: string; /** * The VPC origin ID. * @attribute */ readonly vpcOriginId: string; /** * The domain name of the CloudFront VPC origin endpoint configuration. */ readonly domainName?: string; readonly cdkTagManager: TagManager; constructor(scope: Construct, id: string, props: VpcOriginProps) { super(scope, id); // Enhanced CDK Analytics Telemetry addConstructMetadata(this, props); this.validatePortNumber(props.httpPort, 'httpPort'); this.validatePortNumber(props.httpsPort, 'httpsPort'); const resource = new CfnVpcOrigin(this, 'Resource', { vpcOriginEndpointConfig: { arn: props.endpoint.endpointArn, httpPort: props.httpPort, httpsPort: props.httpsPort, name: props.vpcOriginName ?? Names.uniqueResourceName(this, { maxLength: 64 }), originProtocolPolicy: props.protocolPolicy, originSslProtocols: props.originSslProtocols ?? [OriginSslPolicy.TLS_V1_2], }, }); this.vpcOriginArn = this.getResourceArnAttribute(resource.attrArn, { service: 'cloudfront', region: '', resource: 'vpcorigin', resourceName: resource.attrId, }); this.vpcOriginId = resource.attrId; this.domainName = props.endpoint.domainName; this.cdkTagManager = resource.cdkTagManager; } private validatePortNumber(port: number | undefined, attrName: string) { if (port && !Token.isUnresolved(port) && !([80, 443].includes(port) || (port >= 1024 && port <= 65535))) { throw new ValidationError(`'${attrName}' must be 80, 443, or a value between 1024 and 65535, got ${port}`, this); } } }