Auto Scaling, Elastic IP - amazon-web-services

When I use Network Load Balancer with Auto Scaling, everytime an instance is spawned it gets a new public IP.
I would like to have an EIP for each instance. I was hoping that when I assigned an EIP to availability zones in the Network Loadbalancer configuration would do the trick.
Is there a a way to have autoscale and static IPs for the instances spawned?
https://aws.amazon.com/blogs/aws/new-network-load-balancer-effortless-scaling-to-millions-of-requests-per-second/
According to this it looks it's not possible:
Unfortunately, there is no way to make autoscaling automatically
assign an Elastic IP address to newly launched instances
Static IP for Auto Scale in AWS
and according to this:
Assigning static IPs to auto scaled EC2 instance

Write a script and put it on your startup script in launch configuration for your autoscale group, that script can do anything you want, range from assigning the new EIP to check other services for the white/blacklist.
For more info read
https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/user-data.html

As others have mentioned this can be accomplished by provisioning new EIP and using UserData to associate the instance with newly issued EIP. However, following setup would have the following issues:
1) EIP have limits by default its 5 per VPC, and even you can increase the limit you need to know the maximum number of EIP your VPC will use
2) When instance gets terminated you will need to create a process to delete staled EIP or figure out how to reassociated previously allocated EIP
Having said that I do use a static EIP in my ASG but its only for HA rather than scalability, so in the following example I'm reusing existing EIP each time I launch a new instance
#!/bin/bash -xe
INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
aws ec2 disassociate-address --association-id ${OpenPVNEIP.AllocationId} --region ${AWS::Region} || true
aws ec2 associate-address --instance-id "${!INSTANCE_ID}" --allocation-id ${OpenPVNEIP.AllocationId} --region ${AWS::Region}

I created a Lambda inside a private subnet.
I linked the private subnet to a NAT Gateway and thus I managed to get a static IP for my Lambda. The limit of 5 EIPs was an issue for me.
https://aws.amazon.com/premiumsupport/knowledge-center/internet-access-lambda-function/

With EC2 & Auto scaling, You need using user data in EC2 to Auto Attach Elastic IP to EC2 Instance For Auto scaling
#!/bin/bash
aws configure set aws_access_key_id "XYZ..."
aws configure set aws_secret_access_key "ABC..."
aws configure set region "ap-..."
aws ec2 associate-address --instance-id "$(curl -X GET "http://169.254.169.254/latest/meta-data/instance-id")" --public-ip your_elastic_IP
Note: you should create new user & IAM have only permission associate-address to create/get aws key
Hope it be help you :)

Related

how to allocate elastip ip to autoscaling group with 1 instance

I have 1 instance in auto scaling group with min = 1 max = 1 and desired = 1
I also have an elastic ip which i want to assign single instance and also when this once instance goes down, the elastic ip should be released and allocated to the new instance. I have attached admin policy with the role which is attached in the launch configuration for ASG. I have added below information in user data in launch template but my elastic ip is still not getting associated with new instance. I really need help with this please
#!/bin/bash
InstanceID=`/usr/bin/curl -s http://169.254.169.254/latest/meta-data/instance-id`
Allocate_ID= 'eipalloc-0d54643260cd69141'
aws ec2 associate-address --instance-id $InstanceID --allocation-id $Allocate_ID
You'll need to disassociate the address from the instance to which the EIP is attached to before associating it again.
This will do the job:
#!/bin/bash
ALLOCATE_ID="eipalloc-0d54643260cd69141"
# Release the EIP if it is currently associated with an instance
aws ec2 disassociate-address --association-id "$ALLOCATE_ID" || true
# Associate address to this instance
INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
aws ec2 associate-address --instance-id "$INSTANCE_ID" --allocation-id "$ALLOCATE_ID"

Is it possible to schedule a startup of an AWS instance from within the instance?

I have an AWS instance that does some network data collection when it boots up. It's important that the collection happen from a fresh public IP address -- I can't get useful data by running the collection again on the same address.
Right now, I can stop and then restart the instance in the EC2 console, and when it restarts, it gets a new IP address and collects more useful data. (Just rebooting the instance doesn't assign a new IP -- I have to stop and then start.)
I know about time-based instance start scheduling, but what I'd like to do instead is schedule a restart from within the instance itself. Sort of like an at job: at now + 5 minutes restart-this-instance ; shutdown -h now.
Alternatively, if there's a way to release and reallocate an instance's public IP, that would work too.
No, this is not possible.
The command to Start the instance needs to be issued when the instance is Stopped. Therefore, the instance cannot issue the command to start itself.
It could, however, trigger something external to cause it to happen, such as creating a CloudWatch Rule or a Lambda function.
I suggest another approach...
The goal is to change Public IP address to measure how caching and repeat traffic from previously-seen IP addresses affects the measured performance of the main system.
Therefore, I would recommend:
Have an Elastic IP address associated with the instance
When a new IP address is desired:
Disassociate the Elastic IP address
Release the Elastic IP address
Allocate a new Elastic IP address
Associate the new Elastic IP address with the instance
You can use this script:
INSTANCE=`curl -s http://169.254.169.254/latest/meta-data/instance-id/`
ALLOC=`aws ec2 describe-addresses --filters Name=instance-id,Values=$INSTANCE --query Addresses[].AllocationId --output text`
aws ec2 release-address --allocation-id $ALLOC
NEW=`aws ec2 allocate-address --domain vpc --query AllocationId --output text`
aws ec2 associate-address --allocation-id $NEW --instance-id $INSTANCE

EC2 auto scaling with elastic IP

I have deployed an auto scaling EC2 and has associated an Elastic IP address with it. I'm not using a load balancer, because the total number of users doesn't exceed 20. Therefore, my current settings are to have 1 minimum and 1 maximum servers.
If the EC2 server fails, another one is created instead, which is what i'm trying to do. However, the elastic IP is not automatically remapped to the newly created server.
How can i assign the elastic IP automatically to the newly created EC2 instance? Is there a workaround this issue?
UPDATE:
I've added the following to User Data, but the new EC2 is created without a public ip still.
#!/bin/bash
INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
aws ec2 associate-address --instance-id $INSTANCE_ID --allocation-id=eipalloc-**.***.***.***
Without an ELB to manage your Elastic IPs, you'll need to use the User Data field on your EC2 instance to call the aws ec2 associate-address API endpoint upon instance creation:
aws ec2 associate-address --instance-id <instance id> --allocation-id <eip-alloc-id>
The EIP allocation ID can be found using the AWS Console. You can obtain the Instance ID by making this call in the User Data:
INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
With EC2 & Auto scaling, You need using user data in EC2 to Auto Attach Elastic IP to EC2 Instance For Auto scaling
#!/bin/bash
aws configure set aws_access_key_id "XYZ..."
aws configure set aws_secret_access_key "ABC..."
aws configure set region "ap-..."
aws ec2 associate-address --instance-id "$(curl -X GET "http://169.254.169.254/latest/meta-data/instance-id")" --public-ip your_elastic_IP
Note: you should create new user & IAM have only permission associate-address to create/get aws key
Hope it be help you :)

What is the best way to get the private IP addresses of other ec2's in an autoscaling group while on one of the ec2 instances?

I need to update a config file in a shared EFS drive with all of the private IP addresses of the current autoscaling group.
The approach I'm thinking is to run a user data script that queries the ASG for the private IP addresses then echo that into the config file. To do that the ec2 needs to have AWS CLI credentials and appropriate read-only access. Ideally, I don't want to store any credentials on this ec2.
Is there another way? Possibly VPC Endpoint or something?
Thanks!
You are asking two questions.
How do I provide credentials securely to an EC2 instance?
You use IAM Roles and assign the role to your EC2 instances. Then use the instance credentials in your code. The CLI examples below will automatically pick up these credentials.
Using an IAM Role to Grant Permissions to Applications Running on Amazon EC2 Instances
How do I get the private IP address of EC2 instances in an Auto Scaling Group (ASG)?
You need to get a list of instances attached to your ASG.
For each instance in your ASG call the describe API and extract the private IP address.
Example commands:
aws autoscaling describe-auto-scaling-groups --auto-scaling-group-name my-auto-scaling-group
aws ec2 describe-instances --instance-ids i-1234567890abcdef0
You can filter the command output. For example add the following to the second command to just display the private IP address:
--query 'Reservations[*].Instances[*].PrivateIpAddress'
Recommendation:
I would use the Python SDK and write a simple program that provides these features and updates your config file.

How to attach Elastic IP to EC2 instance during bootstrapping in aws CLI?

I can able to create an instace with follwoing command
aws ec2 run-instances --image-id $AMI_ID --count 1 --instance-type ${INSTANCE_TYPE} --key-name KEY_NAME --region us-east-1 --security-groups MYSECURITY_GROUP
But I did not find any option to attach elastic IP address to it. Is it possible to attach a Elastic IP during bootstrapping? Or post bootstrapping?
You can use --user-data (string) option to run-instances. The user data that you pass will contain the CLI to associate the elastic IP. The CLI command is given below. To get the instance-id in user data, use the metadata server:
curl instance-data/latest/meta-data/instance-id
You can also attach an elastic IP after you launch. Use associate-address to attach an elastic IP.
More examples in: associate-address
This example uses the new style (longer) instance id.
aws ec2 associate-address --instance-id i-0b263919b6498b123 --allocation-id eipalloc-64d5890a
You can get the allocation id from
aws ec2 describe-addresses
describe-addresses
The desire I read in the question is "how to start an instance with a given known IP address (from an elastic IP pool,) without first starting it with another temporary IP address."
The way to do this that I've found, is to first allocate a NetworkInterface, and then allocate the IP address, and then bind the IP address to the NetworkInterface, and then bind the pre-allocated NetworkInterface to the eth0 interface as part of the NetworkInterface launch parameters. Yup, four steps, just because you want your instance to start out with an IP address that won't change for the duration of its lifetime!
For "infrastructure as cattle" behind a NAT/load balancer of some sort, this doesn't matter of course. But for "cloud developer hosts" that you SSH to or "open remote" to from your IDE, keeping the IP address the same all the way from the beginning is a pretty important requirement.