Repository: pulumi/pulumi-awsx (ts)

Issue:
Fargate max CPU size limits are no longer accurate
### What happened?

Fargate has increased the number of allowed vCPUs to 16: https://aws.amazon.com/about-aws/whats-new/2022/09/aws-fargate-increases-compute-memory-resource-configurations-4x/

In our vCPU calculation, we still have a ceiling of 4: https://github.com/pulumi/pulumi-awsx/blob/d03fbad7d367599aff8cffa9aff367dfd0fd6867/awsx/ecs/fargateMemoryAndCpu.ts#L66



### Expected Behavior

When setting the vCPU size of each container, we should allow a total of 16 vCPU

### Steps to reproduce

Create a task definition with multiple containers that has a vCPU requested of > 4

### Output of `pulumi about`

not required

### Additional context

_No response_

### Contributing

Vote on this issue by adding a 👍 reaction. 
To contribute a fix for this issue, leave a comment (and link to your pull request, if you've opened one already). 


Pull request description:
Update max CPU and memory for Fargate, add tests
Resolves #991

Patch:
diff --git a/awsx/ecs/fargateMemoryAndCpu.ts b/awsx/ecs/fargateMemoryAndCpu.ts
index 9e817732..21eb96b3 100644
--- a/awsx/ecs/fargateMemoryAndCpu.ts
+++ b/awsx/ecs/fargateMemoryAndCpu.ts
@@ -30,24 +30,29 @@ function* cpuMemoryConfigs({ vcpu, memGBs }: { vcpu: number; memGBs: Iterable<nu
   }
 }
 
+// from https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-cpu-memory-error.html
+// Supported task CPU and memory values for Fargate tasks are as follows.
+const allConfigs = [
+  ...cpuMemoryConfigs({ vcpu: 0.25, memGBs: [0.5, 1, 2] }),
+  ...cpuMemoryConfigs({ vcpu: 0.5, memGBs: range(1, 4) }),
+  ...cpuMemoryConfigs({ vcpu: 1, memGBs: range(2, 8) }),
+  ...cpuMemoryConfigs({ vcpu: 2, memGBs: range(4, 16) }),
+  ...cpuMemoryConfigs({ vcpu: 4, memGBs: range(8, 30) }),
+  ...cpuMemoryConfigs({ vcpu: 8, memGBs: range(16, 60) }),
+  ...cpuMemoryConfigs({ vcpu: 16, memGBs: range(32, 120) }),
+].sort((c1, c2) => c1.cost - c2.cost);
+
+// exported for tests
+export const maxVCPU = allConfigs.sort((c1, c2) => c1.vcpu - c2.vcpu)[allConfigs.length - 1].vcpu;
+export const maxMemGB = allConfigs.sort((c1, c2) => c1.memGB - c2.memGB)[allConfigs.length - 1]
+  .memGB;
+
 /**
  * Gets the list of all supported fargate configs.  We'll compute the amount of memory/vcpu
  * needed by the containers and we'll return the cheapest fargate config that supplies at
  * least that much memory/vcpu.
  */
 function fargateConfigsByPriceAscending() {
-  // from https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-cpu-memory-error.html
-  // Supported task CPU and memory values for Fargate tasks are as follows.
-  const allConfigs = [
-    ...cpuMemoryConfigs({ vcpu: 0.25, memGBs: [0.5, 1, 2] }),
-    ...cpuMemoryConfigs({ vcpu: 0.5, memGBs: range(1, 4) }),
-    ...cpuMemoryConfigs({ vcpu: 1, memGBs: range(2, 8) }),
-    ...cpuMemoryConfigs({ vcpu: 2, memGBs: range(4, 16) }),
-    ...cpuMemoryConfigs({ vcpu: 4, memGBs: range(8, 30) }),
-    ...cpuMemoryConfigs({ vcpu: 8, memGBs: range(16, 60) }),
-    ...cpuMemoryConfigs({ vcpu: 16, memGBs: range(32, 120) }),
-  ];
-  allConfigs.sort((c1, c2) => c1.cost - c2.cost);
   return allConfigs;
 }
 
@@ -61,13 +66,13 @@ export function calculateFargateMemoryAndCPU(containers: FargateContainerMemoryA
   // First, determine how much VCPU/GB that the user is asking for in their containers.
   let { requestedVCPU, requestedGB } = getRequestedVCPUandMemory(containers);
 
-  // Max CPU that can be requested is only 4.  Don't exceed that.  No need to worry about a
+  // Don't exceed the max CPU that can be requested. No need to worry about a
   // min as we're finding the first config that provides *at least* this amount.
-  requestedVCPU = Math.min(requestedVCPU, 4);
+  requestedVCPU = Math.min(requestedVCPU, maxVCPU);
 
-  // Max memory that can be requested is only 30.  Don't exceed that.  No need to worry about
+  // Don't exceed the max memory that can be requested. No need to worry about
   // a min as we're finding the first config that provides *at least* this amount.
-  requestedGB = Math.min(requestedGB, 30);
+  requestedGB = Math.min(requestedGB, maxMemGB);
 
   // Get all configs that can at least satisfy this pair of cpu/memory needs.
   const config = fargateConfigsByPriceAscending().find(


Test patch:
diff --git a/awsx/ecs/fargateMemoryAndCpu.test.ts b/awsx/ecs/fargateMemoryAndCpu.test.ts
new file mode 100644
index 00000000..c1cf2b1b
--- /dev/null
+++ b/awsx/ecs/fargateMemoryAndCpu.test.ts
@@ -0,0 +1,51 @@
+// Copyright 2016-2022, Pulumi Corporation.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import { calculateFargateMemoryAndCPU, maxMemGB, maxVCPU } from "./fargateMemoryAndCpu";
+
+describe("max vcpu and memory", () => {
+  it("max cpu", async () => {
+    expect(maxVCPU).toBeGreaterThanOrEqual(16);
+  });
+
+  it("max memory", async () => {
+    expect(maxMemGB).toBeGreaterThanOrEqual(120);
+  });
+
+  it("can request valid exact values", async () => {
+    const memCpu = calculateFargateMemoryAndCPU([
+      {
+        cpu: 8192, // 8 vcpu * 1024
+        memory: 20480, // 20 GB * 1024
+      },
+    ]);
+    expect(memCpu.cpu).toEqual("8192");
+    expect(memCpu.memory).toEqual("20480");
+  });
+
+  it("can request valid approximate values", async () => {
+    const memCpu = calculateFargateMemoryAndCPU([
+      {
+        cpu: 8000, // will be rounded up to 8 vcpu * 1024
+        memory: 21000, // will be rounded up to 21 GB = 21,504 MB.
+        // TODO,tkappler this doesn't seem correct as Fargate memory for this CPU range can
+        // only be requested "Between 16 GB and 4 GB increments" so it should probably be
+        // rounded up to 24 GB.
+        // https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-cpu-memory-error.html
+      },
+    ]);
+    expect(memCpu.cpu).toEqual("8192");
+    expect(memCpu.memory).toEqual("21504");
+  });
+});