All of the examples use the CfnOutput
class. But the CfnOutput
class only accepts a str
for the value
parameter.
This doesn't work for that reason:
from aws_cdk import CfnOutput, Stack, aws_ec2
from constructs import Construct
class MyVpc(Stack):
def __init__(self, scope: Construct, construct_id: str) -> None:
super().__init__(scope, construct_id)
vpc = aws_ec2.Vpc.from_lookup(scope, construct_id, is_default=True)
CfnOutput(self, "private_subnets", values=vpc.private_subnets)
CfnOutput(self, "public_subnets", values=vpc.public_subnets)
The error being
Argument of type "List[ISubnet]" cannot be assigned to parameter "value" of type "str" in function
As the code snippet shows, I'd like to export a list of VPC subnets from the AWS-created default VPC in order to pass into to an another stack that needs a list of subnet IDs. There is no example or documentation for something like this that I can find after a long search in vain: there are hundreds of Python classes in this library whose documentation is extremely difficult to navigate for someone who's new to AWS CDK. I can concatenate the subnet IDs into a string and then split them in the other stack, but that seems ridiculous.
What is the correct way to export a value that is more general than a string from one stack to be used in another stack?
If you need to reference VPC resources across independent stacks (not nested or in the same CDK app), you can use CfnOutput and Vpc.from_lookup()
Outputs only accept strings, not lists. So we can create the CfnOutput
by iterating over subnets like this:
for idx, subnet in vpc.private_subnets:
CfnOutput(self, f"private_subnet{idx}", value=subnet.subnet_id)
For nested stacks or Stacks that are part of the same App, it's simpler to pass the VPC object directly:
class VpcStack(Stack):
def __init__(self, scope: Construct, construct_id: str, **kwargs):
super().__init__(scope, construct_id, **kwargs)
self.vpc = aws_ec2.Vpc(self, "VPC", max_azs=2)
self.private_subnets = self.vpc.private_subnets
self.public_subnets = self.vpc.public_subnets
class VpcConsumerStack(Stack):
def __init__(self, scope: Construct, construct_id: str, vpc_provider: VpcProviderStack, **kwargs):
super().__init__(scope, construct_id, **kwargs)
private_subnets = vpc_provider.private_subnets
public_subnets = vpc_provider.public_subnets
# Use these subnets as needed
app = App()
vpc_provider = VpcProviderStack(app, "VpcProviderStack")
vpc_consumer = VpcConsumerStack(app, "VpcConsumerStack", vpc_provider=vpc_provider)
app.synth()