From b729efa6f0addf5a3262e38f4449209f274cf202 Mon Sep 17 00:00:00 2001 From: Naveen Kumar Date: Fri, 25 Sep 2020 18:43:00 +0530 Subject: [PATCH 01/14] fix(core): Moving Interface endpoints creation to Phase 3 --- src/deployments/cdk/src/apps/phase-1.ts | 44 ---- src/deployments/cdk/src/apps/phase-2.ts | 9 +- .../cdk/src/deployments/vpc/index.ts | 1 + .../cdk/src/deployments/vpc/step-3.ts | 204 ++++++++++++++++++ 4 files changed, 213 insertions(+), 45 deletions(-) create mode 100644 src/deployments/cdk/src/deployments/vpc/step-3.ts diff --git a/src/deployments/cdk/src/apps/phase-1.ts b/src/deployments/cdk/src/apps/phase-1.ts index a980249f6..88feb4c0e 100644 --- a/src/deployments/cdk/src/apps/phase-1.ts +++ b/src/deployments/cdk/src/apps/phase-1.ts @@ -157,50 +157,6 @@ export async function deploy({ acceleratorConfig, accountStacks, accounts, conte const vpcStack = new VpcStack(accountStack, `VpcStack${vpcStackPrettyName}`, props); const vpc = vpcStack.vpc; - const endpointConfig = vpcConfig['interface-endpoints']; - if (InterfaceEndpointConfig.is(endpointConfig)) { - const subnetName = endpointConfig.subnet; - const subnetIds = vpc.azSubnets.getAzSubnetIdsForSubnetName(subnetName); - if (subnetIds.length === 0) { - console.warn(`Cannot find subnet ID with name "${subnetName}'`); - return; - } - - let endpointCount = 0; - let endpointStackIndex = 0; - let endpointStack; - for (const endpoint of endpointConfig.endpoints) { - if (!limiter.create(accountKey, Limit.VpcInterfaceEndpointsPerVpc, vpc.name)) { - console.log( - `Skipping endpoint "${endpoint}" creation in VPC "${vpc.name}". Reached maximum interface endpoints per VPC`, - ); - continue; - } - - if (!endpointStack || endpointCount >= 30) { - endpointStack = new NestedStack(accountStack, `Endpoint${endpointStackIndex++}`); - endpointCount = 0; - } - const interfaceEndpoint = new InterfaceEndpoint(endpointStack, pascalCase(endpoint), { - serviceName: endpoint, - vpcId: vpc.vpcId, - vpcRegion: vpc.region, - subnetIds, - }); - - new centralEndpoints.CfnHostedZoneOutput(endpointStack, `HostedZoneOutput-${endpoint}`, { - accountKey, - domain: interfaceEndpoint.hostedZone.name, - hostedZoneId: interfaceEndpoint.hostedZone.ref, - region: vpc.region, - zoneType: 'PRIVATE', - serviceName: endpoint, - vpcName: vpc.name, - }); - endpointCount++; - } - } - // Store the VPC output so that subsequent phases can access the output new vpcDeployment.CfnVpcOutput(vpc, `VpcOutput`, { accountKey, diff --git a/src/deployments/cdk/src/apps/phase-2.ts b/src/deployments/cdk/src/apps/phase-2.ts index b7b5e1069..9f53b9681 100644 --- a/src/deployments/cdk/src/apps/phase-2.ts +++ b/src/deployments/cdk/src/apps/phase-2.ts @@ -45,7 +45,7 @@ import * as snsDeployment from '../deployments/sns'; * - TGW Peering Attachments */ -export async function deploy({ acceleratorConfig, accountStacks, accounts, context, outputs }: PhaseInput) { +export async function deploy({ acceleratorConfig, accountStacks, accounts, context, outputs, limiter }: PhaseInput) { const securityAccountKey = acceleratorConfig.getMandatoryAccountKey('central-security'); // Find the account buckets in the outputs @@ -330,4 +330,11 @@ export async function deploy({ acceleratorConfig, accountStacks, accounts, conte config: acceleratorConfig, outputs, }); + + await vpcDeployment.step3({ + accountStacks, + config: acceleratorConfig, + limiter, + outputs, + }); } diff --git a/src/deployments/cdk/src/deployments/vpc/index.ts b/src/deployments/cdk/src/deployments/vpc/index.ts index 36c3424d9..875763069 100644 --- a/src/deployments/cdk/src/deployments/vpc/index.ts +++ b/src/deployments/cdk/src/deployments/vpc/index.ts @@ -1,3 +1,4 @@ export * from './outputs'; export * from './step-1'; export * from './step-2'; +export * from './step-3'; diff --git a/src/deployments/cdk/src/deployments/vpc/step-3.ts b/src/deployments/cdk/src/deployments/vpc/step-3.ts new file mode 100644 index 000000000..673d9c335 --- /dev/null +++ b/src/deployments/cdk/src/deployments/vpc/step-3.ts @@ -0,0 +1,204 @@ +import { AcceleratorConfig, InterfaceEndpointConfig } from '@aws-accelerator/common-config'; +import { StackOutput } from '@aws-accelerator/common-outputs/src/stack-output'; +import { + StaticResourcesOutput, + StaticResourcesOutputFinder, +} from '@aws-accelerator/common-outputs/src/static-resource'; +import { AccountStacks } from '../../common/account-stacks'; +import { VpcOutputFinder } from '@aws-accelerator/common-outputs/src/vpc'; +import { region } from '@aws-accelerator/common-types'; +import { CfnHostedZoneOutput, CfnStaticResourcesOutput } from '../central-endpoints'; +import { InterfaceEndpoint } from '../../common/interface-endpoints'; +import { pascalCase } from 'pascal-case'; +import { Limit, Limiter } from '../../utils/limits'; + +// Changing this will result to redeploy most of the stack +const MAX_RESOURCES_IN_STACK = 30; +const RESOURCE_TYPE = 'INTERFACE_ENDPOINTS'; +const STACK_SUFFIX = 'VPCEndpoints'; + +interface VpcStep3Props { + config: AcceleratorConfig; + outputs: StackOutput[]; + accountStacks: AccountStacks; + limiter: Limiter; +} + +export async function step3(props: VpcStep3Props) { + const { config, outputs, accountStacks, limiter } = props; + const allStaticResources = StaticResourcesOutputFinder.findAll({ + outputs, + }).filter(sr => sr.resourceType === RESOURCE_TYPE); + + const accountStaticResourcesConfig: { [accountKey: string]: StaticResourcesOutput[] } = {}; + const accountRegionExistingResources: { + [accountKey: string]: { + [region: string]: string[]; + }; + } = {}; + const accountRegionMaxSuffix: { + [accountKey: string]: { + [region: string]: number; + }; + } = {}; + + // Initiate previous stacks to handle deletion of previously deployed stack if there are no resources + for (const sr of allStaticResources) { + accountStacks.tryGetOrCreateAccountStack(sr.accountKey, sr.region, `${STACK_SUFFIX}-${sr.suffix}`); + } + + for (const { accountKey, vpcConfig } of config.getVpcConfigs()) { + if (!InterfaceEndpointConfig.is(vpcConfig['interface-endpoints'])) { + continue; + } + const endpointsConfig = vpcConfig['interface-endpoints']; + + // Retrieving current VPCId + const vpcOutput = VpcOutputFinder.tryFindOneByAccountAndRegionAndName({ + outputs, + accountKey, + region: vpcConfig.region, + vpcName: vpcConfig.name, + }); + if (!vpcOutput) { + console.error(`Cannot find resolved VPC with name "${vpcConfig.name}"`); + continue; + } + + let suffix: number; + let stackSuffix: string; + let newResource = true; + + // Load all account stacks to object + if (!accountStaticResourcesConfig[accountKey]) { + accountStaticResourcesConfig[accountKey] = allStaticResources.filter(sr => sr.accountKey === accountKey); + } + if (!accountRegionMaxSuffix[accountKey]) { + accountRegionMaxSuffix[accountKey] = {}; + } + + // Load Max suffix for each region of account to object + if (!accountRegionMaxSuffix[accountKey][vpcConfig.region]) { + const localSuffix = accountStaticResourcesConfig[accountKey] + .filter(sr => sr.region === vpcConfig.region) + .flatMap(r => r.suffix); + accountRegionMaxSuffix[accountKey][vpcConfig.region] = localSuffix.length === 0 ? 1 : Math.max(...localSuffix); + } + + if (!accountRegionExistingResources[accountKey]) { + const localRegionalResources = accountStaticResourcesConfig[accountKey] + .filter(sr => sr.region === vpcConfig.region) + .flatMap(sr => sr.resources); + accountRegionExistingResources[accountKey] = {}; + accountRegionExistingResources[accountKey][vpcConfig.region] = localRegionalResources; + } else if (!accountRegionExistingResources[accountKey][vpcConfig.region]) { + const localRegionalResources = accountStaticResourcesConfig[accountKey] + .filter(sr => sr.region === vpcConfig.region) + .flatMap(sr => sr.resources); + accountRegionExistingResources[accountKey][vpcConfig.region] = localRegionalResources; + } + + const regionStacks = accountStaticResourcesConfig[accountKey].filter(sr => sr.region === vpcConfig.region); + + // Get Account & Region Current Max Suffix and update it when it is changed + suffix = accountRegionMaxSuffix[accountKey][vpcConfig.region]; + stackSuffix = `${STACK_SUFFIX}-${suffix}`; + for (const endpoint of endpointsConfig.endpoints) { + if (!limiter.create(accountKey, Limit.VpcInterfaceEndpointsPerVpc, vpcConfig.name)) { + console.log( + `Skipping endpoint "${endpoint}" creation in VPC "${vpcConfig.name}". Reached maximum interface endpoints per VPC`, + ); + continue; + } + const constructName = `${STACK_SUFFIX}-${vpcConfig.name}-${endpoint}`; + if (accountRegionExistingResources[accountKey][vpcConfig.region].includes(constructName)) { + newResource = false; + const currentStaticResource = regionStacks.find(rs => rs.resources.includes(constructName)); + if (currentStaticResource) { + stackSuffix = `${STACK_SUFFIX}-${currentStaticResource.suffix}`; + } + } else { + const existingResources = accountStaticResourcesConfig[accountKey].find( + sr => sr.region === vpcConfig.region && sr.suffix === suffix, + ); + if (existingResources && existingResources.resources.length >= MAX_RESOURCES_IN_STACK) { + // Updating Account & Region Max Suffix + accountRegionMaxSuffix[accountKey][vpcConfig.region] = ++suffix; + } + stackSuffix = `${STACK_SUFFIX}-${suffix}`; + } + + const accountStack = accountStacks.tryGetOrCreateAccountStack(accountKey, vpcConfig.region, stackSuffix); + if (!accountStack) { + console.error(`Cannot find account stack ${accountKey}: ${vpcConfig.region}, while Associating Resolver Rules`); + continue; + } + + const interfaceEndpoint = new InterfaceEndpoint( + accountStack, + `Endpoint-${vpcConfig.name}-${pascalCase(endpoint)}`, + { + serviceName: endpoint, + vpcId: vpcOutput.vpcId, + vpcRegion: vpcConfig.region, + subnetIds: vpcOutput.subnets.filter(sn => sn.subnetName === endpointsConfig.subnet).map(s => s.subnetId), + }, + ); + + new CfnHostedZoneOutput(accountStack, `HostedZoneOutput-${vpcConfig.name}-${pascalCase(endpoint)}`, { + accountKey, + domain: interfaceEndpoint.hostedZone.name, + hostedZoneId: interfaceEndpoint.hostedZone.ref, + region: vpcConfig.region, + zoneType: 'PRIVATE', + serviceName: endpoint, + vpcName: vpcConfig.name, + }); + + if (newResource) { + const currentSuffixIndex = allStaticResources.findIndex( + sr => sr.region === vpcConfig.region && sr.suffix === suffix && sr.accountKey === accountKey, + ); + const currentAccountSuffixIndex = accountStaticResourcesConfig[accountKey].findIndex( + sr => sr.region === vpcConfig.region && sr.suffix === suffix, + ); + if (currentSuffixIndex === -1) { + const currentResourcesObject: StaticResourcesOutput = { + accountKey, + id: `${STACK_SUFFIX}-${vpcConfig.region}-${accountKey}-${suffix}`, + region: vpcConfig.region, + resourceType: RESOURCE_TYPE, + resources: [constructName], + suffix, + }; + allStaticResources.push(currentResourcesObject); + accountStaticResourcesConfig[accountKey].push(currentResourcesObject); + } else { + const currentResourcesObject = allStaticResources[currentSuffixIndex]; + const currentAccountResourcesObject = accountStaticResourcesConfig[accountKey][currentAccountSuffixIndex]; + if (!currentResourcesObject.resources.includes(constructName)) { + currentResourcesObject.resources.push(constructName); + } + if (!currentAccountResourcesObject.resources.includes(constructName)) { + currentAccountResourcesObject.resources.push(constructName); + } + allStaticResources[currentSuffixIndex] = currentResourcesObject; + accountStaticResourcesConfig[accountKey][currentAccountSuffixIndex] = currentAccountResourcesObject; + } + } + } + } + for (const sr of allStaticResources) { + const accountStack = accountStacks.tryGetOrCreateAccountStack( + sr.accountKey, + sr.region, + `${STACK_SUFFIX}-${sr.suffix}`, + ); + if (!accountStack) { + throw new Error( + `Not able to get or create stack for ${sr.accountKey}: ${sr.region}: ${STACK_SUFFIX}-${sr.suffix}`, + ); + } + new CfnStaticResourcesOutput(accountStack, `StaticResourceOutput-${sr.suffix}`, sr); + } +} From 1deca075bc88b1b523d17f2201dc587a4d05ae01 Mon Sep 17 00:00:00 2001 From: Naveen Kumar Date: Fri, 25 Sep 2020 21:14:49 +0530 Subject: [PATCH 02/14] increasing number of interface endpoints into one stack --- src/deployments/cdk/src/deployments/vpc/step-3.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/deployments/cdk/src/deployments/vpc/step-3.ts b/src/deployments/cdk/src/deployments/vpc/step-3.ts index 673d9c335..63c4d0411 100644 --- a/src/deployments/cdk/src/deployments/vpc/step-3.ts +++ b/src/deployments/cdk/src/deployments/vpc/step-3.ts @@ -6,14 +6,13 @@ import { } from '@aws-accelerator/common-outputs/src/static-resource'; import { AccountStacks } from '../../common/account-stacks'; import { VpcOutputFinder } from '@aws-accelerator/common-outputs/src/vpc'; -import { region } from '@aws-accelerator/common-types'; import { CfnHostedZoneOutput, CfnStaticResourcesOutput } from '../central-endpoints'; import { InterfaceEndpoint } from '../../common/interface-endpoints'; import { pascalCase } from 'pascal-case'; import { Limit, Limiter } from '../../utils/limits'; // Changing this will result to redeploy most of the stack -const MAX_RESOURCES_IN_STACK = 30; +const MAX_RESOURCES_IN_STACK = 45; const RESOURCE_TYPE = 'INTERFACE_ENDPOINTS'; const STACK_SUFFIX = 'VPCEndpoints'; From 0427da0376053ff0ebf0848d79af27225e7afd20 Mon Sep 17 00:00:00 2001 From: Naveen Kumar Date: Tue, 29 Sep 2020 11:53:00 +0530 Subject: [PATCH 03/14] adding limit check regional --- src/core/runtime/src/load-limits-step.ts | 134 ++++++++++-------- .../cdk/src/deployments/vpc/step-3.ts | 2 +- src/lib/common-outputs/src/limits.ts | 1 + src/lib/common/src/aws/service-quotas.ts | 3 +- .../runtime/src/index.ts | 29 +++- 5 files changed, 107 insertions(+), 62 deletions(-) diff --git a/src/core/runtime/src/load-limits-step.ts b/src/core/runtime/src/load-limits-step.ts index 451196b52..af0809c0e 100644 --- a/src/core/runtime/src/load-limits-step.ts +++ b/src/core/runtime/src/load-limits-step.ts @@ -70,10 +70,12 @@ export const handler = async (input: LoadLimitsInput) => { commitId: configCommitId, }); + const defaultRegion: string = config['global-options']['aws-org-master'].region!; + // Capture limit results const limits: LimitOutput[] = []; - const accountConfigs = config.getAccountConfigs(); + const accountConfigs = [config.getAccountConfigs()[0]]; for (const [accountKey, accountConfig] of accountConfigs) { const accountId = getAccountId(accounts, accountKey); @@ -82,9 +84,18 @@ export const handler = async (input: LoadLimitsInput) => { continue; } - const sts = new STS(); - const credentials = await sts.getCredentialsForAccountAndRole(accountId, assumeRoleName); - const quotas = new ServiceQuotas(credentials); + const regions: string[] = Array.from( + new Set( + config + .getVpcConfigs() + .filter(vc => vc.accountKey === accountKey) + .map(accConfig => accConfig.vpcConfig.region), + ), + ); + + if (!regions.includes(defaultRegion)) { + regions.push(defaultRegion); + } // First check that all limits in the config exist const limitConfig = accountConfig.limits; @@ -97,62 +108,71 @@ export const handler = async (input: LoadLimitsInput) => { } } - // The fetch all supported limits and request an increase if necessary - for (const [limitKey, limitCode] of Object.entries(LIMITS)) { - if (!limitKeysFromConfig.includes(limitKey)) { - console.info(`Cannot find limit with key "${limitKey}" in accelerator config`); - continue; - } - if (!limitCode.enabled) { - console.warn(`The limit "${limitKey}" is not enabled`); - continue; - } - - const quota = await quotas.getServiceQuotaOrDefault({ - ServiceCode: limitCode.serviceCode, - QuotaCode: limitCode.quotaCode, - }); - let value = quota.Value!; - const accountLimitConfig = limitConfig[limitKey]; - if (accountLimitConfig && accountLimitConfig['customer-confirm-inplace']) { - value = accountLimitConfig.value; - } - - // Keep track of limits so we can return them at the end of this function - limits.push({ - accountKey, - limitKey, - serviceCode: limitCode.serviceCode, - quotaCode: limitCode.quotaCode, - value, - }); - - if (!accountLimitConfig) { - console.debug(`Quota "${limitKey}" has no desired value for account "${accountKey}"`); - continue; - } - - const desiredValue = accountLimitConfig.value; - - if (value >= desiredValue) { - console.debug(`Quota "${limitKey}" already has a value equal or larger than the desired value`); - continue; + for (const region of regions) { + const sts = new STS(); + const credentials = await sts.getCredentialsForAccountAndRole(accountId, assumeRoleName); + const quotas = new ServiceQuotas(credentials, region); + + // The fetch all supported limits and request an increase if necessary + for (const [limitKey, limitCode] of Object.entries(LIMITS)) { + if (!limitKeysFromConfig.includes(limitKey)) { + console.info(`Cannot find limit with key "${limitKey}" in accelerator config`); + continue; + } + if (!limitCode.enabled) { + console.warn(`The limit "${limitKey}" is not enabled`); + continue; + } + + const quota = await quotas.getServiceQuotaOrDefault({ + ServiceCode: limitCode.serviceCode, + QuotaCode: limitCode.quotaCode, + }); + let value = quota.Value!; + const accountLimitConfig = limitConfig[limitKey]; + if (accountLimitConfig && accountLimitConfig['customer-confirm-inplace']) { + value = accountLimitConfig.value; + } + + // Keep track of limits so we can return them at the end of this function + limits.push({ + accountKey, + limitKey, + serviceCode: limitCode.serviceCode, + quotaCode: limitCode.quotaCode, + value, + region, + }); + + if (!accountLimitConfig) { + console.debug(`Quota "${limitKey}" has no desired value for account "${accountKey}"`); + continue; + } + + const desiredValue = accountLimitConfig.value; + + if (value >= desiredValue) { + console.debug(`Quota "${limitKey}" already has a value equal or larger than the desired value`); + continue; + } + if (!quota.Adjustable) { + console.warn(`Quota "${limitKey}" is not adjustable`); + continue; + } + + if (region === defaultRegion) { + // Request the increase or renew if the previous request was more than two days ago + await quotas.renewServiceQuotaIncrease({ + ServiceCode: limitCode.serviceCode, + QuotaCode: limitCode.quotaCode, + DesiredValue: desiredValue, + MinTimeBetweenRequestsMillis: 1000 * 60 * 60 * 24 * 2, // Two days in milliseconds + }); + } } - if (!quota.Adjustable) { - console.warn(`Quota "${limitKey}" is not adjustable`); - continue; - } - - // Request the increase or renew if the previous request was more than two days ago - await quotas.renewServiceQuotaIncrease({ - ServiceCode: limitCode.serviceCode, - QuotaCode: limitCode.quotaCode, - DesiredValue: desiredValue, - MinTimeBetweenRequestsMillis: 1000 * 60 * 60 * 24 * 2, // Two days in milliseconds - }); } } // Store the limits in the dynamodb await dynamodb.updateItem(getUpdateItemInput(parametersTableName, itemId, JSON.stringify(limits, null, 2))); -}; +}; \ No newline at end of file diff --git a/src/deployments/cdk/src/deployments/vpc/step-3.ts b/src/deployments/cdk/src/deployments/vpc/step-3.ts index 63c4d0411..86c447e15 100644 --- a/src/deployments/cdk/src/deployments/vpc/step-3.ts +++ b/src/deployments/cdk/src/deployments/vpc/step-3.ts @@ -103,7 +103,7 @@ export async function step3(props: VpcStep3Props) { suffix = accountRegionMaxSuffix[accountKey][vpcConfig.region]; stackSuffix = `${STACK_SUFFIX}-${suffix}`; for (const endpoint of endpointsConfig.endpoints) { - if (!limiter.create(accountKey, Limit.VpcInterfaceEndpointsPerVpc, vpcConfig.name)) { + if (!limiter.create(accountKey, Limit.VpcInterfaceEndpointsPerVpc, vpcConfig.region, vpcConfig.name)) { console.log( `Skipping endpoint "${endpoint}" creation in VPC "${vpcConfig.name}". Reached maximum interface endpoints per VPC`, ); diff --git a/src/lib/common-outputs/src/limits.ts b/src/lib/common-outputs/src/limits.ts index d033225f9..a379535da 100644 --- a/src/lib/common-outputs/src/limits.ts +++ b/src/lib/common-outputs/src/limits.ts @@ -13,4 +13,5 @@ export interface LimitOutput { serviceCode: string; quotaCode: string; value: number; + region: string; } diff --git a/src/lib/common/src/aws/service-quotas.ts b/src/lib/common/src/aws/service-quotas.ts index 8b5291da3..cb59e48db 100644 --- a/src/lib/common/src/aws/service-quotas.ts +++ b/src/lib/common/src/aws/service-quotas.ts @@ -16,9 +16,10 @@ export interface RenewServiceQuotaIncrease { export class ServiceQuotas { private readonly client: aws.ServiceQuotas; - public constructor(credentials?: aws.Credentials) { + public constructor(credentials?: aws.Credentials, region?: string) { this.client = new aws.ServiceQuotas({ credentials, + region, }); } diff --git a/src/lib/custom-resources/cdk-associate-hosted-zones/runtime/src/index.ts b/src/lib/custom-resources/cdk-associate-hosted-zones/runtime/src/index.ts index 2ed489ca6..e396daf9a 100644 --- a/src/lib/custom-resources/cdk-associate-hosted-zones/runtime/src/index.ts +++ b/src/lib/custom-resources/cdk-associate-hosted-zones/runtime/src/index.ts @@ -230,6 +230,9 @@ async function onUpdate(event: CloudFormationCustomResourceUpdateEvent) { } catch (e) { if (e.code === 'VPCAssociationNotFound') { console.warn(`The specified VPC "${vpcId}" and hosted zone "${hostedZoneId}" are not currently associated.`); + } else if (e.code === 'NoSuchHostedZone') { + console.warn(`The specified VPC "${vpcId}" and hosted zone "${hostedZoneId}" are not currently associated.`); + continue; } else { console.error(`Error while associating the hosted zone "${hostedZoneId}" to VPC "${vpcName}"`); console.error(e); @@ -239,7 +242,19 @@ async function onUpdate(event: CloudFormationCustomResourceUpdateEvent) { // delete association of VPC with Hosted zones when VPC and Hosted Zones are defined in two different accounts if (vpcAccountId !== hostedZoneAccountId) { - await throttlingBackOff(() => hostedZoneRoute53.deleteVPCAssociationAuthorization(hostedZoneProps).promise()); + try { + await throttlingBackOff(() => hostedZoneRoute53.deleteVPCAssociationAuthorization(hostedZoneProps).promise()); + } catch (e) { + if (e.code === 'VPCAssociationNotFound') { + console.warn(`The specified VPC "${vpcId}" and hosted zone "${hostedZoneId}" are not currently associated.`); + } else if (e.code === 'NoSuchHostedZone') { + console.warn(`The specified VPC "${vpcId}" and hosted zone "${hostedZoneId}" are not currently associated.`); + } else { + console.error(`Error while associating the hosted zone "${hostedZoneId}" to VPC "${vpcName}"`); + console.error(e); + throw new Error(e); + } + } } } @@ -298,11 +313,19 @@ async function onDelete(event: CloudFormationCustomResourceDeleteEvent) { } catch (e) { console.error(`Ignoring error while deleting Association and stack ${hostedZoneId} to VPC "${vpcName}"`); console.error(e); + if (e.code === 'NoSuchHostedZone') { + continue; + } } // delete association of VPC with Hosted zones when VPC and Hosted Zones are defined in two different accounts if (vpcAccountId !== hostedZoneAccountId) { - await throttlingBackOff(() => hostedZoneRoute53.deleteVPCAssociationAuthorization(hostedZoneProps).promise()); + try { + await throttlingBackOff(() => hostedZoneRoute53.deleteVPCAssociationAuthorization(hostedZoneProps).promise()); + } catch (e) { + console.error(`Ignoring error while deleting Association and stack ${hostedZoneId} to VPC "${vpcName}"`); + console.error(e); + } } } -} +} \ No newline at end of file From 870a781bbdd145c486c7147922305dee33391c36 Mon Sep 17 00:00:00 2001 From: Naveen Kumar Date: Tue, 29 Sep 2020 13:15:51 +0530 Subject: [PATCH 04/14] adding limits check before creation --- src/core/runtime/src/load-limits-step.ts | 2 +- src/core/runtime/src/store-stack-output-step.ts | 7 ++----- src/deployments/cdk/src/deployments/vpc/step-3.ts | 2 +- .../cdk-associate-hosted-zones/runtime/src/index.ts | 2 +- 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/core/runtime/src/load-limits-step.ts b/src/core/runtime/src/load-limits-step.ts index af0809c0e..038b020c5 100644 --- a/src/core/runtime/src/load-limits-step.ts +++ b/src/core/runtime/src/load-limits-step.ts @@ -175,4 +175,4 @@ export const handler = async (input: LoadLimitsInput) => { // Store the limits in the dynamodb await dynamodb.updateItem(getUpdateItemInput(parametersTableName, itemId, JSON.stringify(limits, null, 2))); -}; \ No newline at end of file +}; diff --git a/src/core/runtime/src/store-stack-output-step.ts b/src/core/runtime/src/store-stack-output-step.ts index 2a4b3ea1a..ce500133d 100644 --- a/src/core/runtime/src/store-stack-output-step.ts +++ b/src/core/runtime/src/store-stack-output-step.ts @@ -2,9 +2,6 @@ import { STS } from '@aws-accelerator/common/src/aws/sts'; import { DynamoDB } from '@aws-accelerator/common/src/aws/dynamodb'; import { CloudFormation } from '@aws-accelerator/common/src/aws/cloudformation'; import { StackOutput } from '@aws-accelerator/common-outputs/src/stack-output'; -import { Organizations } from '@aws-accelerator/common/src/aws/organizations'; -import { loadAcceleratorConfig } from '@aws-accelerator/common-config/src/load'; -import { LoadConfigurationInput } from './load-configuration-step'; import { Account } from '@aws-accelerator/common-outputs/src/accounts'; import { getUpdateValueInput } from './utils/dynamodb-requests'; @@ -29,7 +26,7 @@ export const handler = async (input: StoreStackOutputInput) => { const credentials = await sts.getCredentialsForAccountAndRole(account.id, assumeRoleName); const cfn = new CloudFormation(credentials, region); const stacks = cfn.listStacksGenerator({ - StackStatusFilter: ['CREATE_COMPLETE', 'UPDATE_COMPLETE'], + StackStatusFilter: ['CREATE_COMPLETE', 'UPDATE_COMPLETE', 'UPDATE_ROLLBACK_COMPLETE'], }); const outputs: StackOutput[] = []; @@ -53,7 +50,7 @@ export const handler = async (input: StoreStackOutputInput) => { stack.Outputs?.forEach(output => outputs.push({ accountKey, - outputKey: `${output.OutputKey}sjkdh`, + outputKey: `${output.OutputKey}`, outputValue: output.OutputValue, outputDescription: output.Description, outputExportName: output.ExportName, diff --git a/src/deployments/cdk/src/deployments/vpc/step-3.ts b/src/deployments/cdk/src/deployments/vpc/step-3.ts index 86c447e15..cfe3a90da 100644 --- a/src/deployments/cdk/src/deployments/vpc/step-3.ts +++ b/src/deployments/cdk/src/deployments/vpc/step-3.ts @@ -105,7 +105,7 @@ export async function step3(props: VpcStep3Props) { for (const endpoint of endpointsConfig.endpoints) { if (!limiter.create(accountKey, Limit.VpcInterfaceEndpointsPerVpc, vpcConfig.region, vpcConfig.name)) { console.log( - `Skipping endpoint "${endpoint}" creation in VPC "${vpcConfig.name}". Reached maximum interface endpoints per VPC`, + `Skipping endpoint "${endpoint}" creation in VPC "${vpcConfig.name}". Reached maximum interface endpoints per VPC`, accountKey, vpcConfig.region ); continue; } diff --git a/src/lib/custom-resources/cdk-associate-hosted-zones/runtime/src/index.ts b/src/lib/custom-resources/cdk-associate-hosted-zones/runtime/src/index.ts index e396daf9a..820d45295 100644 --- a/src/lib/custom-resources/cdk-associate-hosted-zones/runtime/src/index.ts +++ b/src/lib/custom-resources/cdk-associate-hosted-zones/runtime/src/index.ts @@ -328,4 +328,4 @@ async function onDelete(event: CloudFormationCustomResourceDeleteEvent) { } } } -} \ No newline at end of file +} From 43c17f1d6b653414fbb294c4b87a6fe8dff9337e Mon Sep 17 00:00:00 2001 From: Naveen Kumar Date: Tue, 29 Sep 2020 13:16:46 +0530 Subject: [PATCH 05/14] prettier --- src/deployments/cdk/src/deployments/vpc/step-3.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/deployments/cdk/src/deployments/vpc/step-3.ts b/src/deployments/cdk/src/deployments/vpc/step-3.ts index cfe3a90da..b705830fd 100644 --- a/src/deployments/cdk/src/deployments/vpc/step-3.ts +++ b/src/deployments/cdk/src/deployments/vpc/step-3.ts @@ -12,7 +12,7 @@ import { pascalCase } from 'pascal-case'; import { Limit, Limiter } from '../../utils/limits'; // Changing this will result to redeploy most of the stack -const MAX_RESOURCES_IN_STACK = 45; +const MAX_RESOURCES_IN_STACK = 30; const RESOURCE_TYPE = 'INTERFACE_ENDPOINTS'; const STACK_SUFFIX = 'VPCEndpoints'; @@ -105,7 +105,9 @@ export async function step3(props: VpcStep3Props) { for (const endpoint of endpointsConfig.endpoints) { if (!limiter.create(accountKey, Limit.VpcInterfaceEndpointsPerVpc, vpcConfig.region, vpcConfig.name)) { console.log( - `Skipping endpoint "${endpoint}" creation in VPC "${vpcConfig.name}". Reached maximum interface endpoints per VPC`, accountKey, vpcConfig.region + `Skipping endpoint "${endpoint}" creation in VPC "${vpcConfig.name}". Reached maximum interface endpoints per VPC`, + accountKey, + vpcConfig.region, ); continue; } From bbe66d4a0ea0c28fa803a33b3a92dcb2800d7326 Mon Sep 17 00:00:00 2001 From: Naveen Kumar Date: Tue, 29 Sep 2020 16:22:12 +0530 Subject: [PATCH 06/14] Adding random sleep and regional limits --- .../cdk/src/common/interface-endpoints.ts | 9 ++++++++- src/deployments/cdk/src/utils/limits.ts | 16 +++++++++++++--- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/deployments/cdk/src/common/interface-endpoints.ts b/src/deployments/cdk/src/common/interface-endpoints.ts index a0c40707f..8c78c5cdb 100644 --- a/src/deployments/cdk/src/common/interface-endpoints.ts +++ b/src/deployments/cdk/src/common/interface-endpoints.ts @@ -1,6 +1,7 @@ import * as ec2 from '@aws-cdk/aws-ec2'; import * as route53 from '@aws-cdk/aws-route53'; import * as cdk from '@aws-cdk/core'; +import { CfnSleep } from '@aws-accelerator/custom-resource-cfn-sleep'; export interface InterfaceEndpointProps { serviceName: string; @@ -57,6 +58,12 @@ export class InterfaceEndpoint extends cdk.Construct { }); endpoint.addDependsOn(securityGroup); + // Sleep 1 to 10 random seconds after creation of the vpc endpoint to avoid RateExceeded issue with Route53 api accross regions + const sleep = new CfnSleep(this, 'Sleep', { + sleep: Math.floor((Math.random() * (10000 - 1000 + 1) + 3000)), + }); + sleep.node.addDependency(endpoint); + const hostedZoneName = zoneNameForRegionAndEndpointName(vpcRegion, serviceName); this._hostedZone = new route53.CfnHostedZone(this, 'Phz', { name: hostedZoneName, @@ -70,7 +77,7 @@ export class InterfaceEndpoint extends cdk.Construct { comment: `zzEndpoint - ${serviceName}`, }, }); - this._hostedZone.addDependsOn(endpoint); + this._hostedZone.node.addDependency(sleep); const recordSet = new route53.CfnRecordSet(this, 'RecordSet', { type: 'A', diff --git a/src/deployments/cdk/src/utils/limits.ts b/src/deployments/cdk/src/utils/limits.ts index ffc1a26c2..44689ff86 100644 --- a/src/deployments/cdk/src/utils/limits.ts +++ b/src/deployments/cdk/src/utils/limits.ts @@ -48,6 +48,16 @@ export function tryGetQuotaByAccountAndLimit( return limitOutput?.value; } +export function tryGetQuotaByAccountRegionAndLimit( + limits: LimitOutputs, + accountKey: string, + limit: Limit, + region: string, +): number | undefined { + const limitOutput = limits.find(a => a.accountKey === accountKey && a.limitKey === limit && a.region === region); + return limitOutput?.value; +} + export class Limiter { readonly limits: LimitOutputs; readonly counts: { [index: string]: number } = {}; @@ -56,12 +66,12 @@ export class Limiter { this.limits = limits; } - create(accountKey: string, limit: Limit, suffix?: string): boolean { - const quota = tryGetQuotaByAccountAndLimit(this.limits, accountKey, limit); + create(accountKey: string, limit: Limit, region: string, suffix?: string): boolean { + const quota = tryGetQuotaByAccountRegionAndLimit(this.limits, accountKey, limit, region); if (!quota) { return true; } - const index = `${accountKey}/${limit}/${suffix}`; + const index = `${accountKey}/${region}/${limit}/${suffix}`; const count = this.counts[index] ?? 0; if (count < quota) { this.counts[index] = count + 1; From 334ab52a56d67ccfe9acf9890d034961230839ff Mon Sep 17 00:00:00 2001 From: Naveen Kumar Date: Tue, 29 Sep 2020 16:22:48 +0530 Subject: [PATCH 07/14] Sleep 1 to 10 random seconds after creation of the vpc endpoint --- src/deployments/cdk/src/common/interface-endpoints.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/deployments/cdk/src/common/interface-endpoints.ts b/src/deployments/cdk/src/common/interface-endpoints.ts index 8c78c5cdb..bf6fef13f 100644 --- a/src/deployments/cdk/src/common/interface-endpoints.ts +++ b/src/deployments/cdk/src/common/interface-endpoints.ts @@ -60,7 +60,7 @@ export class InterfaceEndpoint extends cdk.Construct { // Sleep 1 to 10 random seconds after creation of the vpc endpoint to avoid RateExceeded issue with Route53 api accross regions const sleep = new CfnSleep(this, 'Sleep', { - sleep: Math.floor((Math.random() * (10000 - 1000 + 1) + 3000)), + sleep: Math.floor(Math.random() * (10000 - 1000 + 1) + 1000), }); sleep.node.addDependency(endpoint); From 0679febac7ae115a1c3f54693a40dcfec4c37419 Mon Sep 17 00:00:00 2001 From: Naveen Kumar Date: Wed, 30 Sep 2020 12:16:23 +0530 Subject: [PATCH 08/14] using custom resource to create private hosted zone --- src/deployments/cdk/package.json | 1 + .../cdk/src/common/interface-endpoints.ts | 62 +++++++----- .../iam/central-endpoints-deployment-roles.ts | 7 ++ .../cdk/src/deployments/vpc/step-3.ts | 13 ++- .../cdk-create-hosted-zone/README.md | 15 +++ .../cdk-create-hosted-zone/cdk/index.ts | 61 ++++++++++++ .../cdk-create-hosted-zone/package.json | 24 +++++ .../runtime/package.json | 31 ++++++ .../runtime/src/index.ts | 95 +++++++++++++++++++ .../runtime/tsconfig.json | 15 +++ .../runtime/webpack.config.ts | 4 + .../cdk-create-hosted-zone/tsconfig.json | 21 ++++ 12 files changed, 322 insertions(+), 27 deletions(-) create mode 100644 src/lib/custom-resources/cdk-create-hosted-zone/README.md create mode 100644 src/lib/custom-resources/cdk-create-hosted-zone/cdk/index.ts create mode 100644 src/lib/custom-resources/cdk-create-hosted-zone/package.json create mode 100644 src/lib/custom-resources/cdk-create-hosted-zone/runtime/package.json create mode 100644 src/lib/custom-resources/cdk-create-hosted-zone/runtime/src/index.ts create mode 100644 src/lib/custom-resources/cdk-create-hosted-zone/runtime/tsconfig.json create mode 100644 src/lib/custom-resources/cdk-create-hosted-zone/runtime/webpack.config.ts create mode 100644 src/lib/custom-resources/cdk-create-hosted-zone/tsconfig.json diff --git a/src/deployments/cdk/package.json b/src/deployments/cdk/package.json index 28ddb38a7..6213d2b9e 100644 --- a/src/deployments/cdk/package.json +++ b/src/deployments/cdk/package.json @@ -84,6 +84,7 @@ "@aws-accelerator/custom-resource-associate-resolver-rules": "workspace:^0.0.1", "@aws-accelerator/custom-resource-create-resolver-rule": "workspace:^0.0.1", "@aws-accelerator/custom-resource-ssm-increase-throughput": "workspace:^0.0.1", + "@aws-accelerator/custom-resource-create-hosted-zone": "workspace:^0.0.1", "@aws-cdk/aws-accessanalyzer": "1.46.0", "@aws-cdk/aws-autoscaling": "1.46.0", "@aws-cdk/aws-budgets": "1.46.0", diff --git a/src/deployments/cdk/src/common/interface-endpoints.ts b/src/deployments/cdk/src/common/interface-endpoints.ts index bf6fef13f..0360f160c 100644 --- a/src/deployments/cdk/src/common/interface-endpoints.ts +++ b/src/deployments/cdk/src/common/interface-endpoints.ts @@ -1,13 +1,15 @@ import * as ec2 from '@aws-cdk/aws-ec2'; import * as route53 from '@aws-cdk/aws-route53'; import * as cdk from '@aws-cdk/core'; -import { CfnSleep } from '@aws-accelerator/custom-resource-cfn-sleep'; +import { CreateHostedZone } from '@aws-accelerator/custom-resource-create-hosted-zone'; +import { domain } from 'process'; export interface InterfaceEndpointProps { serviceName: string; vpcId: string; vpcRegion: string; subnetIds: string[]; + roleArn: string; } /** @@ -15,11 +17,12 @@ export interface InterfaceEndpointProps { * SecurityGroup, VPCEndpoint, HostedZone and RecordSet. */ export class InterfaceEndpoint extends cdk.Construct { - private _hostedZone: route53.CfnHostedZone; + private _hostedZone: CreateHostedZone; + private _hostedZoneName: string; constructor(scope: cdk.Construct, id: string, props: InterfaceEndpointProps) { super(scope, id); - const { serviceName, vpcId, vpcRegion, subnetIds } = props; + const { serviceName, vpcId, vpcRegion, subnetIds, roleArn } = props; // Create a new security groupo per endpoint const securityGroup = new ec2.CfnSecurityGroup(this, `ep_${serviceName}`, { @@ -58,38 +61,45 @@ export class InterfaceEndpoint extends cdk.Construct { }); endpoint.addDependsOn(securityGroup); - // Sleep 1 to 10 random seconds after creation of the vpc endpoint to avoid RateExceeded issue with Route53 api accross regions - const sleep = new CfnSleep(this, 'Sleep', { - sleep: Math.floor(Math.random() * (10000 - 1000 + 1) + 1000), - }); - sleep.node.addDependency(endpoint); + this._hostedZoneName = zoneNameForRegionAndEndpointName(vpcRegion, serviceName); + // this._hostedZone = new route53.CfnHostedZone(this, 'Phz', { + // name: hostedZoneName, + // vpcs: [ + // { + // vpcId, + // vpcRegion, + // }, + // ], + // hostedZoneConfig: { + // comment: `zzEndpoint - ${serviceName}`, + // }, + // }); + - const hostedZoneName = zoneNameForRegionAndEndpointName(vpcRegion, serviceName); - this._hostedZone = new route53.CfnHostedZone(this, 'Phz', { - name: hostedZoneName, - vpcs: [ - { - vpcId, - vpcRegion, - }, - ], - hostedZoneConfig: { - comment: `zzEndpoint - ${serviceName}`, - }, + this._hostedZone = new CreateHostedZone(this, 'Phz', { + domain: this._hostedZoneName, + comment: `zzEndpoint - ${serviceName}`, + region: vpcRegion, + roleArn, + vpcId, }); - this._hostedZone.node.addDependency(sleep); + + this._hostedZone.node.addDependency(endpoint); const recordSet = new route53.CfnRecordSet(this, 'RecordSet', { type: 'A', - name: hostedZoneName, - hostedZoneId: this._hostedZone.ref, + name: this._hostedZoneName, + hostedZoneId: this._hostedZone.zoneId, aliasTarget: aliasTargetForServiceNameAndEndpoint(serviceName, endpoint), }); - recordSet.addDependsOn(this._hostedZone); + recordSet.node.addDependency(this._hostedZone); } - get hostedZone(): route53.CfnHostedZone { - return this._hostedZone; + get hostedZone(): {name: string; id: string;} { + return { + name: this._hostedZone.zoneId, + id: this._hostedZoneName, + }; } } diff --git a/src/deployments/cdk/src/deployments/iam/central-endpoints-deployment-roles.ts b/src/deployments/cdk/src/deployments/iam/central-endpoints-deployment-roles.ts index 56057358c..5c9708b49 100644 --- a/src/deployments/cdk/src/deployments/iam/central-endpoints-deployment-roles.ts +++ b/src/deployments/cdk/src/deployments/iam/central-endpoints-deployment-roles.ts @@ -52,6 +52,13 @@ export async function centralEndpointDeploymentRole(stack: AccountStack) { }), ); + role.addToPrincipalPolicy( + new iam.PolicyStatement({ + actions: ['route53:List*', 'route53:DeleteHostedZone', 'route53:CreateHostedZone'], + resources: ['*'], + }), + ); + role.addToPrincipalPolicy( new iam.PolicyStatement({ actions: ['logs:CreateLogGroup', 'logs:CreateLogStream', 'logs:PutLogEvents'], diff --git a/src/deployments/cdk/src/deployments/vpc/step-3.ts b/src/deployments/cdk/src/deployments/vpc/step-3.ts index b705830fd..98db017d6 100644 --- a/src/deployments/cdk/src/deployments/vpc/step-3.ts +++ b/src/deployments/cdk/src/deployments/vpc/step-3.ts @@ -10,6 +10,7 @@ import { CfnHostedZoneOutput, CfnStaticResourcesOutput } from '../central-endpoi import { InterfaceEndpoint } from '../../common/interface-endpoints'; import { pascalCase } from 'pascal-case'; import { Limit, Limiter } from '../../utils/limits'; +import { IamRoleOutputFinder } from '@aws-accelerator/common-outputs/src/iam-role'; // Changing this will result to redeploy most of the stack const MAX_RESOURCES_IN_STACK = 30; @@ -102,6 +103,15 @@ export async function step3(props: VpcStep3Props) { // Get Account & Region Current Max Suffix and update it when it is changed suffix = accountRegionMaxSuffix[accountKey][vpcConfig.region]; stackSuffix = `${STACK_SUFFIX}-${suffix}`; + + const roleOutput = IamRoleOutputFinder.tryFindOneByName({ + outputs, + accountKey, + roleKey: 'CentralEndpointDeployment', + }); + if (!roleOutput) { + continue; + } for (const endpoint of endpointsConfig.endpoints) { if (!limiter.create(accountKey, Limit.VpcInterfaceEndpointsPerVpc, vpcConfig.region, vpcConfig.name)) { console.log( @@ -143,13 +153,14 @@ export async function step3(props: VpcStep3Props) { vpcId: vpcOutput.vpcId, vpcRegion: vpcConfig.region, subnetIds: vpcOutput.subnets.filter(sn => sn.subnetName === endpointsConfig.subnet).map(s => s.subnetId), + roleArn: roleOutput.roleArn, }, ); new CfnHostedZoneOutput(accountStack, `HostedZoneOutput-${vpcConfig.name}-${pascalCase(endpoint)}`, { accountKey, domain: interfaceEndpoint.hostedZone.name, - hostedZoneId: interfaceEndpoint.hostedZone.ref, + hostedZoneId: interfaceEndpoint.hostedZone.id, region: vpcConfig.region, zoneType: 'PRIVATE', serviceName: endpoint, diff --git a/src/lib/custom-resources/cdk-create-hosted-zone/README.md b/src/lib/custom-resources/cdk-create-hosted-zone/README.md new file mode 100644 index 000000000..2b05379ea --- /dev/null +++ b/src/lib/custom-resources/cdk-create-hosted-zone/README.md @@ -0,0 +1,15 @@ +# Create Hosted Zone + +This is a custom resource to Create Private Hosted Zone Used `createHostedZone`, `listHostedZonesByVPC`, and `deleteHostedZone` API calls. + +## Usage + + import { CreateHostedZone } from '@aws-accelerator/custom-resource-create-hosted-zone'; + + this._hostedZone = new CreateHostedZone(this, 'Phz', { + domain: this._hostedZoneName, + comment: `zzEndpoint - ${serviceName}`, + region: vpcRegion, + roleArn, + vpcId, + }); diff --git a/src/lib/custom-resources/cdk-create-hosted-zone/cdk/index.ts b/src/lib/custom-resources/cdk-create-hosted-zone/cdk/index.ts new file mode 100644 index 000000000..590cac14c --- /dev/null +++ b/src/lib/custom-resources/cdk-create-hosted-zone/cdk/index.ts @@ -0,0 +1,61 @@ +import * as path from 'path'; +import * as cdk from '@aws-cdk/core'; +import * as iam from '@aws-cdk/aws-iam'; +import * as lambda from '@aws-cdk/aws-lambda'; + +const resourceType = 'Custom::CreateHostedZone'; + +export interface CreateHostedZoneProps { + vpcId: string; + domain: string; + region: string; + comment: string; + roleArn: string; +} + +export interface CreateHostedZoneRuntimeProps extends Omit {} +/** + * Custom resource that will create Resolver Rule. + */ +export class CreateHostedZone extends cdk.Construct { + private readonly resource: cdk.CustomResource; + private role: iam.IRole; + + constructor(scope: cdk.Construct, id: string, props: CreateHostedZoneProps) { + super(scope, id); + this.role = iam.Role.fromRoleArn(this, `${resourceType}Role`, props.roleArn); + + const runtimeProps: CreateHostedZoneRuntimeProps = props; + this.resource = new cdk.CustomResource(this, 'Resource', { + resourceType, + serviceToken: this.lambdaFunction.functionArn, + properties: { + ...runtimeProps, + }, + }); + } + + get zoneId(): string { + return this.resource.getAttString('ZoneId'); + } + + private get lambdaFunction(): lambda.Function { + const constructName = `${resourceType}Lambda`; + const stack = cdk.Stack.of(this); + const existing = stack.node.tryFindChild(constructName); + if (existing) { + return existing as lambda.Function; + } + + const lambdaPath = require.resolve('@aws-accelerator/custom-resource-create-hosted-zone-runtime'); + const lambdaDir = path.dirname(lambdaPath); + + return new lambda.Function(stack, constructName, { + runtime: lambda.Runtime.NODEJS_12_X, + code: lambda.Code.fromAsset(lambdaDir), + handler: 'index.handler', + role: this.role, + timeout: cdk.Duration.minutes(15), + }); + } +} diff --git a/src/lib/custom-resources/cdk-create-hosted-zone/package.json b/src/lib/custom-resources/cdk-create-hosted-zone/package.json new file mode 100644 index 000000000..517aa6f01 --- /dev/null +++ b/src/lib/custom-resources/cdk-create-hosted-zone/package.json @@ -0,0 +1,24 @@ +{ + "name": "@aws-accelerator/custom-resource-create-hosted-zone", + "peerDependencies": { + "@aws-cdk/aws-iam": "^1.46.0", + "@aws-cdk/core": "^1.46.0" + }, + "main": "cdk/index.ts", + "private": true, + "version": "0.0.1", + "dependencies": { + "@aws-cdk/aws-iam": "1.46.0", + "@aws-cdk/core": "1.46.0", + "@aws-cdk/aws-lambda": "1.46.0" + }, + "devDependencies": { + "tslint": "6.1.0", + "tslint-config-standard": "9.0.0", + "@types/aws-lambda": "8.10.46", + "tslint-config-prettier": "1.18.0", + "@types/cfn-response": "1.0.3", + "@types/node": "12.12.6", + "@aws-accelerator/custom-resource-create-hosted-zone-runtime": "workspace:^0.0.1" + } +} \ No newline at end of file diff --git a/src/lib/custom-resources/cdk-create-hosted-zone/runtime/package.json b/src/lib/custom-resources/cdk-create-hosted-zone/runtime/package.json new file mode 100644 index 000000000..9fa7a67f2 --- /dev/null +++ b/src/lib/custom-resources/cdk-create-hosted-zone/runtime/package.json @@ -0,0 +1,31 @@ +{ + "name": "@aws-accelerator/custom-resource-create-hosted-zone-runtime", + "externals": [ + "aws-lambda", + "aws-sdk" + ], + "private": true, + "source": "src/index.ts", + "version": "0.0.1", + "dependencies": { + "@aws-accelerator/custom-resource-runtime-cfn-response": "workspace:^0.0.1", + "@aws-accelerator/custom-resource-cfn-utils": "workspace:^0.0.1", + "exponential-backoff": "3.0.0", + "aws-sdk": "2.763.0", + "aws-lambda": "1.0.5" + }, + "scripts": { + "prepare": "webpack-cli --config webpack.config.ts" + }, + "devDependencies": { + "ts-loader": "7.0.5", + "typescript": "3.8.3", + "@types/aws-lambda": "8.10.46", + "webpack": "4.42.1", + "@aws-accelerator/custom-resource-runtime-webpack-base": "workspace:^0.0.1", + "@types/node": "12.12.6", + "webpack-cli": "3.3.11" + }, + "main": "dist/index.js", + "types": "dist/index.d.ts" +} \ No newline at end of file diff --git a/src/lib/custom-resources/cdk-create-hosted-zone/runtime/src/index.ts b/src/lib/custom-resources/cdk-create-hosted-zone/runtime/src/index.ts new file mode 100644 index 000000000..676fd8554 --- /dev/null +++ b/src/lib/custom-resources/cdk-create-hosted-zone/runtime/src/index.ts @@ -0,0 +1,95 @@ +import * as AWS from 'aws-sdk'; +AWS.config.logger = console; +import { CloudFormationCustomResourceEvent, CloudFormationCustomResourceDeleteEvent } from 'aws-lambda'; +import { errorHandler } from '@aws-accelerator/custom-resource-runtime-cfn-response'; +import { delay, throttlingBackOff } from '@aws-accelerator/custom-resource-cfn-utils'; + +export interface HandlerProperties { + vpcId: string; + domain: string; + region: string; + comment: string; +} + +const route53 = new AWS.Route53(); + +export const handler = errorHandler(onEvent); + +async function onEvent(event: CloudFormationCustomResourceEvent) { + console.log(`Create Hosted Zone..`); + console.log(JSON.stringify(event, null, 2)); + + // tslint:disable-next-line: switch-default + switch (event.RequestType) { + case 'Create': + return onCreateOrUpdate(event); + case 'Update': + return onCreateOrUpdate(event); + case 'Delete': + return onDelete(event); + } +} + +async function onCreateOrUpdate(event: CloudFormationCustomResourceEvent) { + const properties = (event.ResourceProperties as unknown) as HandlerProperties; + const { comment, vpcId, domain, region } = properties; + let hostedZoneId: string; + // Sleep 1 to 10 random seconds after creation of the vpc endpoint to avoid RateExceeded issue with Route53 api accross regions + await delay(Math.floor(Math.random() * (10000 - 1000 + 1) + 1000)) + try { + const hostedZone = await throttlingBackOff(() => route53.createHostedZone({ + CallerReference: `${vpcId}-${domain}-${new Date().toTimeString()}`, + Name: domain, + HostedZoneConfig: { + Comment: comment, + PrivateZone: true, + }, + VPC: { + VPCId: vpcId, + VPCRegion: region + } + }).promise()); + hostedZoneId = hostedZone.HostedZone.Id; + } catch (e) { + console.log(e); + if (e.code === 'ConflictingDomainExists') { + const hostedZone = await throttlingBackOff(() => route53.listHostedZonesByVPC({ + VPCId: vpcId, + VPCRegion: region, + }).promise()); + hostedZoneId = hostedZone.HostedZoneSummaries[0].HostedZoneId; + } else { + throw new Error(e); + } + } + return { + physicalResourceId: `${vpcId}-${domain}`, + data: { + ZoneId: hostedZoneId, + }, + }; +} + +async function onDelete(event: CloudFormationCustomResourceDeleteEvent) { + console.log(`Deleting Hosted Zone...`); + console.log(JSON.stringify(event, null, 2)); + const properties = (event.ResourceProperties as unknown) as HandlerProperties; + const { vpcId, domain, region } = properties; + if (event.PhysicalResourceId != `${vpcId}-${domain}`) { + return; + } + try { + const hostedZones = await throttlingBackOff(() => route53.listHostedZonesByVPC({ + VPCId: vpcId, + VPCRegion: region, + }).promise()); + const hostedZoneId = hostedZones.HostedZoneSummaries.find(hz => hz.Name === domain)?.HostedZoneId; + // Sleep 1 to 10 random seconds after creation of the vpc endpoint to avoid RateExceeded issue with Route53 api accross regions + await delay(Math.floor(Math.random() * (10000 - 1000 + 1) + 1000)) + await throttlingBackOff(() => route53.deleteHostedZone({ + Id: hostedZoneId!, + }).promise()); + } catch(e) { + console.error(e); + } +} \ No newline at end of file diff --git a/src/lib/custom-resources/cdk-create-hosted-zone/runtime/tsconfig.json b/src/lib/custom-resources/cdk-create-hosted-zone/runtime/tsconfig.json new file mode 100644 index 000000000..118a8376a --- /dev/null +++ b/src/lib/custom-resources/cdk-create-hosted-zone/runtime/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "target": "es2019", + "lib": ["es2019"], + "module": "commonjs", + "moduleResolution": "node", + "strict": true, + "declaration": true, + "esModuleInterop": true, + "noImplicitAny": true, + "resolveJsonModule": true + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "**/*.spec.ts"] +} diff --git a/src/lib/custom-resources/cdk-create-hosted-zone/runtime/webpack.config.ts b/src/lib/custom-resources/cdk-create-hosted-zone/runtime/webpack.config.ts new file mode 100644 index 000000000..425acd8ba --- /dev/null +++ b/src/lib/custom-resources/cdk-create-hosted-zone/runtime/webpack.config.ts @@ -0,0 +1,4 @@ +import { webpackConfigurationForPackage } from '@aws-accelerator/custom-resource-runtime-webpack-base'; +import pkg from './package.json'; + +export default webpackConfigurationForPackage(pkg); diff --git a/src/lib/custom-resources/cdk-create-hosted-zone/tsconfig.json b/src/lib/custom-resources/cdk-create-hosted-zone/tsconfig.json new file mode 100644 index 000000000..4db940b9b --- /dev/null +++ b/src/lib/custom-resources/cdk-create-hosted-zone/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "target": "es2019", + "lib": [ + "es2019" + ], + "noImplicitAny": true, + "module": "commonjs", + "strict": true, + "esModuleInterop": true, + "moduleResolution": "node", + "outDir": "dist" + }, + "exclude": [ + "node_modules", + "**/*.spec.ts" + ], + "include": [ + "cdk/**/*" + ] +} \ No newline at end of file From fdbfec4ba205caac544c7a669cccffe2d761fc48 Mon Sep 17 00:00:00 2001 From: Naveen Kumar Date: Wed, 30 Sep 2020 12:16:31 +0530 Subject: [PATCH 09/14] prettier --- .../cdk/src/common/interface-endpoints.ts | 3 +- .../runtime/src/index.ts | 70 ++++++++++++------- 2 files changed, 44 insertions(+), 29 deletions(-) diff --git a/src/deployments/cdk/src/common/interface-endpoints.ts b/src/deployments/cdk/src/common/interface-endpoints.ts index 0360f160c..c33738a26 100644 --- a/src/deployments/cdk/src/common/interface-endpoints.ts +++ b/src/deployments/cdk/src/common/interface-endpoints.ts @@ -74,7 +74,6 @@ export class InterfaceEndpoint extends cdk.Construct { // comment: `zzEndpoint - ${serviceName}`, // }, // }); - this._hostedZone = new CreateHostedZone(this, 'Phz', { domain: this._hostedZoneName, @@ -95,7 +94,7 @@ export class InterfaceEndpoint extends cdk.Construct { recordSet.node.addDependency(this._hostedZone); } - get hostedZone(): {name: string; id: string;} { + get hostedZone(): { name: string; id: string } { return { name: this._hostedZone.zoneId, id: this._hostedZoneName, diff --git a/src/lib/custom-resources/cdk-create-hosted-zone/runtime/src/index.ts b/src/lib/custom-resources/cdk-create-hosted-zone/runtime/src/index.ts index 676fd8554..a54eba94f 100644 --- a/src/lib/custom-resources/cdk-create-hosted-zone/runtime/src/index.ts +++ b/src/lib/custom-resources/cdk-create-hosted-zone/runtime/src/index.ts @@ -35,28 +35,36 @@ async function onCreateOrUpdate(event: CloudFormationCustomResourceEvent) { const { comment, vpcId, domain, region } = properties; let hostedZoneId: string; // Sleep 1 to 10 random seconds after creation of the vpc endpoint to avoid RateExceeded issue with Route53 api accross regions - await delay(Math.floor(Math.random() * (10000 - 1000 + 1) + 1000)) + await delay(Math.floor(Math.random() * (10000 - 1000 + 1) + 1000)); try { - const hostedZone = await throttlingBackOff(() => route53.createHostedZone({ - CallerReference: `${vpcId}-${domain}-${new Date().toTimeString()}`, - Name: domain, - HostedZoneConfig: { - Comment: comment, - PrivateZone: true, - }, - VPC: { - VPCId: vpcId, - VPCRegion: region - } - }).promise()); + const hostedZone = await throttlingBackOff(() => + route53 + .createHostedZone({ + CallerReference: `${vpcId}-${domain}-${new Date().toTimeString()}`, + Name: domain, + HostedZoneConfig: { + Comment: comment, + PrivateZone: true, + }, + VPC: { + VPCId: vpcId, + VPCRegion: region, + }, + }) + .promise(), + ); hostedZoneId = hostedZone.HostedZone.Id; } catch (e) { console.log(e); if (e.code === 'ConflictingDomainExists') { - const hostedZone = await throttlingBackOff(() => route53.listHostedZonesByVPC({ - VPCId: vpcId, - VPCRegion: region, - }).promise()); + const hostedZone = await throttlingBackOff(() => + route53 + .listHostedZonesByVPC({ + VPCId: vpcId, + VPCRegion: region, + }) + .promise(), + ); hostedZoneId = hostedZone.HostedZoneSummaries[0].HostedZoneId; } else { throw new Error(e); @@ -79,17 +87,25 @@ async function onDelete(event: CloudFormationCustomResourceDeleteEvent) { return; } try { - const hostedZones = await throttlingBackOff(() => route53.listHostedZonesByVPC({ - VPCId: vpcId, - VPCRegion: region, - }).promise()); + const hostedZones = await throttlingBackOff(() => + route53 + .listHostedZonesByVPC({ + VPCId: vpcId, + VPCRegion: region, + }) + .promise(), + ); const hostedZoneId = hostedZones.HostedZoneSummaries.find(hz => hz.Name === domain)?.HostedZoneId; // Sleep 1 to 10 random seconds after creation of the vpc endpoint to avoid RateExceeded issue with Route53 api accross regions - await delay(Math.floor(Math.random() * (10000 - 1000 + 1) + 1000)) - await throttlingBackOff(() => route53.deleteHostedZone({ - Id: hostedZoneId!, - }).promise()); - } catch(e) { + await delay(Math.floor(Math.random() * (10000 - 1000 + 1) + 1000)); + await throttlingBackOff(() => + route53 + .deleteHostedZone({ + Id: hostedZoneId!, + }) + .promise(), + ); + } catch (e) { console.error(e); } -} \ No newline at end of file +} From 7251f413449a5bab1e2e6ee9ede69e0339a23706 Mon Sep 17 00:00:00 2001 From: Naveen Kumar Date: Wed, 30 Sep 2020 15:20:39 +0530 Subject: [PATCH 10/14] remove using custom resource for Private Hosted Zone --- src/core/runtime/src/create-stack/verify.ts | 1 + src/deployments/cdk/package.json | 1 - .../cdk/src/common/interface-endpoints.ts | 55 +++++++------------ .../cdk/src/deployments/vpc/step-3.ts | 11 +--- 4 files changed, 23 insertions(+), 45 deletions(-) diff --git a/src/core/runtime/src/create-stack/verify.ts b/src/core/runtime/src/create-stack/verify.ts index 0c7356f19..8e93717ed 100644 --- a/src/core/runtime/src/create-stack/verify.ts +++ b/src/core/runtime/src/create-stack/verify.ts @@ -27,6 +27,7 @@ export const handler = async (input: Partial) => { return { status: 'SUCCESS', statusReason: stack.StackStatusReason || '', + outputs: stack.Outputs, }; } else if (FAILED_STATUSES.includes(status)) { return { diff --git a/src/deployments/cdk/package.json b/src/deployments/cdk/package.json index 6213d2b9e..28ddb38a7 100644 --- a/src/deployments/cdk/package.json +++ b/src/deployments/cdk/package.json @@ -84,7 +84,6 @@ "@aws-accelerator/custom-resource-associate-resolver-rules": "workspace:^0.0.1", "@aws-accelerator/custom-resource-create-resolver-rule": "workspace:^0.0.1", "@aws-accelerator/custom-resource-ssm-increase-throughput": "workspace:^0.0.1", - "@aws-accelerator/custom-resource-create-hosted-zone": "workspace:^0.0.1", "@aws-cdk/aws-accessanalyzer": "1.46.0", "@aws-cdk/aws-autoscaling": "1.46.0", "@aws-cdk/aws-budgets": "1.46.0", diff --git a/src/deployments/cdk/src/common/interface-endpoints.ts b/src/deployments/cdk/src/common/interface-endpoints.ts index c33738a26..40912db47 100644 --- a/src/deployments/cdk/src/common/interface-endpoints.ts +++ b/src/deployments/cdk/src/common/interface-endpoints.ts @@ -1,15 +1,12 @@ import * as ec2 from '@aws-cdk/aws-ec2'; import * as route53 from '@aws-cdk/aws-route53'; import * as cdk from '@aws-cdk/core'; -import { CreateHostedZone } from '@aws-accelerator/custom-resource-create-hosted-zone'; -import { domain } from 'process'; export interface InterfaceEndpointProps { serviceName: string; vpcId: string; vpcRegion: string; subnetIds: string[]; - roleArn: string; } /** @@ -17,12 +14,11 @@ export interface InterfaceEndpointProps { * SecurityGroup, VPCEndpoint, HostedZone and RecordSet. */ export class InterfaceEndpoint extends cdk.Construct { - private _hostedZone: CreateHostedZone; - private _hostedZoneName: string; + private _hostedZone: route53.CfnHostedZone; constructor(scope: cdk.Construct, id: string, props: InterfaceEndpointProps) { super(scope, id); - const { serviceName, vpcId, vpcRegion, subnetIds, roleArn } = props; + const { serviceName, vpcId, vpcRegion, subnetIds } = props; // Create a new security groupo per endpoint const securityGroup = new ec2.CfnSecurityGroup(this, `ep_${serviceName}`, { @@ -61,44 +57,35 @@ export class InterfaceEndpoint extends cdk.Construct { }); endpoint.addDependsOn(securityGroup); - this._hostedZoneName = zoneNameForRegionAndEndpointName(vpcRegion, serviceName); - // this._hostedZone = new route53.CfnHostedZone(this, 'Phz', { - // name: hostedZoneName, - // vpcs: [ - // { - // vpcId, - // vpcRegion, - // }, - // ], - // hostedZoneConfig: { - // comment: `zzEndpoint - ${serviceName}`, - // }, - // }); - - this._hostedZone = new CreateHostedZone(this, 'Phz', { - domain: this._hostedZoneName, - comment: `zzEndpoint - ${serviceName}`, - region: vpcRegion, - roleArn, - vpcId, + const hostedZoneName = zoneNameForRegionAndEndpointName(vpcRegion, serviceName); + this._hostedZone = new route53.CfnHostedZone(this, 'Phz', { + name: hostedZoneName, + vpcs: [ + { + vpcId, + vpcRegion, + }, + ], + hostedZoneConfig: { + comment: `zzEndpoint - ${serviceName}`, + }, }); - this._hostedZone.node.addDependency(endpoint); + + + this._hostedZone.addDependsOn(endpoint); const recordSet = new route53.CfnRecordSet(this, 'RecordSet', { type: 'A', - name: this._hostedZoneName, - hostedZoneId: this._hostedZone.zoneId, + name: hostedZoneName, + hostedZoneId: this._hostedZone.ref, aliasTarget: aliasTargetForServiceNameAndEndpoint(serviceName, endpoint), }); recordSet.node.addDependency(this._hostedZone); } - get hostedZone(): { name: string; id: string } { - return { - name: this._hostedZone.zoneId, - id: this._hostedZoneName, - }; + get hostedZone(): route53.CfnHostedZone { + return this._hostedZone; } } diff --git a/src/deployments/cdk/src/deployments/vpc/step-3.ts b/src/deployments/cdk/src/deployments/vpc/step-3.ts index 98db017d6..021f4a760 100644 --- a/src/deployments/cdk/src/deployments/vpc/step-3.ts +++ b/src/deployments/cdk/src/deployments/vpc/step-3.ts @@ -104,14 +104,6 @@ export async function step3(props: VpcStep3Props) { suffix = accountRegionMaxSuffix[accountKey][vpcConfig.region]; stackSuffix = `${STACK_SUFFIX}-${suffix}`; - const roleOutput = IamRoleOutputFinder.tryFindOneByName({ - outputs, - accountKey, - roleKey: 'CentralEndpointDeployment', - }); - if (!roleOutput) { - continue; - } for (const endpoint of endpointsConfig.endpoints) { if (!limiter.create(accountKey, Limit.VpcInterfaceEndpointsPerVpc, vpcConfig.region, vpcConfig.name)) { console.log( @@ -153,14 +145,13 @@ export async function step3(props: VpcStep3Props) { vpcId: vpcOutput.vpcId, vpcRegion: vpcConfig.region, subnetIds: vpcOutput.subnets.filter(sn => sn.subnetName === endpointsConfig.subnet).map(s => s.subnetId), - roleArn: roleOutput.roleArn, }, ); new CfnHostedZoneOutput(accountStack, `HostedZoneOutput-${vpcConfig.name}-${pascalCase(endpoint)}`, { accountKey, domain: interfaceEndpoint.hostedZone.name, - hostedZoneId: interfaceEndpoint.hostedZone.id, + hostedZoneId: interfaceEndpoint.hostedZone.ref, region: vpcConfig.region, zoneType: 'PRIVATE', serviceName: endpoint, From 86098bc9389ea2d7f86163149f3e5935d85f26f6 Mon Sep 17 00:00:00 2001 From: Naveen Kumar Date: Wed, 30 Sep 2020 15:55:18 +0530 Subject: [PATCH 11/14] limits fix --- src/core/runtime/src/create-stack/verify.ts | 1 - src/core/runtime/src/load-limits-step.ts | 2 +- src/deployments/cdk/src/common/interface-endpoints.ts | 4 +--- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/core/runtime/src/create-stack/verify.ts b/src/core/runtime/src/create-stack/verify.ts index 8e93717ed..0c7356f19 100644 --- a/src/core/runtime/src/create-stack/verify.ts +++ b/src/core/runtime/src/create-stack/verify.ts @@ -27,7 +27,6 @@ export const handler = async (input: Partial) => { return { status: 'SUCCESS', statusReason: stack.StackStatusReason || '', - outputs: stack.Outputs, }; } else if (FAILED_STATUSES.includes(status)) { return { diff --git a/src/core/runtime/src/load-limits-step.ts b/src/core/runtime/src/load-limits-step.ts index 038b020c5..370db027c 100644 --- a/src/core/runtime/src/load-limits-step.ts +++ b/src/core/runtime/src/load-limits-step.ts @@ -75,7 +75,7 @@ export const handler = async (input: LoadLimitsInput) => { // Capture limit results const limits: LimitOutput[] = []; - const accountConfigs = [config.getAccountConfigs()[0]]; + const accountConfigs = config.getAccountConfigs(); for (const [accountKey, accountConfig] of accountConfigs) { const accountId = getAccountId(accounts, accountKey); diff --git a/src/deployments/cdk/src/common/interface-endpoints.ts b/src/deployments/cdk/src/common/interface-endpoints.ts index 40912db47..87d071444 100644 --- a/src/deployments/cdk/src/common/interface-endpoints.ts +++ b/src/deployments/cdk/src/common/interface-endpoints.ts @@ -71,8 +71,6 @@ export class InterfaceEndpoint extends cdk.Construct { }, }); - - this._hostedZone.addDependsOn(endpoint); const recordSet = new route53.CfnRecordSet(this, 'RecordSet', { @@ -81,7 +79,7 @@ export class InterfaceEndpoint extends cdk.Construct { hostedZoneId: this._hostedZone.ref, aliasTarget: aliasTargetForServiceNameAndEndpoint(serviceName, endpoint), }); - recordSet.node.addDependency(this._hostedZone); + recordSet.addDependsOn(this._hostedZone); } get hostedZone(): route53.CfnHostedZone { From 35f22fb260753ffd5e84c96a41dbaf7bd005a038 Mon Sep 17 00:00:00 2001 From: Naveen Kumar Date: Wed, 30 Sep 2020 16:32:34 +0530 Subject: [PATCH 12/14] Fixing tests --- src/core/runtime/src/load-limits-step.ts | 2 +- .../unsupported-changed.spec.ts.snap | 128 +++++++++--------- 2 files changed, 65 insertions(+), 65 deletions(-) diff --git a/src/core/runtime/src/load-limits-step.ts b/src/core/runtime/src/load-limits-step.ts index 370db027c..128e8e795 100644 --- a/src/core/runtime/src/load-limits-step.ts +++ b/src/core/runtime/src/load-limits-step.ts @@ -70,7 +70,7 @@ export const handler = async (input: LoadLimitsInput) => { commitId: configCommitId, }); - const defaultRegion: string = config['global-options']['aws-org-master'].region!; + const defaultRegion: string = config['global-options']['aws-org-master'].region; // Capture limit results const limits: LimitOutput[] = []; diff --git a/src/deployments/cdk/test/apps/__snapshots__/unsupported-changed.spec.ts.snap b/src/deployments/cdk/test/apps/__snapshots__/unsupported-changed.spec.ts.snap index 52d3a6e60..91840545d 100644 --- a/src/deployments/cdk/test/apps/__snapshots__/unsupported-changed.spec.ts.snap +++ b/src/deployments/cdk/test/apps/__snapshots__/unsupported-changed.spec.ts.snap @@ -454,12 +454,12 @@ Array [ ] `; -exports[`there should not be any unsupported resource changes for AWS::Budgets::Budget: PerimeterPhase1Endpoint02EC98C35 1`] = `Array []`; - exports[`there should not be any unsupported resource changes for AWS::Budgets::Budget: PerimeterPhase1VpcStackPerimeter0F2B12AF 1`] = `Array []`; exports[`there should not be any unsupported resource changes for AWS::Budgets::Budget: PerimeterPhase2 1`] = `Array []`; +exports[`there should not be any unsupported resource changes for AWS::Budgets::Budget: PerimeterPhase2VpcEndpoints1 1`] = `Array []`; + exports[`there should not be any unsupported resource changes for AWS::Budgets::Budget: PerimeterPhase3 1`] = `Array []`; exports[`there should not be any unsupported resource changes for AWS::Budgets::Budget: SecurityPhase0 1`] = `Array []`; @@ -606,12 +606,6 @@ Array [ ] `; -exports[`there should not be any unsupported resource changes for AWS::Budgets::Budget: SharedNetworkPhase1Endpoint0CD50B8FF 1`] = `Array []`; - -exports[`there should not be any unsupported resource changes for AWS::Budgets::Budget: SharedNetworkPhase1Endpoint20AE19710 1`] = `Array []`; - -exports[`there should not be any unsupported resource changes for AWS::Budgets::Budget: SharedNetworkPhase1Endpoint125DF8CB0 1`] = `Array []`; - exports[`there should not be any unsupported resource changes for AWS::Budgets::Budget: SharedNetworkPhase1UsEast1 1`] = `Array []`; exports[`there should not be any unsupported resource changes for AWS::Budgets::Budget: SharedNetworkPhase1VpcStackCentralB4A762DD 1`] = `Array []`; @@ -628,6 +622,12 @@ exports[`there should not be any unsupported resource changes for AWS::Budgets:: exports[`there should not be any unsupported resource changes for AWS::Budgets::Budget: SharedNetworkPhase2 1`] = `Array []`; +exports[`there should not be any unsupported resource changes for AWS::Budgets::Budget: SharedNetworkPhase2VpcEndpoints1 1`] = `Array []`; + +exports[`there should not be any unsupported resource changes for AWS::Budgets::Budget: SharedNetworkPhase2VpcEndpoints2 1`] = `Array []`; + +exports[`there should not be any unsupported resource changes for AWS::Budgets::Budget: SharedNetworkPhase2VpcEndpoints3 1`] = `Array []`; + exports[`there should not be any unsupported resource changes for AWS::Budgets::Budget: SharedNetworkPhase3 1`] = `Array []`; exports[`there should not be any unsupported resource changes for AWS::Budgets::Budget: SharedServicesPhase0 1`] = `Array []`; @@ -731,12 +731,12 @@ exports[`there should not be any unsupported resource changes for AWS::Directory exports[`there should not be any unsupported resource changes for AWS::DirectoryService::MicrosoftAD: PerimeterPhase1 1`] = `Array []`; -exports[`there should not be any unsupported resource changes for AWS::DirectoryService::MicrosoftAD: PerimeterPhase1Endpoint02EC98C35 1`] = `Array []`; - exports[`there should not be any unsupported resource changes for AWS::DirectoryService::MicrosoftAD: PerimeterPhase1VpcStackPerimeter0F2B12AF 1`] = `Array []`; exports[`there should not be any unsupported resource changes for AWS::DirectoryService::MicrosoftAD: PerimeterPhase2 1`] = `Array []`; +exports[`there should not be any unsupported resource changes for AWS::DirectoryService::MicrosoftAD: PerimeterPhase2VpcEndpoints1 1`] = `Array []`; + exports[`there should not be any unsupported resource changes for AWS::DirectoryService::MicrosoftAD: PerimeterPhase3 1`] = `Array []`; exports[`there should not be any unsupported resource changes for AWS::DirectoryService::MicrosoftAD: SecurityPhase0 1`] = `Array []`; @@ -751,12 +751,6 @@ exports[`there should not be any unsupported resource changes for AWS::Directory exports[`there should not be any unsupported resource changes for AWS::DirectoryService::MicrosoftAD: SharedNetworkPhase1 1`] = `Array []`; -exports[`there should not be any unsupported resource changes for AWS::DirectoryService::MicrosoftAD: SharedNetworkPhase1Endpoint0CD50B8FF 1`] = `Array []`; - -exports[`there should not be any unsupported resource changes for AWS::DirectoryService::MicrosoftAD: SharedNetworkPhase1Endpoint20AE19710 1`] = `Array []`; - -exports[`there should not be any unsupported resource changes for AWS::DirectoryService::MicrosoftAD: SharedNetworkPhase1Endpoint125DF8CB0 1`] = `Array []`; - exports[`there should not be any unsupported resource changes for AWS::DirectoryService::MicrosoftAD: SharedNetworkPhase1UsEast1 1`] = `Array []`; exports[`there should not be any unsupported resource changes for AWS::DirectoryService::MicrosoftAD: SharedNetworkPhase1VpcStackCentralB4A762DD 1`] = `Array []`; @@ -773,6 +767,12 @@ exports[`there should not be any unsupported resource changes for AWS::Directory exports[`there should not be any unsupported resource changes for AWS::DirectoryService::MicrosoftAD: SharedNetworkPhase2 1`] = `Array []`; +exports[`there should not be any unsupported resource changes for AWS::DirectoryService::MicrosoftAD: SharedNetworkPhase2VpcEndpoints1 1`] = `Array []`; + +exports[`there should not be any unsupported resource changes for AWS::DirectoryService::MicrosoftAD: SharedNetworkPhase2VpcEndpoints2 1`] = `Array []`; + +exports[`there should not be any unsupported resource changes for AWS::DirectoryService::MicrosoftAD: SharedNetworkPhase2VpcEndpoints3 1`] = `Array []`; + exports[`there should not be any unsupported resource changes for AWS::DirectoryService::MicrosoftAD: SharedNetworkPhase3 1`] = `Array []`; exports[`there should not be any unsupported resource changes for AWS::DirectoryService::MicrosoftAD: SharedServicesPhase0 1`] = `Array []`; @@ -870,8 +870,6 @@ exports[`there should not be any unsupported resource changes for AWS::EC2::Inst exports[`there should not be any unsupported resource changes for AWS::EC2::Instance: PerimeterPhase1 1`] = `Array []`; -exports[`there should not be any unsupported resource changes for AWS::EC2::Instance: PerimeterPhase1Endpoint02EC98C35 1`] = `Array []`; - exports[`there should not be any unsupported resource changes for AWS::EC2::Instance: PerimeterPhase1VpcStackPerimeter0F2B12AF 1`] = `Array []`; exports[`there should not be any unsupported resource changes for AWS::EC2::Instance: PerimeterPhase2 1`] = ` @@ -1002,6 +1000,8 @@ Array [ ] `; +exports[`there should not be any unsupported resource changes for AWS::EC2::Instance: PerimeterPhase2VpcEndpoints1 1`] = `Array []`; + exports[`there should not be any unsupported resource changes for AWS::EC2::Instance: PerimeterPhase3 1`] = `Array []`; exports[`there should not be any unsupported resource changes for AWS::EC2::Instance: SecurityPhase0 1`] = `Array []`; @@ -1016,12 +1016,6 @@ exports[`there should not be any unsupported resource changes for AWS::EC2::Inst exports[`there should not be any unsupported resource changes for AWS::EC2::Instance: SharedNetworkPhase1 1`] = `Array []`; -exports[`there should not be any unsupported resource changes for AWS::EC2::Instance: SharedNetworkPhase1Endpoint0CD50B8FF 1`] = `Array []`; - -exports[`there should not be any unsupported resource changes for AWS::EC2::Instance: SharedNetworkPhase1Endpoint20AE19710 1`] = `Array []`; - -exports[`there should not be any unsupported resource changes for AWS::EC2::Instance: SharedNetworkPhase1Endpoint125DF8CB0 1`] = `Array []`; - exports[`there should not be any unsupported resource changes for AWS::EC2::Instance: SharedNetworkPhase1UsEast1 1`] = `Array []`; exports[`there should not be any unsupported resource changes for AWS::EC2::Instance: SharedNetworkPhase1VpcStackCentralB4A762DD 1`] = `Array []`; @@ -1038,6 +1032,12 @@ exports[`there should not be any unsupported resource changes for AWS::EC2::Inst exports[`there should not be any unsupported resource changes for AWS::EC2::Instance: SharedNetworkPhase2 1`] = `Array []`; +exports[`there should not be any unsupported resource changes for AWS::EC2::Instance: SharedNetworkPhase2VpcEndpoints1 1`] = `Array []`; + +exports[`there should not be any unsupported resource changes for AWS::EC2::Instance: SharedNetworkPhase2VpcEndpoints2 1`] = `Array []`; + +exports[`there should not be any unsupported resource changes for AWS::EC2::Instance: SharedNetworkPhase2VpcEndpoints3 1`] = `Array []`; + exports[`there should not be any unsupported resource changes for AWS::EC2::Instance: SharedNetworkPhase3 1`] = `Array []`; exports[`there should not be any unsupported resource changes for AWS::EC2::Instance: SharedServicesPhase0 1`] = `Array []`; @@ -1106,12 +1106,12 @@ exports[`there should not be any unsupported resource changes for AWS::EC2::Tran exports[`there should not be any unsupported resource changes for AWS::EC2::TransitGateway: PerimeterPhase1 1`] = `Array []`; -exports[`there should not be any unsupported resource changes for AWS::EC2::TransitGateway: PerimeterPhase1Endpoint02EC98C35 1`] = `Array []`; - exports[`there should not be any unsupported resource changes for AWS::EC2::TransitGateway: PerimeterPhase1VpcStackPerimeter0F2B12AF 1`] = `Array []`; exports[`there should not be any unsupported resource changes for AWS::EC2::TransitGateway: PerimeterPhase2 1`] = `Array []`; +exports[`there should not be any unsupported resource changes for AWS::EC2::TransitGateway: PerimeterPhase2VpcEndpoints1 1`] = `Array []`; + exports[`there should not be any unsupported resource changes for AWS::EC2::TransitGateway: PerimeterPhase3 1`] = `Array []`; exports[`there should not be any unsupported resource changes for AWS::EC2::TransitGateway: SecurityPhase0 1`] = `Array []`; @@ -1151,12 +1151,6 @@ Array [ exports[`there should not be any unsupported resource changes for AWS::EC2::TransitGateway: SharedNetworkPhase1 1`] = `Array []`; -exports[`there should not be any unsupported resource changes for AWS::EC2::TransitGateway: SharedNetworkPhase1Endpoint0CD50B8FF 1`] = `Array []`; - -exports[`there should not be any unsupported resource changes for AWS::EC2::TransitGateway: SharedNetworkPhase1Endpoint20AE19710 1`] = `Array []`; - -exports[`there should not be any unsupported resource changes for AWS::EC2::TransitGateway: SharedNetworkPhase1Endpoint125DF8CB0 1`] = `Array []`; - exports[`there should not be any unsupported resource changes for AWS::EC2::TransitGateway: SharedNetworkPhase1UsEast1 1`] = `Array []`; exports[`there should not be any unsupported resource changes for AWS::EC2::TransitGateway: SharedNetworkPhase1VpcStackCentralB4A762DD 1`] = `Array []`; @@ -1173,6 +1167,12 @@ exports[`there should not be any unsupported resource changes for AWS::EC2::Tran exports[`there should not be any unsupported resource changes for AWS::EC2::TransitGateway: SharedNetworkPhase2 1`] = `Array []`; +exports[`there should not be any unsupported resource changes for AWS::EC2::TransitGateway: SharedNetworkPhase2VpcEndpoints1 1`] = `Array []`; + +exports[`there should not be any unsupported resource changes for AWS::EC2::TransitGateway: SharedNetworkPhase2VpcEndpoints2 1`] = `Array []`; + +exports[`there should not be any unsupported resource changes for AWS::EC2::TransitGateway: SharedNetworkPhase2VpcEndpoints3 1`] = `Array []`; + exports[`there should not be any unsupported resource changes for AWS::EC2::TransitGateway: SharedNetworkPhase3 1`] = `Array []`; exports[`there should not be any unsupported resource changes for AWS::EC2::TransitGateway: SharedServicesPhase0 1`] = `Array []`; @@ -1241,12 +1241,12 @@ exports[`there should not be any unsupported resource changes for AWS::ElasticLo exports[`there should not be any unsupported resource changes for AWS::ElasticLoadBalancingV2::LoadBalancer: PerimeterPhase1 1`] = `Array []`; -exports[`there should not be any unsupported resource changes for AWS::ElasticLoadBalancingV2::LoadBalancer: PerimeterPhase1Endpoint02EC98C35 1`] = `Array []`; - exports[`there should not be any unsupported resource changes for AWS::ElasticLoadBalancingV2::LoadBalancer: PerimeterPhase1VpcStackPerimeter0F2B12AF 1`] = `Array []`; exports[`there should not be any unsupported resource changes for AWS::ElasticLoadBalancingV2::LoadBalancer: PerimeterPhase2 1`] = `Array []`; +exports[`there should not be any unsupported resource changes for AWS::ElasticLoadBalancingV2::LoadBalancer: PerimeterPhase2VpcEndpoints1 1`] = `Array []`; + exports[`there should not be any unsupported resource changes for AWS::ElasticLoadBalancingV2::LoadBalancer: PerimeterPhase3 1`] = ` Array [ Object { @@ -1282,12 +1282,6 @@ exports[`there should not be any unsupported resource changes for AWS::ElasticLo exports[`there should not be any unsupported resource changes for AWS::ElasticLoadBalancingV2::LoadBalancer: SharedNetworkPhase1 1`] = `Array []`; -exports[`there should not be any unsupported resource changes for AWS::ElasticLoadBalancingV2::LoadBalancer: SharedNetworkPhase1Endpoint0CD50B8FF 1`] = `Array []`; - -exports[`there should not be any unsupported resource changes for AWS::ElasticLoadBalancingV2::LoadBalancer: SharedNetworkPhase1Endpoint20AE19710 1`] = `Array []`; - -exports[`there should not be any unsupported resource changes for AWS::ElasticLoadBalancingV2::LoadBalancer: SharedNetworkPhase1Endpoint125DF8CB0 1`] = `Array []`; - exports[`there should not be any unsupported resource changes for AWS::ElasticLoadBalancingV2::LoadBalancer: SharedNetworkPhase1UsEast1 1`] = `Array []`; exports[`there should not be any unsupported resource changes for AWS::ElasticLoadBalancingV2::LoadBalancer: SharedNetworkPhase1VpcStackCentralB4A762DD 1`] = `Array []`; @@ -1304,6 +1298,12 @@ exports[`there should not be any unsupported resource changes for AWS::ElasticLo exports[`there should not be any unsupported resource changes for AWS::ElasticLoadBalancingV2::LoadBalancer: SharedNetworkPhase2 1`] = `Array []`; +exports[`there should not be any unsupported resource changes for AWS::ElasticLoadBalancingV2::LoadBalancer: SharedNetworkPhase2VpcEndpoints1 1`] = `Array []`; + +exports[`there should not be any unsupported resource changes for AWS::ElasticLoadBalancingV2::LoadBalancer: SharedNetworkPhase2VpcEndpoints2 1`] = `Array []`; + +exports[`there should not be any unsupported resource changes for AWS::ElasticLoadBalancingV2::LoadBalancer: SharedNetworkPhase2VpcEndpoints3 1`] = `Array []`; + exports[`there should not be any unsupported resource changes for AWS::ElasticLoadBalancingV2::LoadBalancer: SharedNetworkPhase3 1`] = `Array []`; exports[`there should not be any unsupported resource changes for AWS::ElasticLoadBalancingV2::LoadBalancer: SharedServicesPhase0 1`] = `Array []`; @@ -1449,12 +1449,12 @@ Array [ ] `; -exports[`there should not be any unsupported resource changes for AWS::S3::Bucket: PerimeterPhase1Endpoint02EC98C35 1`] = `Array []`; - exports[`there should not be any unsupported resource changes for AWS::S3::Bucket: PerimeterPhase1VpcStackPerimeter0F2B12AF 1`] = `Array []`; exports[`there should not be any unsupported resource changes for AWS::S3::Bucket: PerimeterPhase2 1`] = `Array []`; +exports[`there should not be any unsupported resource changes for AWS::S3::Bucket: PerimeterPhase2VpcEndpoints1 1`] = `Array []`; + exports[`there should not be any unsupported resource changes for AWS::S3::Bucket: PerimeterPhase3 1`] = `Array []`; exports[`there should not be any unsupported resource changes for AWS::S3::Bucket: SecurityPhase0 1`] = `Array []`; @@ -1489,12 +1489,6 @@ Array [ ] `; -exports[`there should not be any unsupported resource changes for AWS::S3::Bucket: SharedNetworkPhase1Endpoint0CD50B8FF 1`] = `Array []`; - -exports[`there should not be any unsupported resource changes for AWS::S3::Bucket: SharedNetworkPhase1Endpoint20AE19710 1`] = `Array []`; - -exports[`there should not be any unsupported resource changes for AWS::S3::Bucket: SharedNetworkPhase1Endpoint125DF8CB0 1`] = `Array []`; - exports[`there should not be any unsupported resource changes for AWS::S3::Bucket: SharedNetworkPhase1UsEast1 1`] = `Array []`; exports[`there should not be any unsupported resource changes for AWS::S3::Bucket: SharedNetworkPhase1VpcStackCentralB4A762DD 1`] = `Array []`; @@ -1511,6 +1505,12 @@ exports[`there should not be any unsupported resource changes for AWS::S3::Bucke exports[`there should not be any unsupported resource changes for AWS::S3::Bucket: SharedNetworkPhase2 1`] = `Array []`; +exports[`there should not be any unsupported resource changes for AWS::S3::Bucket: SharedNetworkPhase2VpcEndpoints1 1`] = `Array []`; + +exports[`there should not be any unsupported resource changes for AWS::S3::Bucket: SharedNetworkPhase2VpcEndpoints2 1`] = `Array []`; + +exports[`there should not be any unsupported resource changes for AWS::S3::Bucket: SharedNetworkPhase2VpcEndpoints3 1`] = `Array []`; + exports[`there should not be any unsupported resource changes for AWS::S3::Bucket: SharedNetworkPhase3 1`] = `Array []`; exports[`there should not be any unsupported resource changes for AWS::S3::Bucket: SharedServicesPhase0 1`] = `Array []`; @@ -1646,12 +1646,12 @@ exports[`there should not be any unsupported resource changes for AWS::SecretsMa exports[`there should not be any unsupported resource changes for AWS::SecretsManager::ResourcePolicy: PerimeterPhase1 1`] = `Array []`; -exports[`there should not be any unsupported resource changes for AWS::SecretsManager::ResourcePolicy: PerimeterPhase1Endpoint02EC98C35 1`] = `Array []`; - exports[`there should not be any unsupported resource changes for AWS::SecretsManager::ResourcePolicy: PerimeterPhase1VpcStackPerimeter0F2B12AF 1`] = `Array []`; exports[`there should not be any unsupported resource changes for AWS::SecretsManager::ResourcePolicy: PerimeterPhase2 1`] = `Array []`; +exports[`there should not be any unsupported resource changes for AWS::SecretsManager::ResourcePolicy: PerimeterPhase2VpcEndpoints1 1`] = `Array []`; + exports[`there should not be any unsupported resource changes for AWS::SecretsManager::ResourcePolicy: PerimeterPhase3 1`] = `Array []`; exports[`there should not be any unsupported resource changes for AWS::SecretsManager::ResourcePolicy: SecurityPhase0 1`] = `Array []`; @@ -1666,12 +1666,6 @@ exports[`there should not be any unsupported resource changes for AWS::SecretsMa exports[`there should not be any unsupported resource changes for AWS::SecretsManager::ResourcePolicy: SharedNetworkPhase1 1`] = `Array []`; -exports[`there should not be any unsupported resource changes for AWS::SecretsManager::ResourcePolicy: SharedNetworkPhase1Endpoint0CD50B8FF 1`] = `Array []`; - -exports[`there should not be any unsupported resource changes for AWS::SecretsManager::ResourcePolicy: SharedNetworkPhase1Endpoint20AE19710 1`] = `Array []`; - -exports[`there should not be any unsupported resource changes for AWS::SecretsManager::ResourcePolicy: SharedNetworkPhase1Endpoint125DF8CB0 1`] = `Array []`; - exports[`there should not be any unsupported resource changes for AWS::SecretsManager::ResourcePolicy: SharedNetworkPhase1UsEast1 1`] = `Array []`; exports[`there should not be any unsupported resource changes for AWS::SecretsManager::ResourcePolicy: SharedNetworkPhase1VpcStackCentralB4A762DD 1`] = `Array []`; @@ -1688,6 +1682,12 @@ exports[`there should not be any unsupported resource changes for AWS::SecretsMa exports[`there should not be any unsupported resource changes for AWS::SecretsManager::ResourcePolicy: SharedNetworkPhase2 1`] = `Array []`; +exports[`there should not be any unsupported resource changes for AWS::SecretsManager::ResourcePolicy: SharedNetworkPhase2VpcEndpoints1 1`] = `Array []`; + +exports[`there should not be any unsupported resource changes for AWS::SecretsManager::ResourcePolicy: SharedNetworkPhase2VpcEndpoints2 1`] = `Array []`; + +exports[`there should not be any unsupported resource changes for AWS::SecretsManager::ResourcePolicy: SharedNetworkPhase2VpcEndpoints3 1`] = `Array []`; + exports[`there should not be any unsupported resource changes for AWS::SecretsManager::ResourcePolicy: SharedNetworkPhase3 1`] = `Array []`; exports[`there should not be any unsupported resource changes for AWS::SecretsManager::ResourcePolicy: SharedServicesPhase0 1`] = `Array []`; @@ -1825,12 +1825,12 @@ Array [ ] `; -exports[`there should not be any unsupported resource changes for AWS::SecretsManager::Secret: PerimeterPhase1Endpoint02EC98C35 1`] = `Array []`; - exports[`there should not be any unsupported resource changes for AWS::SecretsManager::Secret: PerimeterPhase1VpcStackPerimeter0F2B12AF 1`] = `Array []`; exports[`there should not be any unsupported resource changes for AWS::SecretsManager::Secret: PerimeterPhase2 1`] = `Array []`; +exports[`there should not be any unsupported resource changes for AWS::SecretsManager::Secret: PerimeterPhase2VpcEndpoints1 1`] = `Array []`; + exports[`there should not be any unsupported resource changes for AWS::SecretsManager::Secret: PerimeterPhase3 1`] = `Array []`; exports[`there should not be any unsupported resource changes for AWS::SecretsManager::Secret: SecurityPhase0 1`] = `Array []`; @@ -1845,12 +1845,6 @@ exports[`there should not be any unsupported resource changes for AWS::SecretsMa exports[`there should not be any unsupported resource changes for AWS::SecretsManager::Secret: SharedNetworkPhase1 1`] = `Array []`; -exports[`there should not be any unsupported resource changes for AWS::SecretsManager::Secret: SharedNetworkPhase1Endpoint0CD50B8FF 1`] = `Array []`; - -exports[`there should not be any unsupported resource changes for AWS::SecretsManager::Secret: SharedNetworkPhase1Endpoint20AE19710 1`] = `Array []`; - -exports[`there should not be any unsupported resource changes for AWS::SecretsManager::Secret: SharedNetworkPhase1Endpoint125DF8CB0 1`] = `Array []`; - exports[`there should not be any unsupported resource changes for AWS::SecretsManager::Secret: SharedNetworkPhase1UsEast1 1`] = `Array []`; exports[`there should not be any unsupported resource changes for AWS::SecretsManager::Secret: SharedNetworkPhase1VpcStackCentralB4A762DD 1`] = `Array []`; @@ -1867,6 +1861,12 @@ exports[`there should not be any unsupported resource changes for AWS::SecretsMa exports[`there should not be any unsupported resource changes for AWS::SecretsManager::Secret: SharedNetworkPhase2 1`] = `Array []`; +exports[`there should not be any unsupported resource changes for AWS::SecretsManager::Secret: SharedNetworkPhase2VpcEndpoints1 1`] = `Array []`; + +exports[`there should not be any unsupported resource changes for AWS::SecretsManager::Secret: SharedNetworkPhase2VpcEndpoints2 1`] = `Array []`; + +exports[`there should not be any unsupported resource changes for AWS::SecretsManager::Secret: SharedNetworkPhase2VpcEndpoints3 1`] = `Array []`; + exports[`there should not be any unsupported resource changes for AWS::SecretsManager::Secret: SharedNetworkPhase3 1`] = `Array []`; exports[`there should not be any unsupported resource changes for AWS::SecretsManager::Secret: SharedServicesPhase0 1`] = `Array []`; From 4f9fff673eea7fde86ea8db5a3106fc4ca470f9b Mon Sep 17 00:00:00 2001 From: Naveen Kumar Date: Tue, 6 Oct 2020 18:36:27 +0530 Subject: [PATCH 13/14] Fixing review --- src/core/runtime/src/load-limits-step.ts | 2 +- .../cdk-associate-hosted-zones/runtime/src/index.ts | 5 +++-- .../cdk-create-hosted-zone/runtime/src/index.ts | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/core/runtime/src/load-limits-step.ts b/src/core/runtime/src/load-limits-step.ts index 128e8e795..a499a8e0c 100644 --- a/src/core/runtime/src/load-limits-step.ts +++ b/src/core/runtime/src/load-limits-step.ts @@ -76,6 +76,7 @@ export const handler = async (input: LoadLimitsInput) => { const limits: LimitOutput[] = []; const accountConfigs = config.getAccountConfigs(); + const sts = new STS(); for (const [accountKey, accountConfig] of accountConfigs) { const accountId = getAccountId(accounts, accountKey); @@ -109,7 +110,6 @@ export const handler = async (input: LoadLimitsInput) => { } for (const region of regions) { - const sts = new STS(); const credentials = await sts.getCredentialsForAccountAndRole(accountId, assumeRoleName); const quotas = new ServiceQuotas(credentials, region); diff --git a/src/lib/custom-resources/cdk-associate-hosted-zones/runtime/src/index.ts b/src/lib/custom-resources/cdk-associate-hosted-zones/runtime/src/index.ts index 820d45295..34218e5ac 100644 --- a/src/lib/custom-resources/cdk-associate-hosted-zones/runtime/src/index.ts +++ b/src/lib/custom-resources/cdk-associate-hosted-zones/runtime/src/index.ts @@ -231,7 +231,7 @@ async function onUpdate(event: CloudFormationCustomResourceUpdateEvent) { if (e.code === 'VPCAssociationNotFound') { console.warn(`The specified VPC "${vpcId}" and hosted zone "${hostedZoneId}" are not currently associated.`); } else if (e.code === 'NoSuchHostedZone') { - console.warn(`The specified VPC "${vpcId}" and hosted zone "${hostedZoneId}" are not currently associated.`); + console.warn(`The specified hosted zone "${hostedZoneId}" doesn't exist.`); continue; } else { console.error(`Error while associating the hosted zone "${hostedZoneId}" to VPC "${vpcName}"`); @@ -248,7 +248,7 @@ async function onUpdate(event: CloudFormationCustomResourceUpdateEvent) { if (e.code === 'VPCAssociationNotFound') { console.warn(`The specified VPC "${vpcId}" and hosted zone "${hostedZoneId}" are not currently associated.`); } else if (e.code === 'NoSuchHostedZone') { - console.warn(`The specified VPC "${vpcId}" and hosted zone "${hostedZoneId}" are not currently associated.`); + console.warn(`The specified hosted zone "${hostedZoneId}" doesn't exist.`); } else { console.error(`Error while associating the hosted zone "${hostedZoneId}" to VPC "${vpcName}"`); console.error(e); @@ -314,6 +314,7 @@ async function onDelete(event: CloudFormationCustomResourceDeleteEvent) { console.error(`Ignoring error while deleting Association and stack ${hostedZoneId} to VPC "${vpcName}"`); console.error(e); if (e.code === 'NoSuchHostedZone') { + console.warn(`The specified hosted zone "${hostedZoneId}" doesn't exist.`); continue; } } diff --git a/src/lib/custom-resources/cdk-create-hosted-zone/runtime/src/index.ts b/src/lib/custom-resources/cdk-create-hosted-zone/runtime/src/index.ts index a54eba94f..02fa2ae3c 100644 --- a/src/lib/custom-resources/cdk-create-hosted-zone/runtime/src/index.ts +++ b/src/lib/custom-resources/cdk-create-hosted-zone/runtime/src/index.ts @@ -40,7 +40,7 @@ async function onCreateOrUpdate(event: CloudFormationCustomResourceEvent) { const hostedZone = await throttlingBackOff(() => route53 .createHostedZone({ - CallerReference: `${vpcId}-${domain}-${new Date().toTimeString()}`, + CallerReference: `${vpcId}-${domain}-${new Date().getTime()}`, Name: domain, HostedZoneConfig: { Comment: comment, @@ -96,7 +96,7 @@ async function onDelete(event: CloudFormationCustomResourceDeleteEvent) { .promise(), ); const hostedZoneId = hostedZones.HostedZoneSummaries.find(hz => hz.Name === domain)?.HostedZoneId; - // Sleep 1 to 10 random seconds after creation of the vpc endpoint to avoid RateExceeded issue with Route53 api accross regions + // Sleep 1 to 10 random seconds after creation of the vpc endpoint to avoid RateExceeded issue with Route53 api across regions await delay(Math.floor(Math.random() * (10000 - 1000 + 1) + 1000)); await throttlingBackOff(() => route53 From 88731cb559c58586d8ec46830cb7bb31378b7709 Mon Sep 17 00:00:00 2001 From: Naveen Kumar Date: Wed, 7 Oct 2020 20:31:24 +0530 Subject: [PATCH 14/14] Fixing stacks validation --- src/deployments/cdk/src/deployments/vpc/step-3.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/deployments/cdk/src/deployments/vpc/step-3.ts b/src/deployments/cdk/src/deployments/vpc/step-3.ts index 021f4a760..3928bbf92 100644 --- a/src/deployments/cdk/src/deployments/vpc/step-3.ts +++ b/src/deployments/cdk/src/deployments/vpc/step-3.ts @@ -67,7 +67,6 @@ export async function step3(props: VpcStep3Props) { let suffix: number; let stackSuffix: string; - let newResource = true; // Load all account stacks to object if (!accountStaticResourcesConfig[accountKey]) { @@ -105,6 +104,7 @@ export async function step3(props: VpcStep3Props) { stackSuffix = `${STACK_SUFFIX}-${suffix}`; for (const endpoint of endpointsConfig.endpoints) { + let newResource = true; if (!limiter.create(accountKey, Limit.VpcInterfaceEndpointsPerVpc, vpcConfig.region, vpcConfig.name)) { console.log( `Skipping endpoint "${endpoint}" creation in VPC "${vpcConfig.name}". Reached maximum interface endpoints per VPC`,