sebdah / aws-ec2-assign-elastic-ip Goto Github PK
View Code? Open in Web Editor NEWAutomatically assign Elastic IPs to AWS EC2 Auto Scaling Group instances
License: Apache License 2.0
Automatically assign Elastic IPs to AWS EC2 Auto Scaling Group instances
License: Apache License 2.0
Hi,
aws-ec2-assign-elastic-ip has added as a part of boostrap scrip in auto scaling group but it was suddenly not assigning EIP's to the instances after launching. It would be great if you could let me know the resason?
#!/bin/bash
sudo yum install python34-pip -y
sudo pip install aws-ec2-assign-elastic-ip
runuser -l ec2-user -c 'aws-ec2-assign-elastic-ip --valid-ips 9.9.9.9'
The Amazon Linux still runs Python 2.6 and aws-ec2-assign-elastic-ip requires Python 2.7.
Things to fix:
{}
formatting)dictConfig
)I'd like to be able to grab an IP from a pool of IPs. For now this in userdata does the trick for me, but this seems like useful thing for this script to support.
ALLOCATION_ID=`aws ec2 describe-addresses --filters="Name=tag:Name,Values=mail" | jq -r '.Addresses[] | "\(.InstanceId) \(.AllocationId)"' | grep null | awk '{print $2}' | xargs shuf -n1 -e`
if [ ! -z $ALLOCATION_ID ]; then
aws ec2 associate-address --instance-id $INSTANCE_ID --allocation-id $ALLOCATION_ID --allow-reassociation
fi
Hello,
The aws-ec2-assign-elastic-ip
package (installed via pip
) got upgraded in our environment from 0.8.1 to 0.10.2. With that new version, the call to aws-ec2-assign-elastic-ip
fails with
Traceback (most recent call last):
File "/usr/bin/aws-ec2-assign-elastic-ip", line 26, in <module>
import aws_ec2_assign_elastic_ip
File "/usr/lib/python2.7/site-packages/aws_ec2_assign_elastic_ip/__init__.py", line 14, in <module>
from ec2_metadata import ec2_metadata
ImportError: No module named ec2_metadata
Checking with pip freeze
, and indeed the ec2_metadata
package is not installed.
For now we solved by pinning to version 0.8.1.
Relevant packages installed (via pip freeze
):
aws-ec2-assign-elastic-ip==0.10.2
boto3==1.12.36
botocore==1.15.36
$ aws --version
aws-cli/1.18.36 Python/2.7.5 Linux/5.6.2-1.el7.elrepo.x86_64 botocore/1.15.36
Hope this helps!
Add support for instance profile authentication
Loving this, but would like to be able to use the changes in 0.7 when installing via PyPI.
Please could you release 0.7.0 to PyPI?
Hi,
Thanks for building this!
Do you know if a similar script exists to mount an ebs volume to an ec2 node?
I would like to have support for Windows hosts.
Pip installed fine, but I can't figure out what changes to syntax or environment are required to execute in Windows Server 2012 with Python 2.7. Any guidance or assistance is greatly appreciated.
Command that worked under 0.7.1 fails under 8.0:
# /usr/local/bin/aws-ec2-assign-elastic-ip --region us-east-1 --valid-ips A.B.C.D
2018-07-18 15:44:17,610 - aws-ec2-assign-eip - INFO - Connected to AWS EC2 in us-east-1
Traceback (most recent call last):
File "/usr/local/bin/aws-ec2-assign-elastic-ip", line 31, in <module>
aws_ec2_assign_elastic_ip.main()
File "/usr/local/lib/python2.7/dist-packages/aws_ec2_assign_elastic_ip/__init__.py", line 61, in main
address = _get_unassociated_address()
File "/usr/local/lib/python2.7/dist-packages/aws_ec2_assign_elastic_ip/__init__.py", line 137, in _get_unassociated_address
eip = ec2_resource.ClassicAddress(address.get('AllocationId'))
File "/usr/local/lib/python2.7/dist-packages/boto3/resources/factory.py", line 474, in create_resource
client=self.meta.client)(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/boto3/resources/base.py", line 119, in __init__
'Required parameter {0} not set'.format(identifier))
ValueError: Required parameter public_ip not set
Thanks for a handy script -- we've been using it and find it useful.
Alas, the latest version that gets installed via pip is fatally broken -- this was working a few days ago, so I dug in to see what I could find.
This line returns an undefined variable, causing the script to fail. expected_state isn't defined anywhere other than line 171 and 181; in the older versions, line 171 would have returned True and line 181 would have returned False.
Also, once this is fixed, there is another bug: args.invalid_ips will be Null unless the script is called with a value passed in via --invalid-ips. This causes args.invalid_ips to be Null, which causes _is_ip_in_range to return False, which causes _is_valid to return False, which means the entire script fails to assign an elastic IP unless --invalid-ips is specified on the command line.
Traceback (most recent call last):
File "/bin/aws-ec2-assign-elastic-ip", line 31, in
aws_ec2_assign_elastic_ip.main()
File "/usr/lib/python2.7/site-packages/aws_ec2_assign_elastic_ip/init.py", line 60, in main
address = _get_unassociated_address()
File "/usr/lib/python2.7/site-packages/aws_ec2_assign_elastic_ip/init.py", line 127, in _get_unassociated_address
if _is_valid(address.public_ip):
File "/usr/lib/python2.7/site-packages/aws_ec2_assign_elastic_ip/init.py", line 191, in _is_valid
if _is_ip_in_range(address, args.valid_ips):
File "/usr/lib/python2.7/site-packages/aws_ec2_assign_elastic_ip/init.py", line 171, in _is_ip_in_range
return expected_state
NameError: global name 'expected_state' is not defined
Make the script idempotent so that it won't change the EIP every time it is executed.
Implement dry run mode
Any chance you'd add a re-association flag so if the IP was in use on another device, it would gracefully re-associate it?
Python Version : 3.12.0
Collecting aws-ec2-assign-elastic-ip
Downloading aws-ec2-assign-elastic-ip-0.10.2.tar.gz (9.5 kB)
Installing build dependencies ... done
Getting requirements to build wheel ... error
error: subprocess-exited-with-error
× Getting requirements to build wheel did not run successfully.
│ exit code: 1
╰─> [26 lines of output]
Traceback (most recent call last):
File "", line 5, in
ModuleNotFoundError: No module named 'ConfigParser'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Software\Python3.12\Lib\site-packages\pip\_vendor\pyproject_hooks\_in_process\_in_process.py", line 353, in <module>
main()
File "C:\Software\Python3.12\Lib\site-packages\pip\_vendor\pyproject_hooks\_in_process\_in_process.py", line 335, in main
json_out['return_val'] = hook(**hook_input['kwargs'])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Software\Python3.12\Lib\site-packages\pip\_vendor\pyproject_hooks\_in_process\_in_process.py", line 118, in get_requires_for_build_wheel
return hook(config_settings)
^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\SrikumarM\AppData\Local\Temp\pip-build-env-_n6_0loh\overlay\Lib\site-packages\setuptools\build_meta.py", line 325, in get_requires_for_build_wheel
return self._get_build_requires(config_settings, requirements=['wheel'])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\SrikumarM\AppData\Local\Temp\pip-build-env-_n6_0loh\overlay\Lib\site-packages\setuptools\build_meta.py", line 295, in _get_build_requires
self.run_setup()
File "C:\Users\SrikumarM\AppData\Local\Temp\pip-build-env-_n6_0loh\overlay\Lib\site-packages\setuptools\build_meta.py", line 480, in run_setup
super(_BuildMetaLegacyBackend, self).run_setup(setup_script=setup_script)
File "C:\Users\SrikumarM\AppData\Local\Temp\pip-build-env-_n6_0loh\overlay\Lib\site-packages\setuptools\build_meta.py", line 311, in run_setup
exec(code, locals())
File "<string>", line 7, in <module>
ImportError: cannot import name 'SafeConfigParser' from 'configparser' (C:\Software\Python3.12\Lib\configparser.py). Did you mean: 'RawConfigParser'?
[end of output]
note: This error originates from a subprocess, and is likely not a problem with pip.
error: subprocess-exited-with-error
× Getting requirements to build wheel did not run successfully.
│ exit code: 1
╰─> See above for output.
note: This error originates from a subprocess, and is likely not a problem with pip.
Hello sir,
When i use your utility , then i get such type of error . for ex. i used your command aws-ec2-assign-elastic-ip --region us-west-2 --access-key ********************* --secret-key ******************************* --valid-ips 52.26.43.166,54.34.56.12 . and when press enter i get error
Hi,
I'm currently thinking of this tool as a daemon starting and stopping with the instance to handle elastic ip's. This would obsolete any execution of this in the user-data section. Would you be willing to accept a pull-request for this? Maybe with a sysconfig switch to define if it should start as daemon or not?!
greets
The EC2 API for associating EIPs appears to be eventually consistent. So if two servers attempt to grab the same EIP at the same time, one of them will succeed and the other will fail but think it succeeded.
Example logs from this happening, with the IP and instance IDs redacted.
2017-11-27 19:50:02,225 - aws-ec2-assign-eip - INFO - Connected to AWS EC2 in us-west-2
2017-11-27 19:50:02,668 - aws-ec2-assign-eip - INFO - Successfully associated Elastic IP x.x.x.105 with i-a77fbf
2017-11-27 19:50:02,064 - aws-ec2-assign-eip - INFO - Connected to AWS EC2 in us-west-2
2017-11-27 19:50:02,909 - aws-ec2-assign-eip - INFO - Successfully associated Elastic IP x.x.x.105 with i-8d7ed1
In reality, i-8d7ed1
won the race and has the EIP associated, while i-a77fbf
thinks it got the EIP but has no EIP associated.
One way to fix this would be to loop doing the describe-addresses call until the association with the current instance ID appears. Would you be interested in a PR that does this?
Hello,
When we create a NAT Gateway for exemple, the EIP associated to it only has a network interface id, no instance id.
This result that the command try to allocate this EIP to my instance but get a 400 bad request because EIP already associated to NAT gateway.
We should modify the _get_unassociated_address() to manage it because today, it only check if EIP as instance ID
Thanks !
Version 0.8.0 seems to be broken when using the --valid-ips
option, it reports No unassociated Elastic IP found!
(but there is one IP address available).
Workaround: downgrade to 0.7.1
CIDRs or valid IP addresses are now required in the current version, but when you specify a large CIDR address space, we end up iterating through the entire address space:
for cidr_ip in cidr:
ips.append(cidr_ip.format())
For 0.0.0.0/0, this will iterate through 4.2 billiion IP addresses, storing each in memory. It would be much better to test valid IPs against the CIDR, instead of enumerating each CIDR address in an array.
This is an especially an issue as valid-ips or CIDR is now required, and thus to accept previously unknown Elastic IP addresses, a large CIDR address space must be used.
The same error doesn't happen with v0.10.0.
[root@my-aws-instance ~]# aws --version
aws-cli/1.14.28 Python/2.7.5 Linux/3.10.0-957.21.3.el7.x86_64 botocore/1.8.35
[root@my-aws-instance ~]# pip install aws-ec2-assign-elastic-ip==0.10.2
DEPRECATION: Python 2.7 reached the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 is no longer maintained. A future version of pip will drop support for Python 2.7. More details about Python 2 support in pip, can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support
Collecting aws-ec2-assign-elastic-ip==0.10.2
Downloading aws-ec2-assign-elastic-ip-0.10.2.tar.gz (9.5 kB)
Collecting boto3>=1.0.0
Downloading boto3-1.12.37-py2.py3-none-any.whl (128 kB)
|████████████████████████████████| 128 kB 7.9 MB/s
Requirement already satisfied: netaddr>=0.7.12 in /usr/lib/python2.7/site-packages (from aws-ec2-assign-elastic-ip==0.10.2) (0.7.19)
Collecting ec2-metadata>=1.8.0
Downloading ec2_metadata-1.8.0-py2.py3-none-any.whl (7.2 kB)
Collecting botocore<1.16.0,>=1.15.37
Downloading botocore-1.15.37-py2.py3-none-any.whl (6.1 MB)
|████████████████████████████████| 6.1 MB 123.4 MB/s
Collecting s3transfer<0.4.0,>=0.3.0
Downloading s3transfer-0.3.3-py2.py3-none-any.whl (69 kB)
|████████████████████████████████| 69 kB 22.0 MB/s
Collecting jmespath<1.0.0,>=0.7.1
Downloading jmespath-0.9.5-py2.py3-none-any.whl (24 kB)
Collecting cached-property
Downloading cached_property-1.5.1-py2.py3-none-any.whl (6.0 kB)
Requirement already satisfied: requests in /usr/lib/python2.7/site-packages (from ec2-metadata>=1.8.0->aws-ec2-assign-elastic-ip==0.10.2) (2.23.0)
Requirement already satisfied: urllib3<1.26,>=1.20; python_version != "3.4" in /usr/lib/python2.7/site-packages (from botocore<1.16.0,>=1.15.37->boto3>=1.0.0->aws-ec2-assign-elastic-ip==0.10.2) (1.25.8)
Requirement already satisfied: docutils<0.16,>=0.10 in /usr/lib/python2.7/site-packages (from botocore<1.16.0,>=1.15.37->boto3>=1.0.0->aws-ec2-assign-elastic-ip==0.10.2) (0.11)
Collecting python-dateutil<3.0.0,>=2.1
Downloading python_dateutil-2.8.1-py2.py3-none-any.whl (227 kB)
|████████████████████████████████| 227 kB 127.2 MB/s
Requirement already satisfied: futures<4.0.0,>=2.2.0; python_version == "2.7" in /usr/lib/python2.7/site-packages (from s3transfer<0.4.0,>=0.3.0->boto3>=1.0.0->aws-ec2-assign-elastic-ip==0.10.2) (3.3.0)
Requirement already satisfied: idna<3,>=2.5 in /usr/lib/python2.7/site-packages (from requests->ec2-metadata>=1.8.0->aws-ec2-assign-elastic-ip==0.10.2) (2.9)
Requirement already satisfied: chardet<4,>=3.0.2 in /usr/lib/python2.7/site-packages (from requests->ec2-metadata>=1.8.0->aws-ec2-assign-elastic-ip==0.10.2) (3.0.4)
Requirement already satisfied: certifi>=2017.4.17 in /usr/lib/python2.7/site-packages (from requests->ec2-metadata>=1.8.0->aws-ec2-assign-elastic-ip==0.10.2) (2019.11.28)
Requirement already satisfied: six>=1.5 in /usr/lib/python2.7/site-packages (from python-dateutil<3.0.0,>=2.1->botocore<1.16.0,>=1.15.37->boto3>=1.0.0->aws-ec2-assign-elastic-ip==0.10.2) (1.14.0)
ERROR: awscli 1.14.28 requires colorama<=0.3.7,>=0.2.5, which is not installed.
ERROR: awscli 1.14.28 has requirement botocore==1.8.32, but you'll have botocore 1.15.37 which is incompatible.
ERROR: awscli 1.14.28 has requirement rsa<=3.5.0,>=3.1.2, but you'll have rsa 4.0 which is incompatible.
ERROR: awscli 1.14.28 has requirement s3transfer<0.2.0,>=0.1.12, but you'll have s3transfer 0.3.3 which is incompatible.
Installing collected packages: jmespath, python-dateutil, botocore, s3transfer, boto3, cached-property, ec2-metadata, aws-ec2-assign-elastic-ip
Attempting uninstall: python-dateutil
Found existing installation: python-dateutil 1.5
Uninstalling python-dateutil-1.5:
Successfully uninstalled python-dateutil-1.5
Attempting uninstall: s3transfer
Found existing installation: s3transfer 0.1.13
Uninstalling s3transfer-0.1.13:
Successfully uninstalled s3transfer-0.1.13
Attempting uninstall: aws-ec2-assign-elastic-ip
Found existing installation: aws-ec2-assign-elastic-ip 0.8.1
Uninstalling aws-ec2-assign-elastic-ip-0.8.1:
Successfully uninstalled aws-ec2-assign-elastic-ip-0.8.1
Running setup.py install for aws-ec2-assign-elastic-ip ... done
Successfully installed aws-ec2-assign-elastic-ip-0.10.2 boto3-1.12.37 botocore-1.15.37 cached-property-1.5.1 ec2-metadata-1.8.0 jmespath-0.9.5 python-dateutil-2.8.1 s3transfer-0.3.3
[root@my-aws-instance ~]# aws --help
Traceback (most recent call last):
File "/usr/bin/aws", line 27, in <module>
sys.exit(main())
File "/usr/bin/aws", line 23, in main
return awscli.clidriver.main()
File "/usr/lib/python2.7/site-packages/awscli/clidriver.py", line 59, in main
driver = create_clidriver()
File "/usr/lib/python2.7/site-packages/awscli/clidriver.py", line 70, in create_clidriver
event_hooks=emitter)
File "/usr/lib/python2.7/site-packages/awscli/plugin.py", line 46, in load_plugins
modules = _import_plugins(plugin_mapping)
File "/usr/lib/python2.7/site-packages/awscli/plugin.py", line 63, in _import_plugins
module = __import__(path, fromlist=[module])
File "/usr/lib/python2.7/site-packages/awscli/handlers.py", line 27, in <module>
from awscli.customizations.cloudformation import initialize as cloudformation_init
File "/usr/lib/python2.7/site-packages/awscli/customizations/cloudformation/__init__.py", line 13, in <module>
from awscli.customizations.cloudformation.package import PackageCommand
File "/usr/lib/python2.7/site-packages/awscli/customizations/cloudformation/package.py", line 27, in <module>
from awscli.customizations.s3uploader import S3Uploader
File "/usr/lib/python2.7/site-packages/awscli/customizations/s3uploader.py", line 23, in <module>
from s3transfer.manager import TransferManager
File "/usr/lib/python2.7/site-packages/s3transfer/manager.py", line 21, in <module>
from s3transfer.utils import get_callbacks
File "/usr/lib/python2.7/site-packages/s3transfer/utils.py", line 27, in <module>
from botocore.exceptions import ReadTimeoutError
ImportError: cannot import name ReadTimeoutError
[root@my-aws-instance ~]#
Feature request: There are several use cases where it is desirable that a newly launched instance can be guaranteed to have/steal an address from a pool of existing addresses that may all be attached. Our use cases is rolling docker deployments. #15 is similar.
A flag like "disassociate_first" that will simply perform a disassociate call on the elastic IP
http://docs.aws.amazon.com/cli/latest/reference/ec2/disassociate-address.html
before trying to acquire the address would seemingly solve our problem. If the flag is false by default it shouldn't be an issue to any existing users.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.