Re-associate another IP to a running instance? - amazon-web-services

I have a complicated use case for this ,
But for short , while an instance is running, can I switch the elastic IP to another one ? and what will happen in this time interval (between de-associating , and re-associating [might be 10-30 minutes] ) .. Won't it be able to communicate over the internet ?
EDIT:
Great answers so far, but this answers the second part of the question, the main one is , how to change the IP while it is running?

All of your questions are more or less addressed in the Feature Guide: Amazon EC2 Elastic IP Addresses, e.g:
While an instance is running, can I switch the elastic IP to another one?
Of course, that's one of the main use cases for Elastic IP addresses:
Unlike a standard EC2 Public IP Address, Elastic IP Addresses are allocated to accounts and can be remapped to other instances when
desired. [This includes running instances, see "How to change the Elastic IP Address of a running EC2 instance" below.]
What will happen in this time interval (between de-associating, and re-associating [might be 10-30 minutes])?
That'd be longer than advertized, see the FAQ How long
does it take to remap an Elastic IP address?:
In most cases, this
will typically take less than a few minutes from when you instruct us
to remap the Elastic IP, and we are continuing to work to make this
even faster. [I've actually not experienced this process taking
longer than a minute myself]
Won't it be able to communicate over the internet?
That depends on the scenario at hand, but as a simplification you should probably work with this assumption, as per the following two FAQs:
If an Elastic IP is removed from an instance is the instance reachable from the internet?
Removing the Elastic IP from an instance temporarily leaves the
instance without a Public IP Address. A background process in the
cloud will re-assign a new Public IP to the instance after a short
period of time. The instance will remain reachable from within the
cloud on its private IP address during this process.
Why do existing connections still work after I associate a new IP address to an instance?
When you remap an Elastic IP to an instance, some of your preexisting
communications (to the old and now unmapped IP address) will continue
to work even after the remap. For example, if you have an open ssh
connection to an instance via its system assigned Public IP address
and subsequently associate one of your Elastic IP addresses with that
instance, the ssh session might continue to function normally for
some time. This behavior is expected but unreliable. We strongly urge
you to reestablish connections via the new remapped IP addresses to
ensure that your software functions correctly.
How to change the Elastic IP Address of a running EC2 instance
The answer to your follow up question is embedded/implied in the aforementioned guide as well, but addressed in more detail in chapter Elastic IP Addresses (EIP), specifically in sections Associating an Elastic IP Address with a Running Instance in Amazon EC2 and Associating an Elastic IP Address with a Different Running Instance in Amazon EC2:
Basically this is performed via the EC2 API action AssociateAddress, which is facilitated by either the AWS Management Console or the Amazon EC2 API Tools in turn (specifically ec2-associate-address), as outlined in the aforementioned sections.
Please refer to the EC2 IP Information FAQ for even more details regarding the subject matter.

Elastic IPs are assigned using NAT. Your instance has an internal IP that is NATed to the Elastic IP. While an instance has no Elastic IP associated it will have an arbitrary IP from a pool and thus will still be able to communicate with the internet (given that access rules are properly configured).

I created this bash script to change the public ip (eip) of a running instance in a VPC. You just provide the name you gave that instance (TAG Name="") so it will convert the Name Tag into the instance ID. Changing your public DNS will always take time. Changing the EIP address in the aws gui is annoying. Dissasociate old ip, Get New IP, Associate New IP, Release Old IP. Mouse clicks stink.
#change vpc instance public IP address (EIP -> NIC|INSTANCE)
#usage "changeip [instance friendly tag=Name] [region]"
#example "changeip my.instnace us-west-1"
#dafault region is us-west-1 (you must include --region for $region default)
#for VPC instances only
function changeip {
if [[ ! $1 ]]; then
echo 'Error : You must provide tag name for instance'
echo 'Example: changeip [friendly name]'
return
fi
if [[ $2 ]]; then
region='--region '$2
echo 'Using region '$2
else
region='--region us-west-1' #sets default region
echo 'Using default '$region
fi
name=$1
instance=$(ec2-describe-instances $region | grep Name | grep $name | cut -f3)
if [[ ! $instance =~ ^('i-'[A-Za-z0-9]*)$ ]]; then
echo 'Error : Getting the instance id'
echo $instance
return
fi
echo 'Applying to '$1 '=> '$instance
echo 'Please wait....'
ip_new=$(ec2-allocate-address $region -d vpc | cut -f2)
if [[ ! $ip_new =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
echo 'Error : Getting a new IP address'
echo $ip_new
return
fi
new_idas=$(ec2-describe-addresses $region $ip_new | cut -f 5) >> /dev/null
if [[ ! $new_idas =~ ^('eipalloc-'[A-Za-z0-9]*)$ ]]; then
echo 'Error : Getting New IP allocation id eipalloc'
echo $new_idas
return
fi
ip_old=$(ec2-describe-addresses $region | grep $instance | cut -f2)
if [[ ! $ip_old =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
echo 'Error : Getting old IP address'
echo $ip_old
return
fi
id_dis=$(ec2-describe-addresses $region $ip_old | cut -f 6)
if [[ ! $id_dis =~ ^('eipassoc-'[A-Za-z0-9]*)$ ]]; then
echo 'Error : Dissasociating Old IP'
echo $id_dis
return
fi
id_release=$(ec2-describe-addresses $region $ip_old | cut -f 5) >> /dev/null
if [[ ! $new_idas =~ ^('eipalloc-'[A-Za-z0-9]*)$ ]]; then
echo 'Error : Release Old IP'
echo $id_release
return
fi
ec2-disassociate-address $region -a $id_dis >> /dev/null
sleep 8
ec2-release-address $region -a $id_release >> /dev/null
ec2-associate-address $region -i $instance -a $new_idas >> /dev/null
echo 'SUCCESS!'
echo 'Old = '$ip_old
echo 'New = '$ip_new
}

You can always use Public DNS name to access the system.
No problem to communicate over internet.
do a curl from the instance to know private / public addresses to use
http : // 169 . 254. 169. 254/latest/meta-data/local-ipv4
http : // 169. 254. 169. 254/latest/meta-data/public-ipv4
Refer : http://docs.amazonwebservices.com/AWSEC2/latest/UserGuide/AESDG-chapter-instancedata.html

Yes: you can change the IP address of a running instance. Just associate a second elastic IP address with the instance and it will replace the existing one.

Related

Does Google Cloud provide public hostnames for their Compute instances?

Does Google Cloud provide public hostnames for their Compute instances?
AWS seems to generate public hostnames for their EC2 instances:
A public (external) DNS hostname takes the form ec2-public-ipv4-address.compute-1.amazonaws.com for the us-east-1 region, and ec2-public-ipv4-address.region.compute.amazonaws.com for other regions. We resolve a public DNS hostname to the public IPv4 address of the instance outside the network of the instance...
Similar question:
This seems like a similar question but (1) setting up a DNS seems like an overkill, (2) seems like I'll need to do some sort of thing outside of Google Cloud anyway or it isn't public (not sure), and (3) it could be outdated (2014).
No, GCE doesn't offer hostnames for an instance. It does assign external IP addresses for each instance. Associating a DNS record with your instance is the only method to generate a hostname.
GCE does have built in private hostnames, inside the same network. For example two instances in the same VPC can ping each other by name
Instance 'test-instance': start server on :8080
Instance 'second-instance': curl test-instance:8080
// Response 'Hello World'
No. Source: FridayPush's answer (thanks! from his profile, seems worthy of trust for Google-Cloud things :-)).
The reason I wrote a separate answer is to make it clear that you can't have a public hostname totally through Google Cloud. You can either have an internal hostname totally through Google Cloud, or you'll need to do something outside of Google Cloud (e.g., own a domain name) to have a public hostname.
GCE instances don't currently have a public DNS name for their external IP address. But there is now a gcloud compute config-ssh (docs) command that's a pretty good substitute.
This will insert Host blocks into your ~/.ssh/config file that contain the IP address and configuration for the host key.
Although this only helps with SSH (and SSH-based applications like Mosh and git+ssh), it does have a few advantages over DNS:
There is no caching/propagation delay as you might have with DNS
It pre-populates the right host key, and the host key is checked the right way even if the ephemeral IP address changes.
Example:
$ gcloud compute config-ssh
...
$ ssh myhost.us-west1-b.surly-koala-232
If your GCP instance has an external IP, ephemeral or static, then that IP address has public DNS entry that you can easily get with a reverse DNS lookup.
Example:
# get your external IP
$ curl icanhazip.com
34.88.81.150
# do a reverse DNS lookup
$ dig +short -x 34.88.81.150
150.81.88.34.bc.googleusercontent.com.
A one-liner to get that public DNS entry:
# (sed removes the trailing dot)
$ dig +short -x $(curl -s icanhazip.com) | sed "s/.$//"
150.81.88.34.bc.googleusercontent.com

How to assign multiple public IPs to an AWS EC2 instance?

I have an m4.4xlarge instance to which I initially assigned an Elastic IP. The security group of this instance allows SSH access and also allows access to the web app on port 8000.
Now I clicked on the EC2 instance, chose: Actions > Networking > Manage IP addresses. And then I assigned a new private IP.
Then I created a new Elastic IP address and mapped it to the newly assigned private IP of the network interface. Now I can see in the EC2 instance description that Elastic IPs is showing both old and new Elastic IP. But the IPv4 Public IP field is still showing the old IP address only.
While I am still able to SSH to the instance using the old Elastic IP, I am not able to do so using the new Elastic IP. Also, I am not able to access the web app on port 8000 using new Elastic IP. How can I accomplish this ?
Here is the script I wrote for making it work with additional network interface and making the change persistent on RHEL/Centos -
#!/bin/bash
# On AWS With multiple network cards with the default route tables the outbound public traffic keeps going out via the default interface
# This can be tested by running tcpdump on default interface and then sending a ping to the 2nd interface
# The second address will try to send return traffic via the 1st interface
# To fix this need to create a rule to direct traffic from second address through the 2nd network interface card
# Also creating a systemd service that will create the rules and routes on boot and also
# adding to the network.service so the script is also called when starting network
# User inputs
INTERFACE1="eth0"
INTERFACE2="eth1"
IP1=10.0.0.70/32
IP2=10.0.5.179/32
ROUTER1=10.0.0.1
ROUTER2=10.0.5.1
# End of user inputs
if [[ $EUID != "0" ]]
then
echo "ERROR. You need root privileges to run this script"
exit 1
fi
# Create the file that will be called by the systemd service
rm -rf /usr/local/src/routes.sh
cat << EOF > /usr/local/src/routes.sh
#!/bin/bash
# Adding the routes for the 2nd network interface to work correctly
ip route flush tab 1 >/dev/null 2>&1
ip route flush tab 2 >/dev/null 2>&1
ip rule del priority 500 >/dev/null 2>&1
ip rule del priority 600 >/dev/null 2>&1
ip route add default via $ROUTER1 dev $INTERFACE1 tab 1
ip route add default via $ROUTER2 dev $INTERFACE2 tab 2
ip rule add from $IP1 tab 1 priority 500
ip rule add from $IP2 tab 2 priority 600
EOF
chmod a+x /usr/local/src/routes.sh
# End of file with new routes and rules
# Create a new systemd service
rm -rf /etc/systemd/system/multiple-nic.service
cat << EOF > /etc/systemd/system/multiple-nic.service
[Unit]
Description=Configure routing for multiple network interface cards
After=network-online.target network.service
[Service]
ExecStart=/usr/local/src/routes.sh
[Install]
WantedBy=network-online.target network.service
EOF
# End of new systemd service
echo "New systemd service - multiple-nic.service created"
systemctl enable multiple-nic.service
systemctl restart network
echo "Network restarted successfully"
You need config second IP addr in your OS, for example CentOS,if the primary network interface is eth0, then you need add eth0:1 as following:
sudo vi /etc/sysconfig/network-scripts/ifcfg-eth0:1
DEVICE=eth0:1
Type=Ethernet
ONBOOT=yes
NM_CONTROLLED=no
BOOTPROTO=none
IPADDR=10.0.0.30
PREFIX=24
Then, reboot your EC2 instance, eg. sudo reboot.

Unable to access EC2 instance

I am using AWS and i created Auto scaling launch configuration using shell Script:
#!/bin/sh
curl -L https://us-west-2-aws-training.s3.amazonaws.com/awsu-spl/spl03-working-elb/static/bootstrap-elb.sh | sh
After creating this and the load balancer, two instances were created. I then copied the DNS Name and pasted it in browser, but it says:
This site can’t be reached
internal-elb-asg-167368762.us-east-1.elb.amazonaws.com took too long to respond.
Go to http://amazonaws.com/
Search Google for internal elb asg 167368762 east amazonaws
ERR_CONNECTION_TIMED_OUT
EDIT
I followed your steps and it failed.
You have to change this part of the User Data:
#!/bin/sh curl -L https://us-west-2-aws-training.s3.amazonaws.com/awsu-spl/spl03-working-elb/static/bootstrap-elb.sh | sh
With this:
#!/bin/sh
curl -L https://us-west-2-aws-training.s3.amazonaws.com/awsu-spl/spl03-working-elb/static/bootstrap-elb.sh | sh
Edit: As #john-rotenstein mentioned is not necessary to use sudo.
Also, check this:
You have the correct security groups on EC2 and with your ELB.
Check if you are listening to the port 80 in you ELB.
The port 80 must be opened in your EC2 security group to your ELB security group and the port 80 must be opened worldwide (0.0.0.0) in your ELB security group.
Finally, are you sure that you are not using an internal load balancer right?
Hope it helps you.

Setting up username/password authentication with EC2 for mongodb on port 27017

I currently have an EC2 instance that I am using to host my mongodb sever on from port 27017. Previously I had just setup the security group to just use my home IP address to authenticate a TCP connection to port 27017, however I no longer have a static IP. I now have one that changes everyday that I cannot control. Is there a way to create a mongo URI like mongolabs has
mongodb://<username><passs>#<my EC2 IP>:27017/db
that I can use to connect from PyMongo.
There are many, many guides available by searching that describe how to enable MongoDB authentication.
Alternatively, you could create a small script that uses the AWS CLI to update the security group with your current IP address. The script could be run when needed or set to run automatically your computer starts or you log in.
Install AWS CLI on your machine. You should have proper IAM permissions to update the security group. Then you can use below bash script to update your security group with your current IP address.
#!/bin/bash
ip = 'curl -s http://whatismijnip.nl |cut -d " " -f 5'
sleep 5
aws ec2 authorize-security-group-ingress --group-name MySecurityGroup --protocol tcp --port 22 --cidr $ip/24

amazon: assign elastic ip in VPC automatically

I have a VPC. Now I have a script which creates ec2-instances and configures them. The configuration is dependent of the public IP during the installation. The problem is that the configuration is wrong for my instance after rebooting it. Because the public ip changed but the config contains the old public IP. Is there a way to define an automatic allocation of an Elastic IP to instances in a specific VPC? (assign an elastic ip immediatley after the creation)
I usually set the Elastic IP from within the EC2 instance, instead of from whatever created the instance to begin with, with userdata, though I don't see why you can't do the same thing from an external script.
Here is my script that I pass in to userdata when launching an application.
Note, this script relies on variables created by other (parent) scripts
e.g.:
REGION = a string holding the region you launched the instance into
RESOURCE_ID = a string holding the ID of the newly launched instance
IP = a string holding the original public IP address
You should be able to get those variables within the response from the initial launch.
You will need to create additional functionality and this assumes you already have launched the instance, however this should get you mostly there.
Note, there is no need to reboot the instance in-between launching and assigning the elastic IP address. In fact, doing so might, as you mentioned, "lose" the public IP address (though I BELIEVE that a simple reboot from the console holds on to the public IP).
#!/bin/bash
EIPID=`aws ec2 allocate-address --domain vpc --region ${REGION} | grep -m 1 'AllocationId' | awk -F : '{print $2}' | sed 's|^ "||' | sed 's|"||'`
IP=`ec2metadata --public-ipv4`
EIP=${IP}
if [ -n "$EIPID" ]
then
conf=`aws ec2 associate-address --instance-id ${RESOURCE_ID} --allocation-id ${EIPID} --region ${REGION} | grep -m 1 'AssociationId' | awk -F : '{print $2}' | sed 's|^ "||' | sed 's|"||'`
if [ -n "$conf" ]
then
while [ "$IP" == "$EIP" ]
do
EIP=`ec2metadata --public-ipv4`
sleep 2
done
echo "Elastic IP ${EIPID} successfully mapped";
echo "ELASTIC_IP=\"${EIP}\"" | sudo tee -a /etc/environment
else
echo "Failed to map Elastic IP Address: ${EIPID}";
fi
else
echo "Failed to acquire Elastic IP address: ${EIPID}";
fi
There is no features inside VPC to make EIP automatic attach to EC2 instance.
You need to use the AWS API language you are familiar with to write own script to do your own automation.
1) Preparation:
Allocate an elastic IP, write down the EIP-id
2) Associate EIP-id to EC2 IP allocation work :
Use AWS API script to create and launch your EC2 instance, capture the EC2-instance ID (or the Instance interface ID) .
Then in the same script, use the API ec2 associate-address(naming is vary slight depends on the AWS API language you use) to attach EIP-id to the EC2 isntance ID(or instance Interface ID)
If you are using API, you may actually use "ec2 describe_addresse" to dynamically find the idle EIP-id that not associated to any instance.
And you need to think ahead of the automation if you want to stop the EC2 from time to time and relaunch them : EC2 Instances will not keep elastic IP
There are two methods
1) use a the API method that is exposed in the aws ec2 associate-address, see http://docs.aws.amazon.com/cli/latest/reference/ec2/associate-address.html
2) use cloudformation instead of a script see http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/quickref-ec2.html#scenario-ec2-eip
As answered by mootmoot I would say there is no features inside VPC to make an EIP automatic attach to a specific EC2 instance. In addition, stopping the instance also disassociates the EIP from it. So EC2 Instances will not keep elastic IP.
There is an option that does not require an Elastic IP.to be assigned by using a service called DynamicURL that change IP Address on A of your domain follow to the Public IP that is assigned to your instance. So whenever the IP is changed your domain is keep associated with your instance.