private createVpc()

in src/construct-hub.ts [419:521]


  private createVpc(isolation: Isolation, codeArtifact: Repository | undefined) {
    if (isolation === Isolation.UNLIMITED_INTERNET_ACCESS) {
      return { vpc: undefined, vpcEndpoints: undefined, vpcSubnets: undefined };
    }

    const subnetType = isolation === Isolation.NO_INTERNET_ACCESS
      ? ec2.SubnetType.ISOLATED
      : ec2.SubnetType.PRIVATE_WITH_NAT;
    const vpcSubnets = { subnetType };

    const vpc = new ec2.Vpc(this, 'VPC', {
      enableDnsHostnames: true,
      enableDnsSupport: true,
      // Provision no NAT gateways if we are running ISOLATED (we wouldn't have a public subnet)
      natGateways: subnetType === ec2.SubnetType.ISOLATED ? 0 : undefined,
      // Pre-allocating PUBLIC / PRIVATE / INTERNAL subnets, regardless of use, so we don't create
      // a whole new VPC if we ever need to introduce subnets of these types.
      subnetConfiguration: [
        // If there is a PRIVATE subnet, there must also have a PUBLIC subnet (for NAT gateways).
        { name: 'Public', subnetType: ec2.SubnetType.PUBLIC, reserved: subnetType === ec2.SubnetType.ISOLATED },
        { name: 'Private', subnetType: ec2.SubnetType.PRIVATE_WITH_NAT, reserved: subnetType === ec2.SubnetType.ISOLATED },
        { name: 'Isolated', subnetType: ec2.SubnetType.ISOLATED, reserved: subnetType !== ec2.SubnetType.ISOLATED },
      ],
    });
    Tags.of(vpc.node.defaultChild!).add('Name', vpc.node.path);

    const securityGroups = subnetType === ec2.SubnetType.PRIVATE_WITH_NAT
      ? createRestrictedSecurityGroups(this, vpc)
      : undefined;

    // Creating the CodeArtifact endpoints only if a repository is present.
    const codeArtifactEndpoints = codeArtifact && {
      codeArtifactApi: vpc.addInterfaceEndpoint('CodeArtifact.API', {
        privateDnsEnabled: false,
        service: new ec2.InterfaceVpcEndpointAwsService('codeartifact.api'),
        subnets: vpcSubnets,
        securityGroups,
      }),
      codeArtifact: vpc.addInterfaceEndpoint('CodeArtifact', {
        privateDnsEnabled: true,
        service: new ec2.InterfaceVpcEndpointAwsService('codeartifact.repositories'),
        subnets: vpcSubnets,
        securityGroups,
      }),
    };

    // We'll only use VPC endpoints if we are configured to run in an ISOLATED subnet.
    const vpcEndpoints = {
      ...codeArtifactEndpoints,
      // This is needed so that ECS workloads can use the awslogs driver
      cloudWatchLogs: vpc.addInterfaceEndpoint('CloudWatch.Logs', {
        privateDnsEnabled: true,
        service: ec2.InterfaceVpcEndpointAwsService.CLOUDWATCH_LOGS,
        subnets: vpcSubnets,
        securityGroups,
      }),
      // These are needed for ECS workloads to be able to pull images
      ecrApi: vpc.addInterfaceEndpoint('ECR.API', {
        privateDnsEnabled: true,
        service: ec2.InterfaceVpcEndpointAwsService.ECR,
        subnets: vpcSubnets,
        securityGroups,
      }),
      ecr: vpc.addInterfaceEndpoint('ECR.Docker', {
        privateDnsEnabled: true,
        service: ec2.InterfaceVpcEndpointAwsService.ECR_DOCKER,
        subnets: vpcSubnets,
        securityGroups,
      }),
      // This is needed (among others) for CodeArtifact registry usage
      s3: vpc.addGatewayEndpoint('S3', {
        service: ec2.GatewayVpcEndpointAwsService.S3,
        subnets: [vpcSubnets],
      }),
      // This is useful for getting results from ECS tasks within workflows
      stepFunctions: vpc.addInterfaceEndpoint('StepFunctions', {
        privateDnsEnabled: true,
        service: ec2.InterfaceVpcEndpointAwsService.STEP_FUNCTIONS,
        subnets: vpcSubnets,
        securityGroups,
      }),
    };

    // The S3 access is necessary for the CodeArtifact Repository and ECR Docker
    // endpoints to be used (they serve objects from S3).
    vpcEndpoints.s3.addToPolicy(new PolicyStatement({
      effect: Effect.ALLOW,
      actions: ['s3:GetObject'],
      resources: [
        // The in-region CodeArtifact S3 Bucket
        ...codeArtifact ? [`${codeArtifact.s3BucketArn}/*`] : [],
        // The in-region ECR layer bucket
        `arn:aws:s3:::prod-${Stack.of(this).region}-starport-layer-bucket/*`,
      ],
      // It doesn't seem we can constrain principals for these grants (unclear
      // which principal those calls are made from, or if that is something we
      // could name here).
      principals: [new AnyPrincipal()],
      sid: 'Allow-CodeArtifact-and-ECR',
    }));

    return { vpc, vpcEndpoints, vpcSubnets, vpcSecurityGroups: securityGroups };
  }