I'm scripting some stuff with aws ec2 describe-addresses, but, for some reason, some instances won't be returned by it.
Example:
$ aws ec2 describe-addresses --filter=Name=instance-id,Values=i-xxxxx
{
"Addresses": []
}
The given instanceId is valid and has addresses, but it just won't be shown by aws cli.
However, for another instances it seems to work just fine:
$ aws ec2 describe-addresses --filter='Name=instance-id,Values=i-yyyyyy'
{
"Addresses": [
{
"PrivateIpAddress": "X.X.X.X",
"InstanceId": "i-yyyyyy",
"NetworkInterfaceOwnerId": "XXXXXXXXXX",
"Domain": "vpc",
"AllocationId": "eipalloc-xxxxxx",
"PublicIp": "Y.Y.Y.Y",
"NetworkInterfaceId": "eni-xxxxxx",
"AssociationId": "eipassoc-xxxxx"
}
]
}
The keys I'm using have EC2FullAccess policy, so, it doesn't seem to be related to security...
What am I doing wrong? Any tips? Is there any limitations of aws cli that I'm not aware of?
I think the reason is you are not listing the instances, actually listing the Elastic IP Addresses. Probably the missing ones are the ones without Elastic IPs.
So for example the command without the filter will list the EIP list
aws ec2 describe-addresses
Output:
{
"Addresses": [
{
"InstanceId": null,
"PublicIp": "198.51.100.0",
"Domain": "standard"
},
{
"PublicIp": "203.0.113.0",
"Domain": "vpc",
"AllocationId": "eipalloc-64d5890a"
}
]
}
Source: http://docs.aws.amazon.com/cli/latest/reference/ec2/describe-addresses.html
Related
I want to query all VPCs belonging to a particular region in my Go-based microservice.
https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeVpcs.html indicates that there exists no filter option by region or any other request parameter.
Golang SDK reference document:
https://docs.aws.amazon.com/sdk-for-go/api/service/ec2/#EC2.DescribeVpcs
Command line SDK reference document: https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-vpcs.html
Here's an example.
{
"Vpcs": [
{
"CidrBlock": "30.1.0.0/16",
"DhcpOptionsId": "dopt-19edf471",
"State": "available",
"VpcId": "vpc-0e9801d129EXAMPLE",
"OwnerId": "111122223333",
"InstanceTenancy": "default",
"CidrBlockAssociationSet": [
{
"AssociationId": "vpc-cidr-assoc-062c64cfafEXAMPLE",
"CidrBlock": "30.1.0.0/16",
"CidrBlockState": {
"State": "associated"
}
}
],
"IsDefault": false,
"Tags": [
{
"Key": "Name",
"Value": "Not Shared"
}
]
}
]
}
However, if I use the command
$aws ec2 describe-vpcs --region us-west-1
then I can query all vpcs in region us-west-1.
Question 1. Why is the --region option not mentioned in the CLI SDK document?
Question 2. How can I incorporate the same in DescribeVpcsInput while using GO SDK?
The --region flag on the CLI is not a filter, it is a required setting that tells the AWS CLI what region to connect to. The ec2 describe-vpcs command is always limited to a single region (most AWS commands are).
You would configure your AWS SDK client with the region you want it to connect to as well. See "Specifying the AWS Region" here.
How to get the details of Instance using particular Elastic IP (EIP). For example , I have an EIP with me and I don't know where its located?
if you know the region you can use describe-addresses in aws cli:
aws ec2 describe-addresses --public-ips xxx.xxx.xxx.xxx
{
"Addresses": [
{
"InstanceId": "i-xxxxxxxxxxxx",
"PublicIp": "xx.xx.xx.xx",
"AllocationId": "eipalloc-xxxxx",
"AssociationId": "eipassoc-xxxxxxxxxxxxxxxx",
"Domain": "vpc",
"NetworkInterfaceId": "eni-xxxxxxx",
"NetworkInterfaceOwnerId": "xxxxxxxxxx",
"PrivateIpAddress": "xx.xx.xx.xx",
"PublicIpv4Pool": "amazon"
}
]
}
if you dont have the region you can use the region table to find it.
I got responsible for the management of a AWS account with a preexisting load balancer, and want to know if it is a Classic load balancer or an application load balancer.
I could not find the information either through the web console or the ruby API
In the web console when you look at your list of load balancers there is a "Type" column that tells you which type it is.
With API V2 describe-load-balancers command will give you the type of the ELB.
aws elbv2 describe-load-balancers --names my-load-balancer
Type will indicate the type of the ELB
{
"LoadBalancers": [
{
"VpcId": "vpc-3ac0fb5f",
"LoadBalancerArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/my-load-balancer/50dc6c495c0c9188",
"State": {
"Code": "active"
},
"DNSName": "my-load-balancer-424835706.us-west-2.elb.amazonaws.com",
"SecurityGroups": [
"sg-5943793c"
],
"LoadBalancerName": "my-load-balancer",
"CreatedTime": "2016-03-25T21:26:12.920Z",
"Scheme": "internet-facing",
"Type": "application",
"CanonicalHostedZoneId": "Z2P70J7EXAMPLE",
"AvailabilityZones": [
{
"SubnetId": "subnet-8360a9e7",
"ZoneName": "us-west-2a"
},
{
"SubnetId": "subnet-b7d581c0",
"ZoneName": "us-west-2b"
}
]
}
]
}
I want to assign one of my reserved Elastic IP's(ec2 classic ip) to Autoscaling group in VPC. Using AWS Cli I moved ip to vpc:
$ aws ec2 move-address-to-vpc --public-ip 23.23.23.23
And saw in aws concole, that this IP passed to VPC.
And Assigned in tags of AutoscalingGroup in Cloudformation template in Resources:
"Process": {
"Type" : "AWS::AutoScaling::AutoScalingGroup",
"Properties": {
"LaunchConfigurationName": {"Ref": "PreprocessorLC"},
"LoadBalancerNames": [{"Ref": "ProcessELB"}],
"VPCZoneIdentifier" : [{ "Fn::Join" : [",", [ { "Ref" : "PublicSubnet1"}, { "Ref" : "PublicSubnet2"} ]]}],
"AvailabilityZones": {"Ref": "AZs"},
"MinSize" : "1",
"MaxSize" : "1",
"HealthCheckGracePeriod": 300,
"Tags" : [
{"Key": "Name", "Value": {"Fn::Join": ["", [{"Ref": "Env"}, "-Process"]]}, "PropagateAtLaunch": true},
{"Key": "WorkersScalingGroup", "Value": {"Fn::Join": ["", ["Offering-", {"Ref": "Env"}, "-Process-Worker"]]}, "PropagateAtLaunch": true},
{"Key": "EIP", "Value": {"Ref": "ProcessIP"}, "PropagateAtLaunch": true},
{"Key": "Environment", "Value": {"Ref": "Env"}, "PropagateAtLaunch": true}
]
}
}
And added value of "ProcessIP" in Parameters:
"ProcessIP":{
"Description": "DEV: 23.23.23.23",
"Type": "String",
"Default": "23.23.23.23",
"AllowedValues": ["23.23.23.23"]
}
And it doesn't worked. Still get random IP.
If someone can tell where I'm wrong or what should to add for make it work?
Thanks!
In my case, I needed to keep a bank of unassigned EIPs and randomly assign them to the EC2 when they boot. That way I always know my servers will be using a specific list of IPs that I can whitelist in other places.
If you create several EIPs named "prod-pool" you can then use this script.
apt install -y jq awscli
ALLOCATION_ID=`aws ec2 describe-addresses --filters="Name=tag:Name,Values=prod-pool" | 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
You can attached this policy to your IAM user
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowEIPAttachment",
"Effect": "Allow",
"Resource": [
"*"
],
"Action": [
"ec2:AssociateAddress",
"ec2:DisassociateAddress"
]
}
]
}
Here is simple bash script:
#!/bin/sh
# Region in Which instance is running
EC2_REGION='us-east-1'
AWS_ACCESS_KEY='xxxxxxxxxxxx'
AWS_SECRET_ACCESS_KEY='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
#Instance ID captured through Instance meta data
InstanceID=`/usr/bin/curl -s http://169.254.169.254/latest/meta-data/instance-id`
#Elastic IP captured through the EIP instance tag
Elastic_IP=`/opt/aws/apitools/ec2/bin/ec2-describe-tags -O $AWS_ACCESS_KEY -W $AWS_SECRET_ACCESS_KEY --filter resource-id=$InstanceID --filter key='EIP' | cut -f5`
Allocate_ID=`/opt/aws/apitools/ec2/bin/ec2-describe-tags -O $AWS_ACCESS_KEY -W $AWS_SECRET_ACCESS_KEY --filter resource-id=$InstanceID --filter key="AllocationID" | cut -f5`
#Assigning Elastic IP to Instance
aws ec2 associate-address --instance-id $InstanceID --allocation-id $Allocate_ID
You need to explicitly associate the Elastic IP address with your desired EC2 instance. You can do this in a userdata script at launch time, or externally through other scripting or Configuration Management.
PropagateAtLaunch simply propagates tags from the Auto Scaling Group to any instances that are launched as a result of Auto Scaling actions. I'm not aware of any magic that would cause a tagged Elastic IP address to be associated with a launched instance.
See more discussion and examples of launch time scripting with EIPs here.
I created a AWS Lambda function which will automatically bind an Elastic IP address from a pool to instance of an autoscaling group. This alleviates the need to grab an EIP address in the bootscript of the instances. For a complete description check out
https://binx.io/blog/2019/09/02/how-to-dynamically-bind-elastic-ip-addresses-to-an-auto-scaling-group/
I have a cloudformation script that attempts to create a VPC, with one subnet per AZ.
When I run:
aws ec2 describe-availablity-zones
I get 4 zones returned:
"AvailabilityZones": [
{
"State": "available",
"RegionName": "us-east-1",
"Messages": [],
"ZoneName": "us-east-1a"
},
{
"State": "available",
"RegionName": "us-east-1",
"Messages": [],
"ZoneName": "us-east-1b"
},
{
"State": "available",
"RegionName": "us-east-1",
"Messages": [],
"ZoneName": "us-east-1c"
},
{
"State": "available",
"RegionName": "us-east-1",
"Messages": [],
"ZoneName": "us-east-1d"
}
]
However, when I try to create my stack, I get an error:
"ResourceStatusReason": "Value (us-east-1a) for parameter availabilityZone
is invalid. Subnets can currently only be created in the following
availability zones: us-east-1c, us-east-1b, us-east-1d.",
I am specifying the AZ with
"AvailabilityZone" : {
"Fn::Select" : [ "0", { "Fn::GetAZs" : "" } ]
},
Is there a way to check to see if the AZ is really available for the creation of a subnet?
This may not be helpful for the CLI Approach or your exact scenario - but with AWS Management Console this works smooth.
With the recent updates with the CloudFormation Parameters, you would be able pin-point the AZs pertaining to the specified AZs.
This would be much convenient during the DR / DR Drills and making the CFN template Region Independent.
"Parameters": {
"SubnetAZ": {
"Description": "Availability Zone of the Subnet",
"Type": "AWS::EC2::AvailabilityZone::Name"
}
}
More Information About the CloudFormation Parameters
Unfortunately I had the same problem. There is no method in CloudFormation to do this and the zones can be different per AWS account. This is a limitation of VPC infrastructure and it is likely not going to change. Your only option will be to hardcode the zones that you have found in your CloudFOrmation template instead of Fn::Select, for example:
"AvailabilityZone" : "us-east-1b"
Alternatively if you leave AvailabilityZone blank, the default behavior would be AWS will automatically pick one for you.
Fn::GetAZs will provide the available and usable availability zones as long as you have a default vpc with a subnet in each AZ! which by the way all new aws accounts have as long as you don't delete them manually.
I get around the limitation by avoiding json as the medium of expression. I use troposphere to compose my cloudformation templates.(https://github.com/cloudtools/troposphere)
You would however would have to deploy some sort of tooling around the deployment of cloudformation templates to individual regions.