RunInstances
Launches one or more instances. This is the only action that creates a machine.
RunInstances is idempotent through ClientToken. Always send one.
Request
Section titled “Request”| Parameter | Type | Required | Notes |
|---|---|---|---|
ImageId | string | Yes | ami-…. See Machine images |
MinCount | integer | Yes | ≥ 1 |
MaxCount | integer | Yes | ≥ 1, and ≥ MinCount |
InstanceType | string | No | Our name or an AWS alias. Defaults to cd-standard-2-2 |
KeyName | string | No | A key pair you have imported. Without it you cannot log in |
UserData | string | No | Base64. ≤ 16384 bytes decoded |
SecurityGroupId.N | list | No | Defaults to the default group of your VPC |
SubnetId | string | No | Defaults to your own subnet |
PrivateIpAddress | string | No | Must be inside your subnet |
TagSpecification.N | list | No | ResourceType must be instance or volume |
BlockDeviceMapping.N | list | No | Root device size only |
ClientToken | string | No | ≤ 64 ASCII characters. Send one |
Placement.AvailabilityZone | string | No | hel1-a |
MetadataOptions | structure | No | Accepted only at the platform defaults — see below |
DryRun | boolean | No | Evaluate permissions and do nothing else |
MinCount and MaxCount
Section titled “MinCount and MaxCount”The call launches as many as it can between the two. If it cannot reach
MinCount it launches nothing and returns InsufficientInstanceCapacity —
it does not partially succeed.
For one machine, set both to 1.
ClientToken
Section titled “ClientToken”Two calls with the same token return the same instances rather than launching a second set. A token is remembered long enough to cover a retry after a lost response, which is exactly the case it exists for.
Without one, a network timeout between your client and us can leave you paying
for a machine you do not know about. Every SDK will generate one if you ask;
the CLI takes --client-token.
UserData
Section titled “UserData”Base64, at most 16384 bytes decoded — the Amazon limit, enforced here even though the platform underneath would accept more, so that a payload which works on AWS works here unchanged.
Never logged: the parameter is marked sensitive.
Delivery, the config drive, and why a running instance may still be
unconfigured: Instance metadata and user data.
MetadataOptions
Section titled “MetadataOptions”Accepted only when every member given equals the platform default:
HttpTokens=optional HttpEndpoint=enabled HttpPutResponseHopLimit=1HttpProtocolIpv6=disabled InstanceMetadataTags=disabledAnything else is UnsupportedOperation. In particular HttpTokens=required
(IMDSv2) is refused rather than silently downgraded, because the metadata
service has no session-token mode and pretending otherwise would leave you
believing in a defence you do not have.
Terraform sends this block only when you configure metadata_options.
BlockDeviceMapping.N
Section titled “BlockDeviceMapping.N”Supported for the root device only, and only to change its size. Additional volumes are created and attached separately — see Volume actions.
A root device size below the image’s minimum is InvalidParameterValue.
Parameters that are refused
Section titled “Parameters that are refused”Refused with InvalidParameterValue or UnsupportedOperation, never ignored:
InstanceMarketOptions (spot), CapacityReservationSpecification,
Placement.GroupName, Placement.HostId and Placement.Tenancy,
LaunchTemplate, IamInstanceProfile, HibernationOptions,
ElasticGpuSpecification, ElasticInferenceAccelerators, EnclaveOptions,
CpuOptions, CreditSpecification, Ipv6AddressCount and
Ipv6Addresses, NetworkInterface.N beyond a single default interface.
Refusing rather than ignoring is deliberate. A module that asks for an IAM instance profile fails at apply rather than launching a machine that silently has no credentials.
Response
Section titled “Response”A reservation containing one entry per instance launched:
| Element | Notes |
|---|---|
reservationId | r-… |
instancesSet | One instance per machine |
instanceId | i-… |
imageId, instanceType, keyName | As launched. instanceType is our name, even if you passed an AWS alias |
instanceState | pending at this point |
privateIpAddress | Present once the address is assigned |
placement.availabilityZone | hel1-a |
amiLaunchIndex | Position within the reservation |
clientToken | If you sent one |
tagSet | Tags applied at launch |
blockDeviceMapping | The root device |
groupSet | Security groups |
[!primary]
The response names our instance type, not the alias you launched with. Launch
m5.largeandDescribeInstancesreportscd-standard-2-8. Terraform records that in state, so a configuration written with the AWS name shows a diff on every plan. Write our name, orignore_changes = [instance_type].
Tags applied through TagSpecification are applied as part of the launch,
not afterwards, so a machine never exists untagged. That is what makes
tag-based reconciliation safe after a failed retry.
Errors
Section titled “Errors”| Code | Status | Cause |
|---|---|---|
InvalidAMIID.NotFound | 400 | No such image, or not one we publish |
InvalidParameterValue | 400 | Unknown instance type, MinCount/MaxCount < 1, user data not base64 or over the limit, client token over 64 characters, a bad tag |
InvalidParameterCombination | 400 | MaxCount below MinCount |
InvalidKeyPair.NotFound | 400 | No such key pair in your account |
InvalidGroup.NotFound | 400 | No such security group |
InstanceLimitExceeded | 400 | Your vCPU or memory quota |
InsufficientInstanceCapacity | 500 | The hardware cannot fit it now. Not a quota problem |
UnsupportedOperation | 400 | A parameter that exists in the model but not here |
Unsupported | 400 | A combination that cannot be honoured |
InsufficientInstanceCapacity is the one to handle differently: retrying the
same shape or asking for more quota will not help. Take a smaller shape, or
wait. GET /v1/catalog reports whether a shape is in stock right now —
Catalog and availability.
Examples
Section titled “Examples”AWS CLI
Section titled “AWS CLI”aws --endpoint-url https://ec2.shelfcs.com --region hel1 \ ec2 run-instances \ --image-id ami-… \ --instance-type cd-standard-2-4 \ --key-name mykey \ --count 1 \ --client-token "$(uuidgen)" \ --user-data file://cloud-init.yaml \ --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=web}]'--count 1 sets both MinCount and MaxCount.
Terraform
Section titled “Terraform”resource "aws_instance" "web" { ami = data.aws_ami.debian.id instance_type = "cd-standard-2-4" # our name, not m5.large key_name = aws_key_pair.mine.key_name user_data = file("cloud-init.yaml")
tags = { Name = "web" }}The provider generates a client token for you.
res = ec2.run_instances( ImageId=image_id, InstanceType="cd-standard-2-4", KeyName="mykey", MinCount=1, MaxCount=1, ClientToken=str(uuid.uuid4()), TagSpecifications=[{ "ResourceType": "instance", "Tags": [{"Key": "Name", "Value": "web"}], }],)iid = res["Instances"][0]["InstanceId"]ec2.get_waiter("instance_running").wait(InstanceIds=[iid])After it returns
Section titled “After it returns”pending becomes running in well under a minute. That means the machine
booted — not that your configuration applied. See
Instance metadata and user data.
Then connect as the image’s login user, never root —
Machine images.