Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What is the best way to suspend/resume server? #8

Open
hiragram opened this issue Feb 21, 2021 · 21 comments
Open

What is the best way to suspend/resume server? #8

hiragram opened this issue Feb 21, 2021 · 21 comments

Comments

@hiragram
Copy link

Hello! Thank you for your great job. I'm enjoying survival life with my friends.

I have a small experience around AWS, but new to ECS, Fargate, and CDK. I want to know the best way to stop servers to avoid being charged, and resume when we start playing again.

If you told me the instruction, I can add it to readme.

@rileydakota
Copy link
Owner

Hi there @hiragram - thanks for reaching out. So you have a couple of options:

  1. Manually modify the desired number of tasks for the Fargate Service from 1 to 0 (will get old fast, but here for reference:
    image
    (CLI command is also an option for this as well - but same pain)

  2. Add Cloudwatch Event Triggers to change the number of desired tasks automatically based on a cron expression: https://docs.aws.amazon.com/cdk/api/latest/docs/aws-ecs-readme.html#integration-with-cloudwatch-events
    (EG - could have rules that change the number of tasks to 0 on weeknights after 2am and set it back to 1 after 12pm?)

Number 2 is probably the best option - just need to figure out a good way to add it without making it too specific to one person.

@rileydakota
Copy link
Owner

I am working on adding #2 in some form (maybe a documented set of examples addable to the code?) - but would also be very open to a PR :)

@sdredsoxfan
Copy link

I am working on adding #2 in some form (maybe a documented set of examples addable to the code?) - but would also be very open to a PR :)

I'd actually be quite curious to know how you'd solve the problem of turning the server back on automatically. AFAIK, there isn't a good way to detect this since the server wouldn't be discoverable while off.

@rileydakota
Copy link
Owner

@sdredsoxfan you are correct - sadly there is no way to handle it in that manner - but we can "Schedule" the server via CloudWatch Event Rules. For example - if you know your group only plays during 4pm-1am EST during weekdays, you could schedule the task to power down during the off hours and save a good bit of money. This is all dependent on this being acceptable to the end user however. Will work for some, but not others.

@sdredsoxfan
Copy link

Makes sense. I think a temporal solution is really the only thing feasible! I was discussing with the people I play with about it. Not sure it would work well for me personally because one of them likes to get some farming in throughout the day.

@sdredsoxfan
Copy link

You could possibly set up an API Gateway that users can hit which uses a Lambda to fire up the server and allow auth'd users to turn on the server when they want to play and then let the auto shut down mechanism fire.

@hiragram
Copy link
Author

@rileydakota Thank you! I could resume/restart server perfectly!

@rileydakota
Copy link
Owner

@hiragram happy to hear it! @sdredsoxfan I was actually thinking of adding a discord/slack bot for a little bit of chatsops type management (think /valheim-aws stop). Just have to rely on people to shut it off (or could just have an auto power off mechanism too)

@DaveB93
Copy link

DaveB93 commented Mar 4, 2021

Just a question / comment on this. When the server restarts it has a different IP. I guess you could also put a command on the api gateway to get the server IP ? alternately you could set up route 53 to point to the servers dns.

or is there an auto-assigned dns for fargateClusters ?

@rileydakota
Copy link
Owner

Hi @DaveB93 - I think to get a static IP you would need to utilize an ELB, and then map a route53 Hosted Zone to the ELB AFAIK. I am planning to add this to the template soon, will probably add a toggle to enable it/disable it as it will add additional cost to the solution

@DaveB93
Copy link

DaveB93 commented Mar 5, 2021

re: Using Cloudwatch Event rules, I wasn't able to figure out how to use that to set the desired capacity for the service to 0 ( to stop things ) or to use it to set the task to stop. instead I ended up using AWS application autoscaling on the service to change the desired capacity.

First you need to register a scalable target

aws application-autoscaling register-scalable-target --service-namespace ecs --resource-id service/ValheimServerAwsCdkStack-fargateCluster#####/ValheimServerAwsCdkStack-valheimService##### --scalable-dimension ecs:service:DesiredCount --min-capacity 0 --max-capacity 1

Then you just set up your rules to stop and start.

aws application-autoscaling put-scheduled-action --service-namespace ecs --resource-id service/ValheimServerAwsCdkStack-fargateCluster####/ValheimServerAwsCdkStack-valheimService#### --schedule "cron(0 0 * * ? *)" --timezone America/Vancouver --scheduled-action-name stopAtMidnight --scalable-dimension ecs:service:DesiredCount --scalable-target-action MinCapacity=0,MaxCapacity=0

to list your existing rules you can
aws application-autoscaling describe-scheduled-actions --service-namespace ecs

Note: it's possible to set --scalable-target-action adjust just the Min or Max capacity, if you're trying to shut the server down, you will have to adjust both Min and Max to 0 in order to get it to work, or you will get the following error in your Event logs:
Message: Failed to set max capacity to 0. Reason: Maximum capacity cannot be less than minimum capacity Cause: scheduled action name stopAtMidnight was triggered

https://docs.aws.amazon.com/autoscaling/application/userguide/examples-scheduled-actions.html
https://docs.aws.amazon.com/cli/latest/reference/application-autoscaling/register-scalable-target.html
https://docs.aws.amazon.com/cli/latest/reference/application-autoscaling/put-scheduled-action.html

it does look like there's cdk hooks for that https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-applicationautoscaling.ScalableTarget.html but I'm not that familiar with the cdk, so not ready to add them via that yet.

@DaveB93
Copy link

DaveB93 commented Mar 8, 2021

I've gotten some lambda functions set up that allow your friends to start/stop the server and see the server IP and if it's running. I currently have them here https://github.com/DaveB93/lambda-ecs-fargate-updownstatus in a very messy state. I will see about working with the CDK to automate the setup of them a bit more, and then possibly integrate them with this script.

@DaveB93
Copy link

DaveB93 commented Mar 14, 2021

Okay I've converted my deploy to use the CDK. It probably wouldn't be too hard to merge it in with your repo, but in order to compile the nodejs lambdas it ends up needing docker installed. ( it might work by just installing esbuild, but I didn't play with that. ) I haven't done conditionals in the CDK yet, and I haven't looked up how to pass values from one service to another, so not sure how into merging them I am at this point.

I also have done the bare minimum of authentication. It feels like it want to be frontended by Cognito, but I didn't find a sample cognito website ( with only a tiny bit of searching. ) I might come back to it, but for now it's probably good enough for me and my friends.

@PAHelper2
Copy link

Can someone provide a cli example to set the instance count to 1 or 0?

@rileydakota
Copy link
Owner

@DaveB93 if you want to create a bare bones PR we can collaborate on combining the code

@DaveB93
Copy link

DaveB93 commented Mar 15, 2021

@PAHelper2

Can someone provide a cli example to set the instance count to 1 or 0?

aws ecs update-service --cluster ValheimServerAwsCdkStack-fargateClusterXXX-eccXXXX --service ValheimServerAwsCdkStack-valheimServiceXXXX-ojXXXXX --desired-count 0

@DaveB93
Copy link

DaveB93 commented Mar 17, 2021

Hey @rileydakota I have a PR, but I need permission from my work to post it. ( thing in my employment contract. )

@DaveB93
Copy link

DaveB93 commented Mar 26, 2021

sorry for the delay on the PR. work took a while to approve it.

@skeeters1
Copy link

skeeters1 commented May 15, 2021

Help request

Love this. Thank you. Just getting started and I am struggling to trigger the start/stop via API gateway in the most basic way. The status function works easily from my browser:
https://MY_ARN.execute-api.eu-west-2.amazonaws.com/prod/serverstatus
returns a "running" status and IP address as expected

But I can't authenticate to the start/stop:
https://MY_ARN.execute-api.eu-west-2.amazonaws.com/prod/startstop?MYPASSWORD
returns not authenticated

I think I just can't get the URL syntax right and not good enough with lambda to debug it. Would someone mind giving an example snippet please?

Agree an EIP option would be helpful as would Discord integration. Also a "start server unless already running" function which any team member could run. Thanks!

@DaveB93
Copy link

DaveB93 commented Jun 1, 2021

Help request

Love this. Thank you. Just getting started and I am struggling to trigger the start/stop via API gateway in the most basic way. The status function works easily from my browser:
https://MY_ARN.execute-api.eu-west-2.amazonaws.com/prod/serverstatus
returns a "running" status and IP address as expected

But I can't authenticate to the start/stop:
https://MY_ARN.execute-api.eu-west-2.amazonaws.com/prod/startstop?MYPASSWORD
returns not authenticated

I think I just can't get the URL syntax right and not good enough with lambda to debug it. Would someone mind giving an example snippet please?

@skeeters1 my apologies, I have my github email going to an account I don't really check. are you still looking for help with this?

looking at your URI, you need key=MYPASSWORD

e.g. https://MY_ARN.execute-api.eu-west-2.amazonaws.com/prod/startstop?key=MYPASSWORD

Agree an EIP option would be helpful as would Discord integration. Also a "start server unless already running" function which any team member could run. Thanks!

the startstop works exactly as this. if they run start as
https://MY_ARN.execute-api.eu-west-2.amazonaws.com/prod/startstop?key=MYPASSWORD

and stop as

https://MY_ARN.execute-api.eu-west-2.amazonaws.com/prod/startstop?key=MYPASSWORD@desiredCount=0

@Mood93
Copy link

Mood93 commented Sep 2, 2021

the startstop works exactly as this. if they run start as
https://MY_ARN.execute-api.eu-west-2.amazonaws.com/prod/startstop?key=MYPASSWORD

and stop as

https://MY_ARN.execute-api.eu-west-2.amazonaws.com/prod/startstop?key=MYPASSWORD@desiredCount=0

Correction: the @ before desiredCount should be an &

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants