Copy ami to different region with cli - amazon-web-services

I am trying to copy an ami from one region to a different region through the AWS CLI.
The following command works fine for copying an ami to the same region:
aws ec2 copy-image --name ami-copy-test --source-image-id ami-123... --source-region us-east-1
but I am trying to copy to a different region, us-east-2 for instance.
There doesn't seem to be a --destination-region flag. The documentation page:
https://docs.aws.amazon.com/cli/latest/reference/ec2/copy-image.html
states:
You specify the destination Region by using its endpoint when making
the request.
But what does this actually mean?

You are on the right page, just continue to read
from https://docs.aws.amazon.com/cli/latest/reference/ec2/copy-image.html
...
This example copies the specified AMI from the us-east-1 region to the ap-northeast-1 region.
Command:
aws ec2 copy-image --source-image-id ami-5731123e --source-region us-east-1 --region ap-northeast-1 --name "My server"

Related

How to iterate through multiple AWS accounts?

Consider an AWS organization with 50+ accounts. Each account has a role created that allows read-only access to the EC2 service - named "EC2ReadAccess" - and a trust relationship with the master(/management) account. A single IAM user in the master account has a policy applied to allow it to assume the role in every single account.
I would like to be able to iterate through all the accounts in order to retrieve all the EC2 instances, using the unique IAM user. I know that running a CLI command against all the accounts at once is out of the question. Leaving aside cycling through the regions in each account, which has been discussed extensively, is there an elegant solution for doing this?
One hack that comes to mind is to programmatically build the credentials file so that it contains a profile for each account. Each profile, in turn, will be "linked" to the profile of the IAM user (as described here), and have the account id within the role updated for each entry. An example below:
[user1]
aws_access_key_id=<key_id>
aws_secret_access_key=<secret_key>
[marketing]
role_arn = arn:aws:iam::123456789012:role/EC2ReadAccess
source_profile = user1
[dev]
role_arn = arn:aws:iam::234567890123:role/EC2ReadAccess
source_profile = user1
...
[prod]
role_arn = arn:aws:iam::345678901234:role/EC2ReadAccess
source_profile = user1
Running the CLI command - in this case aws ec2 describe-instances - can be accompanied by the --profile parameter in order to cycle through all the profiles present in the credentials file. The region can be cycled through within another loop. So a list of commands to be issued, generated programmatically beforehand, could look something like:
aws ec2 describe-instances --profile marketing --region us-east-1
aws ec2 describe-instances --profile marketing --region us-east-2
...
aws ec2 describe-instances --profile marketing --region sa-east-1
aws ec2 describe-instances --profile dev --region us-east-1
aws ec2 describe-instances --profile dev --region us-east-2
...
aws ec2 describe-instances --profile dev --region sa-east-1
...
aws ec2 describe-instances --profile prod --region us-east-1
aws ec2 describe-instances --profile prod --region us-east-2
...
aws ec2 describe-instances --profile prod --region sa-east-1
Is there a better way of doing this? Am I missing something obvious here?
Don't use the CLI to do this. If you're able to "programmatically build the credentials file", then you should be able to write a program that does the following for every child account:
Assumes the administrator role for that account.
Invokes the DescribeInstances API call.
Do whatever you want with the information
You don't indicate what programming language(s) you're familiar with, but here's some Python that I use to create an SDK client with the standard "OrganizationalAccountAccessRole" in a child account:
def create_boto_resource(account, region, resource_type):
creds = assumeRole(account)
return boto3.resource(resource_type,
region_name=region,
aws_access_key_id=creds['AccessKeyId'],
aws_secret_access_key=creds['SecretAccessKey'],
aws_session_token=creds['SessionToken'])
def assumeRole(account, role_name='OrganizationAccountAccessRole', duration=900):
stsClient = boto3.client('sts')
request = {}
request['RoleArn'] = f"arn:aws:iam::{account}:role/{role_name}"
request['RoleSessionName'] = 'DESCRIPTIVE_TEXT_HERE'
request['DurationSeconds'] = duration
return stsClient.assume_role(**request)['Credentials']
This code actually creates a Boto resource object, which is a simplified API that's supported for EC2 and a few other services. Here's and example of using the resource API to create an instance iterator.
Another way to attack this kind of problem might be via Systems Manager Inventory and Querying inventory data from multiple Regions and accounts.

How can I list the regions for my AWS VPC?

I am trying to list down all the regions for which my AWS VPC is configured.
The following commands are of no use to me, since:
aws ec2 describe-vpcs
Only lists VPC details but not the region
aws ec2 describe-availability-zones
Lists all the availability zones available for me.
I do see the specific AZs for my subnets under:
AWS Console --> VPC --> Summary --> Network ACL --> Subnet Associations
But I would like to list the same on the command line for my VPC. Is this possible?
An Amazon VPC exists only in one region. There is no multi-region capability for VPCs.
The VPC will be in the region to which you issue the above commands. Therefore, you must already know the region before issuing any of these commands.
If you merely want a list of regions (unrelated to a particular VPC), use describe-regions:
aws ec2 describe-regions
Yes it possible using the shellscript. At time you can list only one region Resources using AWS CLI.
#!/bin/bash
Profile='Enter_your_profile_name'
while read f1 f2
do
Region=$f1
Region_Name=$f2
echo "$Region - $Region_Name \n" >> vpc-details.csv
aws ec2 describe-vpcs --profile $Profile --region $Region --output text --query 'Vpcs[].[Tags[?Key==`Name`].Value | [0],CidrBlock,VpcId,IsDefault]' --filter Name=isDefault,Values=false >> vpc-details.csv
echo "\n" >> vpc-details.csv
done < region.txt
region.txt
us-east-2 US-East(Ohio) us-east-1 US-East(N-Virginia)
us-west-1 US-West(N-California) us-west-2 US-West-(Oregon)
ap-northeast-1 Asia-Pacific-(Tokyo)
ap-northeast-2 Asia-Pacific-(Seoul) ap-south-1 Asia-Pacific-(Mumbai)
ap-southeast-1 Asia-Pacific-(Singapore)
ap-southeast-2 Asia-Pacific-(Sydney) ca-central-1 Canada-(Central)
eu-central-1 EU -Frankfurt) eu-west-1 EU-(Ireland)
eu-west-2 EU-(London) eu-west-3 EU-(Paris)
sa-east-1 South-America-(São-Paulo)
Sample output
eu-west-1 - EU-(Ireland)
Testining 10.135.0.0/16 vpc-xxxx False
VPC_prod 10.140.0.0/16 vpc-zzzz False
Note: - you will be getting the following output
Name of the VPC
CIDR range
VPC-ID
Is the VPC is default or not
You have to give your profile variable to make it work... Let me know if you have any query.

Query the list of supported regions in aws amazon

How to get list available regions from amazon?
Before I tried next query
https://ec2.amazonaws.com/?Action=DescribeRegions&AWSAccessKeyId=****&SignatureMethod=HmacSHA256&SignatureVersion=1&Version=2013-08-15
But I get "AWS was not able to validate the provided access credentials" and I don't sure that it correct query.
Your Question Does not seem to specify what services you need to use and how but here is generic example from AWS CLI:
Using describe-regions will give answer to your question , example to describe region names only:
aws ec2 describe-regions --query 'Regions[].{Name:RegionName}' --output text output will be like:
ap-south-1
eu-west-1
ap-southeast-1
ap-southeast-2
eu-central-1
ap-northeast-2
ap-northeast-1
us-east-1
sa-east-1
us-west-1
us-west-2
This is the AWS CLI Documentation that you can refer.

Cannot copy an image due to mysterious error about EC2 BillingProduct code

I am attempting to copy an EC2 image for the purpose of encrypting it.
The command line I issue is:
$ aws ec2 copy-image --name encrypted-kafka-201707121432 \
--source-region ap-southeast-2 --encrypted --source-image-id ami-2a617249 \
--region ap-southeast-2
This leads to the following error being emitted:
An error occurred (InvalidRequest) when calling the CopyImage operation:
Images with EC2 BillingProduct codes cannot be copied to another AWS account.
I have looked around and I understand that this error is typically seen when copying Windows AMIs (e.g. here) and it is similar to this issue on SO (here).
However, this image is not from the Marketplace, and it is not a Windows AMI, and it does not have any ProductCodes in it:
$ aws ec2 describe-images --image-ids ami-2a617249 --region ap-southeast-2 \
--query '.Images[].ProductCodes'
[]
Compare this to another one that does:
$ aws ec2 describe-images --image-ids ami-00280263 --region ap-southeast-2 \
--query '.Images[].ProductCodes'
[
{
"ProductCodeType": "marketplace",
"ProductCodeId": "dsli9z1o9amfv5g2hsmdj1pph"
}
]
The image was baked using Packer.
I am out of ideas. Why is this happening - am I doing something wrong, or is this undocumented behaviour?
It turns out that a descendent of this AMI did come from the Amazon Marketplace.
A simplified version of the baking pipeline is:
Account A:
Marketplace AMI (ami-xxxxxxxx) -> packer build (ami-yyyyyyyy) -> share to Account B
Account B:
I then issued:
aws ec2 copy-image --encrypted --source-image ami-yyyyyyyy
And received:
An error occurred (InvalidRequest) when calling the CopyImage operation:
Images with EC2 BillingProduct codes cannot be copied to another AWS account.
From account B I could check the owner, namely the Account that shared it with me:
$ aws ec2 describe-images --image-id ami-yyyyyyyy --region ap-southeast-2 \
> --query 'Images[0].OwnerId'
This returned the 16-digit account ID of Account A.
At this point it is helpful to understand that baking an AMI using Packer causes the product codes to be apparently lost. However, those product codes remain, and Amazon support can see them. It requires a call to Amazon support to confirm this part.
To work around, I now maintain a script encrypt_ami in Python or Bash (AWS CLI) that can be used.

Finding EC2 status using EC2 API

Is there any way to find out status of AWS EC2 instances, which are running on various different regions, from one EC2 instance which is present in any one of region by using EC2 API tool ?
How this is possible ?
I got the answer :-
ec2-describe-instances instance-ID --region region
Example :-
ec2-describe-instances i-f82d5ca0 --region eu-west-1
Where instance ID is EC2 instance ID which is located in region eu-west-1
Thats all .
Or in the new unified AWS CLI, this is slightly different:
aws ec2 describe-instances --instance-id i-f82d5ca0
You can also change the --output into json, text, or a table