Hi, I just created a new environment (test2) for my app, and now I’m trying to deploy a service to that environment but it fails.
Just for context, I’m attempting to use a monorepo setup:
/apps//infrastructure/copilot/copilot from /infrastructure/image property that points to the Dockerfile each service dir under /apps/test2)Here’s what I’m seeing:
/infrastructure/ % copilot app ls
plotwatt
/infrastructure/ % copilot env ls
test2
test
/infrastructure/ % copilot svc ls
Name Type
---- ----
/infrastructure/ % tree copilot -a --noreport -L 2
copilot
├── .workspace
├── bastion
│ ├── addons
│ └── manifest.yml
├── pienado
│ ├── addons
│ └── manifest.yml
└── shared-dummy
├── addons
└── manifest.yml
/infrastructure/ % copilot svc deploy
Select a service in your workspace pienado
Select an environment test2
✘ get service configuration: couldn't find service pienado in the application plotwatt
One strange thing here is that svc ls lists no services, but when the deploy command prompts me to choose a service, it lists all three services. Maybe that’s a clue as to what I messed up?
Any suggestions?
Thanks!
It occurred to me that I might have accidentally borked the application-level resources in my AWS account, so I deleted everything, including the application, with copilot app delete — that worked. Then I recreated the app, and an environment, both of which succeeded. But when I tried to deploy one of my services into the new environment of the new app, I got the same error message.
I’m baffled… 🤔 I did migrate laptops over the weekend… any chance that’s related somehow?
Hi @aviflax, looks like after recreating the app, you didn't recreate the service "pienado " before doing the svc deploy. I think that's why it failed. However, we should also check if the service specified in the manifest in the workspace exists or not in svc deploy because it looks like it is just listing all the services that exist locally (with manifests in the app workspace).
Thanks @iamhopaul123 — that’s very interesting. What does it mean to recreate a service? Is that done by running copilot svc init ? If so that’s interesting… because I thought of that, and I think I tried it, but since it prompted me for a service name rather than detecting the existing manifests, that made me think that the purpose of this command is to initialize a brand-new service from scratch, i.e. to generate a new manifest. Since I already have a manifest, I figured that wasn’t applicable to my situation.
What am I missing?
Thanks!
yeah i agree it seems to be a little bit misleading for this behavior but you actually need to do svc init again and use the service name that you want do deploy, since after deleting the app, all envs and svcs within the app were deleted too and you might need to recreate them (we just won't delete created files). svc init under the hood write your manifest and registers your service to the SSM parameter store where we also query to get svc ls data. However, it is 100% idempotent which means if any resource created by svc init already exists then we'll just skip that part.
OK, I figured I’d try running svc init and going through with the whole process, letting it do its thing, and now I get it: svc init is meant to handle both scenarios — creating a new manifest or using an existing manifest file.
I ran it and it printed this:
✔ Manifest file for service pienado already exists at copilot/pienado/manifest.yml, skipping writing it.
Your manifest contains configurations like your container size and port (:80).
✔ Created ECR repositories for service pienado.
So I should be good at this point.
While I’m here, this does seem like a possible opportunity to improve the UX.
For example, when I run copilot svc help the first line, the description printed, is: “Creates a new service in an application.” — this verb creates is a little fuzzy.
Anyway, thanks for the help!
Ah whoops, race condition! I posted my last comment before seeing your last reply.
So yeah, that makes sense now but I’m not sure how a user is supposed to learn this from the UX or the docs. (I promise, I spent at least an hour perusing the docs, the source code, and the tests to try to figure this out.)
Would it be helpful if I left this issue open for now so your team might consider a tweak to reduce the chances of someone else getting stuck/confused in the same way?
Absolutely @aviflax! I agree we have some UX improvement opportunities here and thank you for finding them!
Cool, my pleasure!
BTW, just a quick suggestion for a minor UX tweak… if I’m running svc init for a service for which I already have a manifest file, it feels strange (and wasteful) to have to specify the name, type, and Dockerfile location for my service before the tool detects that the manifest file already exists and so it then “throws away” the information I supplied via the CLI. Perhaps instead, there could be an option to specify an existing manifest file, because it already contains all that information. So one could run, perhaps, something like copilot svc init --manifest path/to/manifest — not only would that eliminate the unnecessary steps, it would also create an opportunity to explain when and why one might use this option.
🤔 Another thought: if I already have a manifest, maybe svc deploy should also “just work” — in other words, initialize the service and then deploy it — even if the service was deleted, or maybe was never even initialized at all.
I found myself in a similar situation and googling this issue came up.
I am trying to "re-hydrate" an app that is comprised of 4 services that are in 4 different sub-directories. I would have preferred a cleaner UX and a better separation between the "create" (which I associate to init) use case and the "import existing" use case.
In the current implementation I am confused about how/where I need to run the init command. Should I run it in the app root folder? Or in the folder of the service I need to re-hydrate? Also, I am going through the entire input process and eventually it says "oh but that exists". It does but what happens if I mispelled the service name by mistake? Would it have considered it a different service? Also, what happens if I purposely picked a different port? Would the existing manifest control or would my input control?
This is what I did (I launched this inside the service folder, one of the four):
[cloudshell-user@ip-10-1-174-175 yelb-ui]$ copilot svc init
Note: It's best to run this command in the root of your workspace.
Service type: Load Balanced Web Service
Service name: yelb-ui
Docker command is not found; Copilot won't build from a Dockerfile.
Image: mreferre/yelb-ui:0.7
Port: 80
✔ Manifest file for service yelb-ui already exists at manifest.yml, skipping writing it.
Your manifest contains configurations like your container size and port (:80).
✔ Created ECR repositories for service yelb-ui.
Recommended follow-up actions:
- Update your manifest manifest.yml to change the defaults.
- Run `copilot svc deploy --name yelb-ui --env test` to deploy your service to a test environment.
[cloudshell-user@ip-10-1-174-175 yelb-ui]$
Hello @mreferre. Yes we are thinking to make the UX better when users are trying to update the current services. So I think our current behavior is
app folder or svc folder should be ok.svc init will be ignored and will not be included in your manifest. (Opened another issue #1460)copilot svc ls or see it in the copilot folder where we store the manifest.
Most helpful comment
Cool, my pleasure!
BTW, just a quick suggestion for a minor UX tweak… if I’m running
svc initfor a service for which I already have a manifest file, it feels strange (and wasteful) to have to specify the name, type, and Dockerfile location for my service before the tool detects that the manifest file already exists and so it then “throws away” the information I supplied via the CLI. Perhaps instead, there could be an option to specify an existing manifest file, because it already contains all that information. So one could run, perhaps, something likecopilot svc init --manifest path/to/manifest— not only would that eliminate the unnecessary steps, it would also create an opportunity to explain when and why one might use this option.