Skip to main content
mutationdraftawscc
Servicesec2
CredentialsAWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY
Permissionscloudformation:CreateResource ec2:RunInstances ec2:CreateTags ec2:DescribeInstances
Expensive at scale. Launches billable compute; the instance runs until stopped or terminated

Launch an EC2 instance

Launches an EC2 instance through Cloud Control. The launch is asynchronous: the statement returns a progress event immediately and the instance is created in the background, so capture the RequestToken and poll it to confirm success. This launches billable compute - the instance runs until explicitly stopped or terminated.

Query

INSERT INTO awscc.ec2.instances (
ImageId,
InstanceType,
SubnetId,
UserData,
Tags,
region
)
SELECT
'{{image_id}}',
'{{instance_type}}',
'{{subnet_id}}',
'{{user_data}}',
'{{tags}}',
'{{region}}'
RETURNING
ErrorCode,
EventTime,
Identifier,
Operation,
OperationStatus,
RequestToken,
ResourceModel,
RetryAfter,
StatusMessage,
TypeName;

Variation: with security groups and a key pair

Add networking and access properties as further columns; every AWS::EC2::Instance property is settable this way, including BlockDeviceMappings, IamInstanceProfile, MetadataOptions, EbsOptimized, Monitoring and DisableApiTermination:

INSERT INTO awscc.ec2.instances (
ImageId,
InstanceType,
SubnetId,
SecurityGroupIds,
KeyName,
UserData,
Tags,
region
)
SELECT
'{{image_id}}',
'{{instance_type}}',
'{{subnet_id}}',
'["sg-0123456789abcdef0"]',
'my-key-pair',
'{{user_data}}',
'{{tags}}',
'{{region}}'
RETURNING
Identifier,
OperationStatus,
RequestToken,
StatusMessage;

Variation: the native provider

The native provider wraps RunInstances directly and is synchronous - it returns the instance record rather than a progress event, so no polling is needed. MinCount and MaxCount are required, and the tag property is TagSpecification with a ResourceType wrapper:

INSERT INTO aws.ec2.instances (
ImageId,
InstanceType,
SubnetId,
UserData,
TagSpecification,
MinCount,
MaxCount,
region
)
SELECT
'{{image_id}}',
'{{instance_type}}',
'{{subnet_id}}',
'{{user_data}}',
'[{"ResourceType":"instance","Tags":[{"Key":"Name","Value":"my-instance"}]}]',
1,
1,
'{{region}}'
RETURNING
InstanceId,
InstanceType,
PrivateIpAddress,
State,
SubnetId,
VpcId;

Notes

UserData must be base64 encoded before it reaches the query - AWS does not encode it for you, and a plain-text script is accepted silently but never runs. The AMI architecture must match the instance type: t4g and other Graviton types need an arm64 AMI, t3 and m5 need x86_64, and a mismatch fails the launch - confirm a type's architecture with aws/ec2/instance-types-lookup before launching. Cloud Control assigns Identifier eagerly for some resource types and lazily for others: when the returned Identifier is non-null it is the instance id, and when it is null the id only becomes available once the request reaches SUCCESS, so poll aws/cloud_control/resource-request-by-token with the RequestToken and read Identifier from the terminal progress event. On the native provider the input properties are singular where the AWS API is plural - TagSpecification, SecurityGroupId, BlockDeviceMapping, NetworkInterface - which is a common source of unknown-column errors. Terminate with DELETE FROM awscc.ec2.instances WHERE region = '' AND Identifier = '<instance_id>', which is likewise asynchronous.

Related queries