pulumi / pulumi-awsx

AWS infrastructure best practices in component form!
https://www.pulumi.com/docs/guides/crosswalk/aws/
Apache License 2.0
223 stars 104 forks source link

Ability to resolve EC2 VPC subnets/ids by name or tags #748

Open shanehull opened 2 years ago

shanehull commented 2 years ago

Hello!

Issue details

The AWSX provider currently has the ability to return an output of subnets by type, eg:

const isolatedSubnets = myVpc.isolatedSubnets;
const privateSubnets = myVpc.privateSubnets;
const isolatedSubnetIds = myVpc.isolatedSubnetIds;
const privateSubnetIds = myVpc.privateSubnetIds;

It would be nice to have the ability to return a filtered output by the name or the tags assigned when they're created.

Eg. my VPC needs two isolated subnets, but I want to separate these into different RDS subnet groups and create different security groups for each according to their purpose.

// Create a VPC with frontend and backend subnets
const vpc = new awsx.ec2.Vpc(
  `${projectName}-${stackName}-vpc`,
  {
    cidrBlock: vpcCidrBlock,
    numberOfAvailabilityZones: 4,
    subnets: [
      {
        type: "isolated",
        name: `${projectName}-${stackName}-frontend-subnet`,
        tags: {
          Name: `${projectName}-${stackName}-frontend-subnet`,
        },
      },
      {
        type: "isolated",
        name: `${projectName}-${stackName}-backend-subnet`,
        tags: {
          Name: `${projectName}-${stackName}-backend-subnet`,
        },
      },
    ],
  },
  {
    provider: provider
  }
);

Some examples of how I've tried to hack together a solution...

If I output the following, the values are known in a pulumi preview:

const isolatedSubnets = vpc.isolatedSubnets;
const feTest = isolatedSubnets.then((subnets) =>
  subnets.map((subnets) => subnets.subnet.tags.apply((tags) => tags!.Name))
);

export const feTestOutput = feTest;

And I get:

Outputs:
  + feTestOutput         : [
  +     [0]: "my-database-dev-frontend-subnet"
  +     [1]: "my-database-dev-frontend-subnet"
  +     [2]: "my-database-dev-frontend-subnet"
  +     [3]: "my-database-dev-frontend-subnet"
  +     [4]: "my-database-dev-backend-subnet"
  +     [5]: "my-database-dev-backend-subnet"
  +     [6]: "my-database-dev-backend-subnet"
  +     [7]: "my-database-dev-backend-subnet"
    ]

But if I try the following, it clearly isn't equal (due to the way outputs work, I guess) so doesn't return anything:

const feTest = isolatedSubnets.then((subnets) =>
  subnets.filter(
    (subnet) =>
      subnet.subnet.tags!.Name ===
      pulumi.output(`${projectName}-${stackName}-frontend-subnet`)
  )
);

export const feTestOutput = feTest;

Maybe there's a simple solution and I just need to understand more about how outputs work, but either way, the feature would be a handy one to implement and it seems to be doable.

Edit: remove top-level await from examples

guineveresaenger commented 2 years ago

Hi @shed909 - I'm not familiar with your particular context, but you should be able to assign the subnet names to a variable and use them to create any dependent resources.

In case you haven't seen it yet: https://www.pulumi.com/docs/intro/concepts/inputs-outputs/#apply for reference

For faster help, you may want to reach out to the community over at https://slack.pulumi.com/.

shanehull commented 2 years ago

@guineveresaenger this is less of a support request and more of a feature request. I don't think this is possible using an apply.

I'm happy not using AWSX for the moment, which allows me to access each subnet directly in my stack, I just thought it would be a nice thing to have.

Context and examples are in the post - it's as simple as "having the ability to return a filtered output by the name or the tags assigned when a subnet is created", in addition to the isolatedSubnets and privateSubnets functionality.

danielrbradley commented 2 years ago

Hi @shed909 which version of the awsx package are you using here?

We're moving towards a new major release (1.0) which is currently in beta - please could you see if what you're asking for is now covered by the new VPC implementation?

shanehull commented 2 years ago

@danielrbradley I'm using v0.40.0. I'll give it a test!

shanehull commented 2 years ago

Thanks @danielrbradley, the export of subnets is perfect and meets my use case.

Just a side note/question, will this release allow tagging of the subnets?

shanehull commented 2 years ago

My mistake, I didn't actually test this properly before confirming. It looks like subnetName is missing from the new implementations outputs, and I can't see any other way to filter by the user-assigned name (side note, the docs say subnetSpecs.name is templated, but it doesn't appear to be altered in this implementation).

After a really quick look over the code, my suggestions would be:

Blueblazer172 commented 6 months ago
  • implement some sort of export of the subnets by type (eg. the old implementation allowed you to do vpc.publicSubnets, etc. etc.)

still not available in current pulumi version 2.8.0. in the prerelease versions e.g. 0.30.0 this was possible.