Repository: pulumi/pulumi-awsx
Pull request #1207 (2024-01-20 03:07:00)

ci: Use GITHUB_OUTPUT envvar instead of set-output command
`save-state` and `set-output` commands used in GitHub Actions are deprecated and [GitHub recommends using environment files](https://github.blog/changelog/2023-07-24-github-actions-update-on-save-state-and-set-output-commands/).

This PR updates the usage of `::set-output` to `"$GITHUB_OUTPUT"`

Instructions for envvar usage from GitHub docs:

https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-output-parameter

github-actions[bot]: PR is now waiting for a maintainer to run the acceptance tests. This PR will only perform build and linting.
**Note for the maintainer:** To run the acceptance tests, please comment */run-acceptance-tests* on the PR

Patch:
diff --git a/awsx/ec2/knownWorkingSubnets.ts b/awsx/ec2/knownWorkingSubnets.ts
index 46f2089f..6f4ae67a 100644
--- a/awsx/ec2/knownWorkingSubnets.ts
+++ b/awsx/ec2/knownWorkingSubnets.ts
@@ -1323,4 +1323,22 @@ export const knownWorkingSubnets: {
     ],
     vpcCidr: "10.0.0.0/20",
   },
+  {
+    vpcCidr: "10.1.0.0/18",
+    subnetSpecs: [
+      {
+        type: "Private",
+      },
+      {
+        type: "Public",
+      },
+      {
+        type: "Isolated",
+      },
+      {
+        type: "Isolated",
+      },
+    ],
+    result: ["10.1.0.0/19", "10.1.32.0/20", "10.1.48.0/24", "10.1.49.0/24"],
+  },
 ];
diff --git a/awsx/ec2/subnetDistributorLegacy.ts b/awsx/ec2/subnetDistributorLegacy.ts
index c0aadb69..5b396bc1 100644
--- a/awsx/ec2/subnetDistributorLegacy.ts
+++ b/awsx/ec2/subnetDistributorLegacy.ts
@@ -70,8 +70,9 @@ export function getSubnetSpecsLegacy(
 
   let subnetsOut: SubnetSpec[] = [];
 
-  // How many bits do we need if just dividing up evenly?
-  const newBitsPerSubnet = Math.log2(nextPow2(subnetInputs.length));
+  // How many bits do we need if just assuming a "normal" layout with at least a private and public subnet?
+  // Special case where there's only 1 subnet - with a small VPC, we'll let it use the whole space.
+  const newBitsPerSubnet = subnetInputs.length === 1 ? 0 : 1;
 
   for (let i = 0; i < azNames.length; i++) {
     const privateSubnetsOut: SubnetSpec[] = [];


Test patch:
diff --git a/.github/workflows/run-acceptance-tests.yml b/.github/workflows/run-acceptance-tests.yml
index f0be1a00..5b603333 100644
--- a/.github/workflows/run-acceptance-tests.yml
+++ b/.github/workflows/run-acceptance-tests.yml
@@ -31,7 +31,7 @@ jobs:
     steps:
       - name: Create URL to the run output
         id: vars
-        run: echo ::set-output name=run-url::https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID
+        run: echo run-url=https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID >> "$GITHUB_OUTPUT"
       - name: Update with Result
         uses: peter-evans/create-or-update-comment@v3
         with:
diff --git a/awsx/ec2/subnetDistributorLegacy.test.ts b/awsx/ec2/subnetDistributorLegacy.test.ts
index d47cdeb1..25f18819 100644
--- a/awsx/ec2/subnetDistributorLegacy.test.ts
+++ b/awsx/ec2/subnetDistributorLegacy.test.ts
@@ -86,6 +86,44 @@ describe("default subnet layout", () => {
     );
   });
 
+  describe("default sizes private, public and isolated subnet", () => {
+    it("gives /19, /20 and /24 for /16 AZ", () => {
+      expect(getDefaultSubnetSizes(16)).toEqual([19, 20, 24]);
+    });
+    it("gives /19, /20 and /24 for /17 AZ", () => {
+      expect(getDefaultSubnetSizes(17)).toEqual([19, 20, 24]);
+    });
+    it("gives /19, /20 and /24 for /18 AZ", () => {
+      expect(getDefaultSubnetSizes(18)).toEqual([19, 20, 24]);
+    });
+    it("gives /20, /20 and /24 for /19 AZ", () => {
+      expect(getDefaultSubnetSizes(19)).toEqual([20, 20, 24]);
+    });
+    it("gives /21, /21 and /24 for /20 AZ", () => {
+      expect(getDefaultSubnetSizes(20)).toEqual([21, 21, 24]);
+    });
+    it("gives /22, /22 and /24 for /21 AZ", () => {
+      expect(getDefaultSubnetSizes(21)).toEqual([22, 22, 24]);
+    });
+    it("gives /23, /23 and /24 for /22 AZ", () => {
+      expect(getDefaultSubnetSizes(22)).toEqual([23, 23, 24]);
+    });
+    it("gives /24, /24 and /24 for /23 AZ", () => {
+      expect(getDefaultSubnetSizes(23)).toEqual([24, 24, 24]);
+    });
+
+    function getDefaultSubnetSizes(azSize: number) {
+      const vpcCidr = `10.0.0.0/${azSize}`;
+      const result = getSubnetSpecsLegacy(
+        "vpcName",
+        vpcCidr,
+        ["us-east-1a"],
+        [{ type: "Private" }, { type: "Public" }, { type: "Isolated" }],
+      );
+      return result.map((s) => getCidrMask(s.cidrBlock));
+    }
+  });
+
   it("should use default values if VPC is large", () => {
     fc.assert(
       fc.property(
diff --git a/awsx/ec2/subnetDistributorNew.test.ts b/awsx/ec2/subnetDistributorNew.test.ts
index b4970ea0..407da630 100644
--- a/awsx/ec2/subnetDistributorNew.test.ts
+++ b/awsx/ec2/subnetDistributorNew.test.ts
@@ -50,6 +50,30 @@ function subnetSpec() {
 }
 
 describe("default subnet layout", () => {
+  describe("when no layout specified", () => {
+    it.each([16, 17, 18, 19, 20, 21, 22, 23, 24])(
+      "/%i AZ creates single private & public with staggered sizes",
+      (azCidrMask) => {
+        expect(getDefaultSubnetSizes(azCidrMask)).toMatchObject([
+          {
+            type: "Private",
+            cidrMask: azCidrMask + 1,
+          },
+          {
+            type: "Public",
+            cidrMask: azCidrMask + 2,
+          },
+        ]);
+      },
+    );
+
+    function getDefaultSubnetSizes(azSize: number) {
+      const vpcCidr = `10.0.0.0/${azSize}`;
+      const result = getSubnetSpecs("vpcName", vpcCidr, ["us-east-1a"], undefined);
+      return result.map((s) => ({ type: s.type, cidrMask: getCidrMask(s.cidrBlock) }));
+    }
+  });
+
   it("should have smaller subnets than the vpc", () => {
     fc.assert(
       fc.property(
@@ -92,6 +116,36 @@ describe("default subnet layout", () => {
     );
   });
 
+  describe("default sizes for private, public and isolated subnet", () => {
+    it.each([16, 17, 18, 19, 20, 21, 22, 23, 24])(
+      "/%i AZ evenly distributes space",
+      (azCidrMask) => {
+        const vpcCidr = `10.0.0.0/${azCidrMask}`;
+        const result = getSubnetSpecs(
+          "vpcName",
+          vpcCidr,
+          ["us-east-1a"],
+          [{ type: "Private" }, { type: "Public" }, { type: "Isolated" }],
+        );
+        const masks = result.map((s) => ({ type: s.type, cidrMask: getCidrMask(s.cidrBlock) }));
+        expect(masks).toMatchObject([
+          {
+            type: "Private",
+            cidrMask: azCidrMask + 2,
+          },
+          {
+            type: "Public",
+            cidrMask: azCidrMask + 2,
+          },
+          {
+            type: "Isolated",
+            cidrMask: azCidrMask + 2,
+          },
+        ]);
+      },
+    );
+  });
+
   it("should not have overlapping ranges", () => {
     fc.assert(
       fc.property(