I'm trying to fit together the last piece of an EC...
# aws
b
I'm trying to fit together the last piece of an ECS deployment pipeline and I'm not sure how to go about it, and the bits I've found on how others have don't seem to fit with how I'm approaching the problem. So I'm wondering if I need to rethink the entire approach. I have an infrastructure repo that has Pulumi code for defining all sorts of things. This includes all the stuff required for the ECS cluster, including the container definitions themselves for an app. Right now it's using a statically-defined
image
. In the apps' repos, I have Github Actions rules that build the containers and push them to ECR. Now I need to close the gap between these two. My thought was that I'd trigger CodeDeploy from Actions (we're doing that for the old process I'm replacing) and that would handle the deployment. The problem is that the next time I run
pulumi up
, it'll re-deploy some old version of the app. Ideally I'd just leave that field out, but it is required by the SDK. The few things I've found about how other people do this is to run pulumi in the deploy pipeline and pass it the container version in an environment variable. I don't particularly want to run all of the infrastructure configuration stuff on a code deploy, though (and especially don't want changes to infra to potentially roll out while a developer is running what they think is a normal code deploy). But is that what I have to do?
If this is the path, how would I go about putting only a minimal amount of pulumi code in each app's repo, and having that reference all the shared infrastructure that lives in its own place?
l
The app repo should handle deploying to ECR in one Pulumi project. There should be another project, probably in the same repo, with references to that project's outputs (for ECR info), and the infrastructure project's output (for the cluster info). That project creates TaskDefinitions. Each time you
up
stacks in this project, you'll create a new version of the TaskDefinition, and ECS will handle deploying the image and draining old containers.
You need separate projects because you'll have different
up
cycles: you'll deploy images to various ECS clusters much more frequently than you'll push images to ECR.
You'll probably also have much fewer stacks in the ECR-related project. A single image can be pushed to dev, staging, different regions,.. whatever you use stacks for.
b
I already have the container build and push process working outside of pulumi; that should be ok as long as I can pass the resultant container information in to https://github.com/pulumi/actions , right?
But what I'm getting from this is that if I want to define the ECS cluster in pulumi, that means I need to use pulumi to do the deploy of new container versions, yeah?
l
You don't need to, no. You just need to create a new task definition version in ECS.
Pulumi makes that easy, but the AWS SDK and CLI (and other tools) can do it too.
b
Right, so I guess to clarify more, if I want to define the task definition with all its various parameters in Pulumi, then the container version also needs to be Pulumi-ized. So I can't pick and choose and have Pulumi define things like the container memory limits but not the image version. Which I guess is fine.
l
The task definition version is a single JSON document. If you want to build parts of it in one system and parts in another, you can do that, but only by having one system ingest the other system's outputs (or contributing values).
b
Well, ideally I was thinking not of changing the definition, but rather having the definition include dynamism.
nginx:latest
is an example, where it's referring to a tag but that tag can change to whatever.
l
Ah. Major warning: don't ever do that.
b
Yeah, I actually want a specified version
I think the problem here is how Amazon has structured the API for ECS though, because they require the container tag to be set together with all the other stuff. So that's just that.
l
Yes, do that. Build the version, release it to ECR, then when you're ready to deploy to dev, create a new dev TaskDefintion. A few hours later, you'll create a new staging TaskDefinition.
No, that's not a problem: that's correct.
All those values must be confirmed together. If your image tag changes, you need to confirm that its environment variables are still the same, the memory requirements are still the same, etc.
It's deliberate.
b
Correct in that it's accurate, but a pain in the ass, given that some of those are infrastructure concerns and the others are app concerns
l
I think your thinking is not aligned with devops. Changing the app version is not an app-only concern.
If you want to release a new versoin of the app, you need to bring an ops-focused mindset to releasing it.
You need to consider all the factors.
If you just want to deploy a new version of the app for completely private testing, then ECS isn't the right tool. Use
docker run
or
docker-compose up
b
Well this is devolving to philosophical discussions on things we can't actually change, so I don't think that's useful to continue here. But thank you for your help - that's helped me see what my options are