UNPKG

aws-cdk-lib

Version:

Version 2 of the AWS Cloud Development Kit library

2 lines (1 loc) 19.2 kB
"use strict";var __createBinding=exports&&exports.__createBinding||(Object.create?(function(o,m,k,k2){k2===void 0&&(k2=k);var desc=Object.getOwnPropertyDescriptor(m,k);(!desc||("get"in desc?!m.__esModule:desc.writable||desc.configurable))&&(desc={enumerable:!0,get:function(){return m[k]}}),Object.defineProperty(o,k2,desc)}):(function(o,m,k,k2){k2===void 0&&(k2=k),o[k2]=m[k]})),__setModuleDefault=exports&&exports.__setModuleDefault||(Object.create?(function(o,v){Object.defineProperty(o,"default",{enumerable:!0,value:v})}):function(o,v){o.default=v}),__importStar=exports&&exports.__importStar||(function(){var ownKeys=function(o){return ownKeys=Object.getOwnPropertyNames||function(o2){var ar=[];for(var k in o2)Object.prototype.hasOwnProperty.call(o2,k)&&(ar[ar.length]=k);return ar},ownKeys(o)};return function(mod){if(mod&&mod.__esModule)return mod;var result={};if(mod!=null)for(var k=ownKeys(mod),i=0;i<k.length;i++)k[i]!=="default"&&__createBinding(result,mod,k[i]);return __setModuleDefault(result,mod),result}})();Object.defineProperty(exports,"__esModule",{value:!0}),exports.CustomCoupledReference=exports.STRING_LIST_REFERENCE_DELIMITER=void 0,exports.resolveReferences=resolveReferences,exports.getExportable=getExportable,exports.referenceNestedStackValueInParent=referenceNestedStackValueInParent;var constructs_1=()=>{var tmp=require("constructs");return constructs_1=()=>tmp,tmp},cfn_reference_1=()=>{var tmp=require("./cfn-reference");return cfn_reference_1=()=>tmp,tmp},intrinsic_1=()=>{var tmp=require("./intrinsic");return intrinsic_1=()=>tmp,tmp},resolve_1=()=>{var tmp=require("./resolve");return resolve_1=()=>tmp,tmp},uniqueid_1=()=>{var tmp=require("./uniqueid");return uniqueid_1=()=>tmp,tmp},cxapi=()=>{var tmp=__importStar(require("../../../cx-api"));return cxapi=()=>tmp,tmp},annotations_1=()=>{var tmp=require("../annotations");return annotations_1=()=>tmp,tmp},arn_1=()=>{var tmp=require("../arn");return arn_1=()=>tmp,tmp},cfn_element_1=()=>{var tmp=require("../cfn-element");return cfn_element_1=()=>tmp,tmp},cfn_fn_1=()=>{var tmp=require("../cfn-fn");return cfn_fn_1=()=>tmp,tmp},cfn_output_1=()=>{var tmp=require("../cfn-output");return cfn_output_1=()=>tmp,tmp},cfn_parameter_1=()=>{var tmp=require("../cfn-parameter");return cfn_parameter_1=()=>tmp,tmp},export_writer_provider_1=()=>{var tmp=require("../custom-resource-provider/cross-region-export-providers/export-writer-provider");return export_writer_provider_1=()=>tmp,tmp},errors_1=()=>{var tmp=require("../errors");return errors_1=()=>tmp,tmp},lazy_1=()=>{var tmp=require("../lazy");return lazy_1=()=>tmp,tmp},names_1=()=>{var tmp=require("../names");return names_1=()=>tmp,tmp},stack_1=()=>{var tmp=require("../stack");return stack_1=()=>tmp,tmp},token_1=()=>{var tmp=require("../token");return token_1=()=>tmp,tmp},type_hints_1=()=>{var tmp=require("../type-hints");return type_hints_1=()=>tmp,tmp},construct_iteration_1=()=>{var tmp=require("./construct-iteration");return construct_iteration_1=()=>tmp,tmp},cfn_resource_1=()=>{var tmp=require("../cfn-resource");return cfn_resource_1=()=>tmp,tmp},literal_string_1=()=>{var tmp=require("./literal-string");return literal_string_1=()=>tmp,tmp},cross_stack_reference_strength_1=()=>{var tmp=require("../cross-stack-reference-strength");return cross_stack_reference_strength_1=()=>tmp,tmp};exports.STRING_LIST_REFERENCE_DELIMITER="||";function crossStackReferenceStrength(scope){const value=scope.node.tryGetContext(cxapi().DEFAULT_CROSS_STACK_REFERENCES);if(value!=null){if(Object.values(cross_stack_reference_strength_1().ReferenceStrength).includes(value))return value;throw new(errors_1()).UnscopedValidationError((0,literal_string_1().lit)`InvalidReferenceStrength`,`Invalid value for ${cxapi().DEFAULT_CROSS_STACK_REFERENCES}: "${value}". Must be "strong", "weak", or "both".`)}}const WEAK_REFS_WARNING_EMITTED=Symbol.for("@aws-cdk/core.WeakRefsWarningEmitted"),OVERRIDDEN_REFERENCE_SYMBOL=Symbol.for("@aws-cdk/core.CustomCoupledReference");class CustomCoupledReference extends intrinsic_1().Intrinsic{static isCustomCoupledReference(x){return OVERRIDDEN_REFERENCE_SYMBOL in x}reference;strength;resolvedValue;constructor(reference,strength){super(reference,{typeHint:reference.typeHint}),this.reference=reference,this.strength=strength,Object.defineProperty(this,OVERRIDDEN_REFERENCE_SYMBOL,{value:!0})}assignValue(value){this.resolvedValue=value}resolve(context){return this.resolvedValue?this.resolvedValue.resolve(context):this.reference.resolve(context)}}exports.CustomCoupledReference=CustomCoupledReference;function resolveReferences(scope){const{refs,overrides}=findAllReferences(scope);for(const{source,value}of refs){const consumer=stack_1().Stack.of(source);if(!value.hasValueForStack(consumer)){const resolved=resolveValue(consumer,value);value.assignValueForStack(consumer,resolved)}}for(const{source,override}of overrides){const consumer=stack_1().Stack.of(source),resolved=resolveValue(consumer,override.reference,override.strength);override.assignValue(resolved)}}function resolveValue(consumer,reference,strengthOverride){const producer=stack_1().Stack.of(reference.target),producerAccount=token_1().Token.isUnresolved(producer.account)?cxapi().UNKNOWN_ACCOUNT:producer.account,producerRegion=token_1().Token.isUnresolved(producer.region)?cxapi().UNKNOWN_REGION:producer.region,consumerAccount=token_1().Token.isUnresolved(consumer.account)?cxapi().UNKNOWN_ACCOUNT:consumer.account,consumerRegion=token_1().Token.isUnresolved(consumer.region)?cxapi().UNKNOWN_REGION:consumer.region,resourceStrength=cfn_resource_1().CfnResource.isCfnResource(reference.target)?reference.target._crossStackReferenceStrengthOverride:void 0,strength=strengthOverride??resourceStrength??crossStackReferenceStrength(consumer)??"strong";if(producer===consumer)return reference;const appRoot=consumer.node.root;if(!appRoot[WEAK_REFS_WARNING_EMITTED]){const contextStrength=crossStackReferenceStrength(consumer);contextStrength===void 0?(appRoot[WEAK_REFS_WARNING_EMITTED]=!0,annotations_1().Annotations.of(consumer).addWarningV2("@aws-cdk/core:crossStackReferencesDefaultStrong",`No cross-stack-reference strength configured, defaulting to "strong". We recommend you set feature flag "${cxapi().DEFAULT_CROSS_STACK_REFERENCES}" to "both", then deploy everywhere, then set it to "weak". Alternatively, set it to "strong" explicitly to lock in the current producer-protecting behavior. (See: https://github.com/aws/aws-cdk/blob/main/packages/aws-cdk-lib/README.md#reference-strength)`)):contextStrength==="both"&&(appRoot[WEAK_REFS_WARNING_EMITTED]=!0,annotations_1().Annotations.of(consumer).addWarningV2("@aws-cdk/core:crossStackReferencesBothTransitional",`Feature flag "${cxapi().DEFAULT_CROSS_STACK_REFERENCES}" currently set to "both". This is a transitory state. After you have finished deploying this application everywhere, set it to "weak". (See: https://github.com/aws/aws-cdk/blob/main/packages/aws-cdk-lib/README.md#reference-strength)`))}if(producer.node.root!==consumer.node.root)throw new(errors_1()).UnscopedValidationError((0,literal_string_1().lit)`CannotReferenceAcrossApps`,"Cannot reference across apps. Consuming and producing stacks must be defined within the same CDK app.");if(producerAccount!==consumerAccount){if(strength==="strong"&&annotations_1().Annotations.of(consumer).addWarningV2("@aws-cdk/core:crossAccountRefsAreAlwaysWeak",`Strong references requested, but cross-account references can only be weak. Acknowledge this warning or set "${cxapi().DEFAULT_CROSS_STACK_REFERENCES}" to "weak" to remove this message.`),consumer.synthesizer.cloudFormationExecutionRole==null)throw new(errors_1()).UnscopedValidationError((0,literal_string_1().lit)`NoCfnExecutionRoleForCrossAccountRefs`,`Stack "${consumer.node.path}" cannot reference ${renderReference(reference)} in stack "${producer.node.path}". Could not find a CloudFormation execution role for the consumer stack. Use a stack synthesizer that provides a CloudFormation execution role, such as DefaultStackSynthesizer (that uses the role from the bootstrap stack), or one that you can customize, such as BootstraplessSynthesizer.`);if(producerRegion===cxapi().UNKNOWN_REGION||consumerRegion===cxapi().UNKNOWN_REGION)throw new(errors_1()).UnscopedValidationError((0,literal_string_1().lit)`CrossRegionReferencesRequireExplicitRegion`,`Stack "${consumer.node.path}" cannot reference ${renderReference(reference)} in stack "${producer.node.path}". Cross stack/region references are only supported for stacks with an explicit region defined. `);const producerStackArn=stack_1().Stack.of(reference.target).formatArn({service:"cloudformation",resource:"stack",resourceName:`${producer.stackName}/*`,region:producerRegion,account:producerAccount});return createGetStackOutput(reference,{consumerRoleArn:consumer.synthesizer.cloudFormationExecutionRole,producerAccount,producerRegion,producerStackArn})}if(consumer.nestedStackParent&&isNested(consumer,producer)){const parameterValue=resolveValue(consumer.nestedStackParent,reference);return createNestedStackParameter(consumer,reference,parameterValue)}if(producer.nested){const outputValue=createNestedStackOutput(producer,reference),resolvedValue=resolveValue(consumer,outputValue);return reference.typeHint===type_hints_1().ResolutionTypeHint.STRING_LIST?token_1().Tokenization.reverseList(cfn_fn_1().Fn.split(exports.STRING_LIST_REFERENCE_DELIMITER,token_1().Token.asString(resolvedValue))):resolvedValue}if(producerRegion!==consumerRegion){if(producerRegion===cxapi().UNKNOWN_REGION||consumerRegion===cxapi().UNKNOWN_REGION)throw new(errors_1()).UnscopedValidationError((0,literal_string_1().lit)`CrossRegionReferencesRequireExplicitRegion`,`Stack "${consumer.node.path}" cannot reference ${renderReference(reference)} in stack "${producer.node.path}". Cross stack/region references are only supported for stacks with an explicit region defined. `);if(consumer.addDependency(producer,`${consumer.node.path} -> ${reference.target.node.path}.${reference.displayName}`),strength==="strong")return createCrossRegionImportValue(reference,consumer);strength==="both"&&createCrossRegionExportOnly(reference,consumer);const producerStackArn=producer.formatArn({service:"cloudformation",resource:"stack",resourceName:`${producer.stackName}/*`,region:producerRegion,account:producerAccount});return createGetStackOutput(reference,{producerStackArn})}return consumer.addDependency(producer,`${consumer.node.path} -> ${reference.target.node.path}.${reference.displayName}`),strength==="strong"?createImportValue(reference):(strength==="both"&&createImportValue(reference),createGetStackOutput(reference,{}))}function renderReference(ref){return`{${ref.target.node.path}[${ref.displayName}]}`}function findAllReferences(root){const refs=new Array,overrides=new Array;for(const consumer of(0,construct_iteration_1().iterateDfsPreorder)(root))if(cfn_element_1().CfnElement.isCfnElement(consumer))try{const tokens=(0,resolve_1().findTokens)(consumer,()=>consumer._toCloudFormation());for(const token of tokens)CustomCoupledReference.isCustomCoupledReference(token)?overrides.push({source:consumer,override:token}):cfn_reference_1().CfnReference.isCfnReference(token)&&refs.push({source:consumer,value:token})}catch(e){if(e.type==="CfnSynthesisError")continue;throw e}return{refs,overrides}}function createImportValue(reference){const exportingStack=stack_1().Stack.of(reference.target);let importExpr;return reference.typeHint===type_hints_1().ResolutionTypeHint.STRING_LIST?(importExpr=exportingStack.exportStringListValue(reference),token_1().Tokenization.reverseList(importExpr)):(importExpr=exportingStack.exportValue(reference),token_1().Tokenization.reverseCompleteString(importExpr))}function getOrCreateExportWriter(reference,importStack){const referenceStack=stack_1().Stack.of(reference.target),exportingStack=referenceStack.nestedStackParent??referenceStack,exportable=getExportable(exportingStack,reference),id=JSON.stringify(exportingStack.resolve(exportable)),exportName=generateExportName(importStack,reference,id);if(token_1().Token.isUnresolved(exportName))throw new(errors_1()).UnscopedValidationError((0,literal_string_1().lit)`UnresolvedTokenInExportName`,`unresolved token in generated export name: ${JSON.stringify(exportingStack.resolve(exportName))}`);const writerConstructName=(0,uniqueid_1().makeUniqueId)(["ExportsWriter",importStack.region]);return{exportWriter:export_writer_provider_1().ExportWriter.getOrCreate(exportingStack,writerConstructName,{region:importStack.region}),exportName}}function createCrossRegionImportValue(reference,importStack){const{exportWriter,exportName}=getOrCreateExportWriter(reference,importStack),exported=exportWriter.exportValue(exportName,reference,importStack);return importStack.nestedStackParent?createNestedStackParameter(importStack,exported,exported):exported}function createCrossRegionExportOnly(reference,importStack){const{exportWriter,exportName}=getOrCreateExportWriter(reference,importStack);exportWriter.exportValueWriteOnly(exportName,reference,importStack)}function generateExportName(importStack,reference,id){const referenceStack=stack_1().Stack.of(reference.target),components=[referenceStack.stackName??"",referenceStack.region,id],prefix=`${importStack.nestedStackParent?.stackName??importStack.stackName}/`,localPart=(0,uniqueid_1().makeUniqueId)(components);return prefix+localPart.slice(Math.max(0,localPart.length-900+prefix.length))}const ROLE_CONSUMERS=new WeakMap;function createGetStackOutputRole(scope,id,props){const consumers=new Set([props.consumerRoleArn]),resource=new(cfn_resource_1()).CfnResource(scope,id,{type:"AWS::IAM::Role",properties:{AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{AWS:lazy_1().Lazy.any({produce:()=>{const arns=[...consumers].map(arn=>({"Fn::Sub":arn}));return arns.length===1?arns[0]:arns}})},Action:["sts:AssumeRole"]}]}}});ROLE_CONSUMERS.set(resource,consumers);const roleName=names_1().Names.uniqueResourceName(resource,{maxLength:64});resource.addPropertyOverride("RoleName",roleName);const roleArn=stack_1().Stack.of(scope).formatArn({service:"iam",resource:"role",resourceName:roleName,account:props.producerAccount,arnFormat:arn_1().ArnFormat.SLASH_RESOURCE_NAME,region:""});return{resource,roleRef:{roleArn,roleName}}}function addConsumerToRole(roleResource,consumerRoleArn){const consumers=ROLE_CONSUMERS.get(roleResource);consumers&&consumers.add(consumerRoleArn)}function createGetStackOutputPolicy(scope,id,props){const resource=new(cfn_resource_1()).CfnResource(scope,id,{type:"AWS::IAM::Policy",properties:{Roles:[cfn_fn_1().Fn.ref(props.role.logicalId)],PolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Action:"cloudformation:DescribeStacks",Resource:props.producerStackArn}]}}}),policyName=names_1().Names.uniqueResourceName(resource,{maxLength:128});return resource.addPropertyOverride("PolicyName",policyName),{resource,policyRef:{policyId:policyName}}}function createGetStackOutput(reference,options={}){const exportingStack=stack_1().Stack.of(reference.target),outputId="Output"+JSON.stringify(exportingStack.resolve(reference)),roleId="GetStackOutputRole",policyId="GetStackOutputPolicy";function createScope(stack){const scopeName="Publish";let scope2=stack.node.tryFindChild(scopeName);return scope2===void 0&&(scope2=new(constructs_1()).Construct(stack,scopeName)),scope2}const scope=createScope(exportingStack);let output=scope.node.tryFindChild(outputId);output==null&&(output=new(cfn_output_1()).CfnOutput(scope,outputId,{value:token_1().Token.asString(reference)}));let roleArn;if(options.consumerRoleArn){let roleResource=scope.node.tryFindChild(roleId);if(roleResource==null){const{resource,roleRef}=createGetStackOutputRole(scope,roleId,{consumerRoleArn:options.consumerRoleArn,producerAccount:options.producerAccount});roleResource=resource,roleArn=roleRef.roleArn}else{addConsumerToRole(roleResource,options.consumerRoleArn);const roleName=names_1().Names.uniqueResourceName(roleResource,{maxLength:64});roleArn=exportingStack.formatArn({service:"iam",resource:"role",resourceName:roleName,account:options.producerAccount,arnFormat:arn_1().ArnFormat.SLASH_RESOURCE_NAME,region:""})}scope.node.tryFindChild(policyId)==null&&createGetStackOutputPolicy(scope,policyId,{role:roleResource,producerStackArn:options.producerStackArn})}return token_1().Tokenization.reverseCompleteString(cfn_fn_1().Fn.getStackOutput(exportingStack.stackName,output.logicalId,exportingStack.region,roleArn))}function getExportable(stack,reference){return cfn_element_1().CfnElement.isCfnElement(reference.target)&&reference.target._lockLogicalId(),referenceNestedStackValueInParent(reference,stack)}function createNestedStackParameter(nested,reference,value){const paramId=generateUniqueId(nested,reference,"reference-to-");let param=nested.node.tryFindChild(paramId);if(!param){if(param=new(cfn_parameter_1()).CfnParameter(nested,paramId,{type:"String"}),!("setParameter"in nested))throw new(errors_1()).UnscopedValidationError((0,literal_string_1().lit)`NestedStackMustHaveSetParameter`,'assertion failed: nested stack should have a "setParameter" method');nested.setParameter(param.logicalId,token_1().Token.asString(value))}return param.value}function createNestedStackOutput(producer,reference){const outputId=generateUniqueId(producer,reference);let output=producer.node.tryFindChild(outputId);if(output||(reference.typeHint===type_hints_1().ResolutionTypeHint.STRING_LIST?output=new(cfn_output_1()).CfnOutput(producer,outputId,{value:cfn_fn_1().Fn.join(exports.STRING_LIST_REFERENCE_DELIMITER,token_1().Token.asList(reference))}):output=new(cfn_output_1()).CfnOutput(producer,outputId,{value:token_1().Token.asString(reference)})),!producer.nestedStackResource)throw new(errors_1()).AssumptionError((0,literal_string_1().lit)`AssertionFailed`,"assertion failed");return producer.nestedStackResource.getAtt(`Outputs.${output.logicalId}`)}function referenceNestedStackValueInParent(reference,targetStack){let currentStack=stack_1().Stack.of(reference.target);if(currentStack!==targetStack&&!isNested(currentStack,targetStack))throw new(errors_1()).UnscopedValidationError((0,literal_string_1().lit)`ReferencedResourceMustBeInTargetStack`,`Referenced resource must be in stack '${targetStack.node.path}', got '${reference.target.node.path}'`);const isNestedListReference=currentStack!==targetStack&&reference.typeHint===type_hints_1().ResolutionTypeHint.STRING_LIST;for(;currentStack!==targetStack;)reference=createNestedStackOutput(stack_1().Stack.of(reference.target),reference),currentStack=stack_1().Stack.of(reference.target);return isNestedListReference?token_1().Tokenization.reverseList(cfn_fn_1().Fn.split(exports.STRING_LIST_REFERENCE_DELIMITER,token_1().Token.asString(reference))):reference}function isNested(nested,parent){return nested.nestedStackParent===parent?!0:nested.nestedStackParent?isNested(nested.nestedStackParent,parent):!1}function generateUniqueId(stack,ref,prefix=""){return stack.resolve(`${prefix}${names_1().Names.nodeUniqueId(ref.target.node)}${ref.displayName}`)}