How to launch a single EC2 instance in response to an incoming network connection - amazon-web-services

I'm planning to host some private services on AWS. These services will only be used by me and possibly 1-2 other people, but never more.
I would like the single EC2 instance that I'm using to only run when I'm using it. I don't want to manually start and stop it on the AWS console.
Ideally, I would need to things to happen:
Automatically shut down the single EC2 instance, if there have been no requests for the past hour.
Automatically start the instance, when there is an incoming request, i.e. I visit the URL of a service I'm hosting.
I've been able to configure a load balancer to shutdown the instance depending on incoming network traffic. I guess this is ok, if there is no better solution that can filter by IP region or number of incoming connections.
However, I can't figure out how to automatically launch an instance, just by visiting the corresponding URL. Is this even possible?
I could probably write a simple bash script to launch an instance, but I would prefer it to be automated.

Related

AWS ECS Task can't connect to RDS Database

I'm a newer AWS user and today I got stuck while working on a sample project. I successfully created a docker container that runs a simple R script that connects to my AWS RDS MySQL Database and creates & writes some basic files to it. I built a public ECR repository, pushed my docker image there, and built a ECS cluster & task choosing Fargate and using the container image from my repository. My task ran and I could see the R code being executed when I went through the logs, but it was never able to connect to the SQL Database and exited afterwards.
I've had to whitelist my own IP address in the security group for the RDS Database so that I can connect to it, so I'm aware I probably have to do that for my ECS task to establish that connection too. But won't that IP address constantly change because I won't have a static IP for the Fargate Server that is executing my task? I'm trying to stay on the free tier so I'm not sure I want to setup an elastic IP address for this server.
These 2 articles seem close if not the same issue I'm having but I can't figure out a solution. I haven't found any other info.
https://aws.amazon.com/premiumsupport/knowledge-center/ecs-fargate-task-database-connection/
https://aws.amazon.com/premiumsupport/knowledge-center/ecs-fargate-static-elastic-ip-address/
The end goal is to get this sample project successfully running on a scheduled fixed interval, and then running actual scripts on there to help automate things and make my life easier, so this sample project is a first step towards that. Any help or info on the questions I'm having would be appreciated !
Yes, your task is ephemeral (whether you launch it manually or as part of an ECS service) and its private/public ip address may change over time if it gets replaced. The way you'd make the connectivity rules to stick is to assign a security group to the task (that may have inbound access on a specific port you need I assume and outbound to everything) and assign another security group to the RDS db that has inbound access on port 3306 for the security group you assigned to the task (this is the trick, the SG will not change and you are telling RDS to allow access to ALL traffic coming from that SG). I see the first article you posted doesn't talk about this part (it should).

Trigger instance launch on inbound IP traffic on its interface

AWS spot instances are started on pricing decrease, this can happen anytime of the day (or does not happen for many days, depending on the config), i'm looking for a similar way to start an instance when there's a user request, eg. http request/ssh connection ... etc
I'm willing to monitor inbound IP traffic to my elastic IPs (on my internet gateway), and if target instance is stopped then launch it, a kind of wake-on-inbound-traffic.
The monitoring can be in two ways:
Passive: mirror traffic, analyze it in offline with some libpcap-based tool and launch instances based on the capture analysis, the downside is the very early IP requests to that instance will timeout till it start and bootstrap.
Active: analyze inbound traffic inline (using libpcap-based tool as well) and start the target instance, redirect http requests to some "Please wait while warming your instance" till the instance get started.
Anyone thought of doing this ? any guidelines for doing it ?
thanks !

How can I get useful load testing data for my AWS server?

I have a system set up on AWS where I have a set of ec2 insatnces (as an application server from an elastic beanstalk) running in an auto-scaling load-balanced environment. All this works fine.
I would like to load test this instance in order to obtain results that help me to figure out what more needs to be done to the system in order for it to handle, potentially, millions of users. I have used a tool called Locust (http://locust.io) so far to do this. This allows me to send requests to my instance(s?) through a proxy as desired. However, I cannot tell whether the requests are being routed to multiple instances or the same one constantly; and if they are being load balanced appropriately I can't see how many requests each of the ec2 instances are receiving or their health under load. (I have a feeling that the requests are not being properly load balanced as the failure rate always seems to increase drastically at a similar point every test run.)
Is there a way to get this information inside from the AWS ec2 or elastic beanstalk consoles, or is there a better distributed web based load testing tool that can provide the data I need?
There are two ways to get this information
1) Create S3 Bucket and save ELB logs. You can filter these logs to check which instance is serving your request
2) Retrieve application level logs : If apache/nginx installed on your EC2 instances to serve the request. Filter apache/nginx logs in every machine
Hope it helps !!
There is a way to get this data from the AWS console.
Inside the elastic beanstalk console there is a tab titled health. This tab (in the enhanced health overview) shows the number of requests per second, the response for the requests, the latency, the load average and the CPU utilisation for each ec2 instance being run by the elastic beanstalk.
An example of this data is shown in the following image.
This data allows the system manager to see which of their back-end instances are receiving requests and how many they are each being sent through a load-balancer and a proxy.
This can also be attained from the AWS CLI using:
eb health environment_name

Trying to understand how does the AWS scaling work

There is one thing of scaling that I yet do not understand. Assume a simple scenario ELB -> EC2 front-end -> EC2 back-end
When there is high traffic new front-end instances are created, but, how is the connection to the back-end established?
How does the back-end application keep track of which EC2 it is receiving from, so that it can respond to the right end-user?
Moreover, what happen if a connection was established from one of the automatically created instances, and then the traffic is low again and the instance is removed.. the connection to the end-user is lost?
FWIW, the connection between the servers is through WebSocket.
Assuming that, for example, your ec2 'front-ends' are web-servers, and your back-end is a database server, when new front-end instances are spun up they must either be created from a 'gold' AMI that you previously setup with all the required software and configuration information, OR as part of the the machine starting up it must install all of your customizations (either approach is valid). with either approach they will know how to find the back-end server, either by ip address or perhaps a DNS record from the configuration information on the newly started machine.
You don't need to worry about the backend keeping track of the clients - every client talking to the back-end will have an IP address and TCPIP will take care of that handshaking for you.
As far as shutting down instances, you can enable connection draining to make sure existing conversations/connections are not lost:
When Connection Draining is enabled and configured, the process of
deregistering an instance from an Elastic Load Balancer gains an
additional step. For the duration of the configured timeout, the load
balancer will allow existing, in-flight requests made to an instance
to complete, but it will not send any new requests to the instance.
During this time, the API will report the status of the instance as
InService, along with a message stating that “Instance deregistration
currently in progress.” Once the timeout is reached, any remaining
connections will be forcibly closed.
https://aws.amazon.com/blogs/aws/elb-connection-draining-remove-instances-from-service-with-care/

Can I check what instance is currently 'sticked' to the ELB?

I have created a LBCookieStickinessPolicy for my ELB.
But I can't seem to find on any AWS documentation a command that retrieves the instances that are currently 'sticked' (I mean, the actual instance that the ELB is sending load now).
I only find the commands that create the policy itself (create-lb-cookie-stickiness-policy & create-app-cookie-stickiness-policy) ...Any ideas?
Sticky sessions mean that a single user's web browser gets stuck to a single server instance (unless the server goes down or the user clears cookies). The ELB still distributes load across all the servers attached to it. The ELB would distribute multiple users across multiple server instances.
So there is no way to see what you are looking for because the ELB is always using all instances. Now if you just had a single user on your website, you could look at the server logs of each web server to determine which server that user is "stuck" to. In general you would need to look at the web server logs to see which servers are currently receiving traffic.