Moto how to create EC2 instance - InvalidAMIID.NotFound - amazon-web-services

Using moto how can you create an EC2 instance since theres no AMIs available to launch an instance with.
This repo seems to be "pre-loading" AMIs that are later used within tests but im not sure how these are being created
https://github.com/spulec/moto/blob/master/tests/test_ec2/test_instances.py#L25
https://github.com/spulec/moto/blob/master/moto/ec2/resources/amis.json
I've tried calling .describe_images(Owners=["amazon"]) however, all the AMIs returned when used in the run_instances call give the below error.
from moto import mock_ec2
#mock_ec2
def Test_create_ec2():
boto3.client('ec2').run_instances(ImageId="ami-1234abcd", MinCount=1, MaxCount=1)
botocore.exceptions.ClientError: An error occurred (InvalidAMIID.NotFound) when calling the RunInstances operation: The image id '[ami-1234abcd]' does not exist
This issue also relates to the unresolved question How to create ami with specific image-id using moto?

The call to describe_images does give a list of all available ImageId's.
The following test works against the current development branch of Moto:
#mock_ec2
def test_all_images():
client = boto3.client("ec2", region_name="us-east-1")
images = client.describe_images(Owners=["amazon"])["Images"]
for image in images:
client.run_instances(ImageId=image["ImageId"], MinCount=1, MaxCount=1)
The preloaded images come from this file:
https://github.com/spulec/moto/blob/master/moto/ec2/resources/amis.json
If you want to substitute your own AMI's, you can use the following environment variable:
MOTO_AMIS_PATH=/full/path/to/amis.json
This JSON-file has to be in the same format as the one linked above.
Note that the environment variable has to be set before Moto is initialized - these AMI's are loaded the moment you call from moto import mock_ec2, so the environment variable has to be set before that import takes place.

Related

What is the reason for error "Resource in project is the subject of a conflict" while trying to recreate a cloudsql instance?

I am trying to create a cloudsql instance with the following command:
gcloud beta sql instances create sql-instance-1 --tier=db-f1-micro --region=asia-south1 --network=default --storage-type=HDD --storage-size=10GB --authorized-networks=XX.XXX.XX.XX/XX
The instance sql-instance-1 is something I need not running all the time. So I create an sqldump file and when I need the database I create it. When I run this command it fails with the following error
ERROR: (gcloud.beta.sql.instances.create) Resource in project [my-project-id] is the subject of a conflict: The instance or operation is not in an appropriate state to handle the request.
From what I understand the gcloud is complaining that instance name was used before although the instance is already deleted. When I change the name to a new unused name the command works fine. The problem with this is I need to give a new name every time I re-create the instance from the dump.
My questions are:
Is this expected behavior i.e. should name of cloud-sql instance be unique and not used before within a project.
I also found that --network option is not recognized with gcloud. Seems to work only with gcloud beta as explained here. When is this expected to become GA?
This is indeed expected behaviour. From the documentation:
You cannot reuse an instance name for up to a week after you have
deleted an instance.
Regarding the --network flag and it's schedule for GA, there is no ETA for its release outside of beta. However, it's release will be listed in the Google Cloud SDK Release Notes, which you can get updates from by subscribing to the google-cloud-sdk-announce group

Using gcloud cli within a cloud function

There are great but still limited set of SDK access to GCP APIs within cloud function SDKs. e.g. Node.
I want to call gcloud cli within a cloud function. Is this possible? e.g.
gcloud sql instances patch my-database --activation-policy=NEVER
The goal is nightly shutdown of an SQL instance
I believe you should use the Cloud SQL Admin API. If you're using the Python runtime for example you'd had 'google-api-python-client==1.7.8' (for example) to your requirements file and on the respective client library you would use the method instances.patch with the appropriate parameters.
Hope this helps.
Also you have here a working example with the Python runtime, just be sure to edit the 'projid' and 'instance' variables accordingly.
from googleapiclient.discovery import build
service = build('sqladmin', 'v1beta4')
projid = '' #project id where Cloud SQL instance is
instance = '' #Cloud SQL instance
patch = {'settings': {'activationPolicy':'NEVER'}}
req = service.instances().patch(project=projid, instance=instance, body=patch)
x = req.execute()
print(x)

How to create ami with specific image-id using moto?

I'am using moto to mock aws for my application. I wondering if it is possible to create ami in moto with specific image-id (for example: ami-1a2b3c4d).
Thank you!
You want to use preloaded resources like this file: https://github.com/spulec/moto/blob/master/moto/ec2/resources/amis.json
You can use the following environment variable: MOTO_AMIS_PATH=/full/path/to/amis.json
This JSON-file has to be in the same format as the one linked above. Note that the environment variable has to be set before Moto is initialised - these AMI's are loaded the moment you call from moto import mock_ec2, so the environment variable has to be set before that import takes place.
(Copied from https://stackoverflow.com/a/72270977/7224682)
Here is an example coming straight from the docs:
from . import add_servers
from moto import mock_ec2
#mock_ec2
def test_add_servers():
add_servers('ami-XXXXXXX', 2)
client = boto3.client('ec2', region_name='us-west-1')
instances = client.describe_instances()['Reservations'][0]['Instances']
assert len(instances) == 2
instance1 = instances[0]
assert instance1['ImageId'] == 'ami-XXXXXXXX'
You can choose the AMI ID to be whatever you want, there are no restrictions. I'm not sure I understand what the problem is as these are "mock" resources so they can be in any format/contain any name that you want.

how to create a vm snapshot using pyvmomi

I have a task of implementing a basic backup and recovery system within a django app. I have heard of pyvmomi, but never used it before.
My specific tasks at hand is:
1) make a call to a vCenter, pass the vm name, and request to make a snapshot
2) obtain the file location of the snapshot
3) and upload the snapshot file into an OpenStack Swift object store
What is the actual syntax of creating a vm snapshot using pyvmomi?
Also - what is the syntax to request the actual snapshot file from vCenter?
https://github.com/rreubenur/vmware-pyvmomi-examples/blob/master/create_and_remove_snapshot.py
This should be helpful
Snapshot task result itself contains Moref to snashot created
So that you can get reference to created snapshot.

ssh through python onto amazon ec2

I have two databases one on my local machine and one on my amazon ec2 instance.Now what I
do is I run a python program on my local machine which makes changes to the databse on my local machine.I want these changes to be reflected onto the database on amazon ec2 instance,
periodically.I want to do this in python.A script that logs onto the amazon server establishes a connection with the database there and makes the changes.
I came across some modules like pexcept,fabric and paramiko.But I am struggling with the
key authentication.
The way I ssh from my terminal is ssh -i my_rsa_file.pem username#ip_address.There is no password.How do I go about this ??
Also I want to know whether simply using Popen in subprocess to execute the login command work ?
The Boto EC2 documentation here describes the EC2 instance object, of which "key_pair" is an attribute. Look about 3/4 of the way down, under "boto.ec2.instance".
http://boto.readthedocs.org/en/latest/ref/ec2.html
So, e.g., you could run some instances as follows, and then store the first instance as "inst":
reservation = conn.run_instances(...)
inst = reservation.instances[0]
To retrieve your key-pair name as a unicode string, just use:
kp_name = inst.key_name
You can then retrieve the corresponding Boto object using get_key_pair:
kp_obj = conn.get_key_pair(kp_name)
Of course, this is a silly example, since I would have needed my key pair name to run_instances in the first place. May you find a more fruitful application!