sst / ion

SST v3
https://sst.dev
MIT License
1.44k stars 188 forks source link

Cluster: specifying a `containerDefinitions` shall not overwrite base Ion settings #718

Closed 0cv closed 1 month ago

0cv commented 1 month ago

Simplified sst.config.ts:

const service = cluster.addService("Service", {
  image: {
    context: "./service",
  },
  architecture: "arm64",
  cpu: "0.25 vCPU",
  memory: "0.5 GB",
  transform: {
    taskDefinition: {
      containerDefinitions: $jsonStringify([
        {
          portMappings: [
            {
              containerPort: 80,
              hostPort: 80,
              name: "http-80-80",
            },
          ],
        },
      ]),
    },
  },
});

This will fail with the error ClientException: Container.name should not be null or empty.

This is because I didn't specify a name in the Container Definitions along the portMappings. Now I can specify a name, but then the next error will be on the Image, because the image is not part of the containerDefinitions either (but part of the configuration nonetheless). I think that when a containerDefinitions is specified, it will overwrite this part https://github.com/sst/ion/blob/af5c90ce281c6810b2ef6b31f24b66e7e482ee59/platform/src/components/aws/service.ts#L516?

You might ask why I specify a containerDefinitions to begin with, and it's because I want a portMappings (to use Service Connect), but I don't want a Load Balancer.

fwang commented 1 month ago

can you give this a try:

    const service = cluster.addService("Service", {
      image: {
        context: "./service",
      },
      architecture: "arm64",
      cpu: "0.25 vCPU",
      memory: "0.5 GB",
      transform: {
        taskDefinition: (args) => {
          args.containerDefinitions = $output(args.containerDefinitions).apply(
            (v) =>
              JSON.stringify({
                ...JSON.parse(v),
                portMappings: [
                  {
                    containerPort: 80,
                    hostPort: 80,
                    name: "http-80-80",
                  },
                ],
              })
          );
        },
      },
    });
0cv commented 1 month ago

@fwang Thank you, I never realized that Transform<...> in the definitions and thought it shall be a static array ... That's cool! Okay, I've tried this alternative, I had to make some small changes because containerDefinitions is an array (and shall be an array too), but the image is not properly returned. Here is what I get:

transform: {
  taskDefinition: (args) => {
    args.containerDefinitions = $output(args.containerDefinitions).apply(
      (v) => {
        console.log("### => v", v);
        return JSON.stringify([
          {
            ...JSON.parse(v)[0],
            portMappings: [
              {
                containerPort: 80,
                hostPort: 80,
                name: "service-80-tcp",
              },
            ],
          },
        ]);
      }
    );
  },
  ...
}
|  Log         ### => v
[{"name":"Service","image":"<none>@<none>","pseudoTerminal":true,"logConfiguration":{"logDriver":"a
group":"....","awslogs-region":"us-west-2","awslogs-str
prefix":"/service"}},"environment":[{"name":"PORT","value":"80"},...,{"name":"REGION","value":"us-west-
2"},{"name":"SST_RESOURCE_App","value":"{\"name\":\"...",\"stage\":\"...\"}"}]}]

All is perfectly returned (I've omitted some environment variables, removed the app name, stage etc.), but I've not edited anything at the image. It's "image":"<none>@<none>" - which is obviously incorrect. The error is ClientException: Container.image repository contains invalid characters. But yes, the Repo Digest isn't set correctly

fwang commented 1 month ago

@0cv hmm i tried ur code above and got this. Note image is set correctly.

### => v [{"name":"MyService","image":"112245769880.dkr.ecr.us-east-1.amazonaws.com/sst-asset@sha256:7d250accd68cebc5a5e9708f480fb41ce8449dd632835261296cc6cecdd0ec0e","pseudoTerminal":true,"portMappings":[{"containerPort":80}],"logConfiguration":{"logDriver":"awslogs","options":{"awslogs-group":"/sst/cluster/aws-cluster-frank-MyClusterCluster/MyService","awslogs-region":"us-east-1","awslogs-stream-prefix":"/service"}},"environment":[{"name":"SST_RESOURCE_MyBucket","value":"{\"name\":\"aws-cluster-frank-mybucket-kkwrkurd\",\"type\":\"sst:aws:Bucket\"}"},{"name":"SST_RESOURCE_App","value":"{\"name\":\"aws-cluster\",\"stage\":\"frank\"}"}]}]

In our terminal output, above ### => ... do u see the image build successfully?

Screen Shot 2024-07-30 at 3 38 31 PM
0cv commented 1 month ago

@fwang I believe I shall have provided the SST version. I agree that with a recent SST version it works (0.1.40). I'm facing a new issue on Cluster/Service that I've posted here, but it's unrelated to this one https://github.com/sst/ion/issues/795

I will close this issue.