I was going to ask this in the <#CDE799L1M|> channel, but since it's essentially about Pulumi Output...
f
I was going to ask this in the #CDE799L1M channel, but since it's essentially about Pulumi Outputs, I've put it here. I hope that's okay. I have this piece of code:
Copy code
import pulumi
import pulumi_aws as aws
from typing import Mapping, Sequence


class ExistingVPC:
    def __init__(self, vpc_id: str, opts: pulumi.ResourceOptions = None):
        super().__init__("cority:aws:net", vpc_id, None, opts)
        # Variable Names
        vpc_id = vpc_id

        # Get the VPC details
        vpc = aws.ec2.get_vpc(id=vpc_id)

        # Get the Subnet Details of the VPC
        subnets = aws.ec2.get_subnets(
            filters=[
                {
                    "name": "vpc-id",
                    "values": [vpc_id],
                }
            ]
        )

        # Export subnet details
        subnet_ids = []
        for idx, subnet in enumerate(subnets.ids):
            export_name = f"subnet_{idx}_id"
            pulumi.export(export_name, subnet)
            subnet_ids.append(subnet)

        def get_subnet_value(idx):
            return pulumi.output(subnet_ids[idx])
For argument's sake, I want to programmatically access the
subnet_ids
value, so I've tried returning that from this class, for which I am declaring something in Pulumi called a component. Using this I'm trying to access that output:
Copy code
cnetworking = networking
vpc_information = cnetworking.ExistingVPC("vpc-id")
subnet_one = cnetworking.get_subnet_value(0)
But that's not right, and I can't figure out how to programmatically, without referencing stacks, get the output from resources being made in the same
pulumi-up
run. Any help would be greatly appreciated as it is slowing me down on this project.
s
Copy code
self.public_subnet_ids: Output[Sequence[str]] = Output.all(*[subnet.id for subnet in public_subnets])
        self.private_subnet_ids: Output[Sequence[str]] = Output.all(*[subnet.id for subnet in private_subnets])
        self.isolated_subnet_ids: Output[Sequence[str]] = Output.all(*[subnet.id for subnet in isolated_subnets])
f
Can
output.all
do more than just subnets?
As Ive also got to output this stuff for a VPC
Copy code
pulumi.export("vpc_id", vpc.id)
        pulumi.export("vpc_cidr_block", vpc.cidr_block)
        pulumi.export("vpc_enable_dns_support", vpc.enable_dns_support)
        pulumi.export("vpc_enable_dns_hostnames", vpc.enable_dns_hostnames)
        pulumi.export("vpc_default_network_acl_id", vpc.default_network_acl_id)
        pulumi.export("vpc_default_route_table_id", vpc.default_route_table_id)
        pulumi.export("vpc_main_route_table_id", vpc.main_route_table_id)
        pulumi.export("vpc_default_security_group_id", vpc.default_security_group_id)
s
outputting a few different values
but yeah i think you would just do the same for whatever you want available at time
f
Okay so then how to do you call those Output.All stuff like in your main file?
s
usually something like:
Copy code
pulumi.Output.all(
    public_subnets=vpc.public_subnet_ids,
    private_sunets=vpc.private_subnet_ids,
).apply(
    lambda args: share_prod_vpc_to_prod_accounts(
        public_subnets=args['public_subnets'],
        private_subnets=args['private_subnets'],
    )
)
f
Is there any good documentation on this? The stuff I found could have explained it better with code examples to get my head around. I don't mean that as a criticism. Perhaps I am missing something, but it was hard to get my head around, and it still is.
Also, Python is not my main language. I'm also trying to get my head around Python too. lol
s
if youre doing the pulumi.export way.. then you can reference them as strings in other projects/stacks
f
ohh right
Okay.
Thanks
s
f
Cheers I did come accross some of these Ill give them a re-read
Im just trying to do it without referencing a stack
So basically, coming from Terraform, you build modules, call the module, and then use the module output elsewhere in the code. That's what I am looking to achieve here.
s
Copy code
email_bucket = aws.s3.BucketV2(
    f"{product_name}_emails_bucket",
    bucket=f"{product_name}-emails".replace("_", "-"),
    force_destroy=True,
)
email_bucket_policy = aws.s3.BucketPolicy(
    f"{product_name}_email_bucket_policy",
    bucket=email_bucket.id,
    policy=pulumi.Output.all(email_bucket=email_bucket.arn).apply(
        lambda args: json.dumps(
            {
                "Version": "2012-10-17",
                "Statement": [
                    {
                        "Effect": "Allow",
                        "Principal": {"Service": "ses.amazonaws.com"},
                        "Action": "s3:PutObject",
                        "Resource": [
                            f"{args['email_bucket']}/*",
                        ],
                        "Condition": {"StringEquals": {"aws:Referer": aws_account_id}},
                    }
                ],
            }
        )
    ),
)
here is a good example to turn the bucket_arn into a string to convert it to json to be used in the bucket policy