Skip to content

aws.ec2-instance resource

Description

Instance is an EC2 instance: a virtual machine launched from an AMI or a launch template into a subnet. One RunInstances call provisions it with every field that call accepts; the only create-time field RunInstances does not take is source-dest-check, which a follow-on ModifyInstanceAttribute disables when the input asks for it. The instance settles from pending to running before its computed addresses, DNS names, and root volume id exist, so Create waits for that and returns the settled values from a Read rather than the run response.

The image, key pair, subnet, Availability Zone, primary private address, public-address association, tenancy, EBS-optimization flag, launch template, and the additional and instance-store volumes are fixed when the instance is created, so a change to any of them replaces the instance. The instance type and user data are reconciled by stopping the instance, modifying the one attribute, and starting it again. The security group set, the IAM instance profile, source-dest-check, monitoring, the two API-protection flags, the shutdown behavior, the metadata options, the volume tags, and the root volume's size, type, IOPS, throughput, delete-on-termination flag, and tags are all reconciled in place, each by its own call. A nil optional field is never sent: AWS applies its own default and fills the computed outputs.

A terminated instance still describes for a while, so Read maps a terminated state to a gone resource, the same as a not-found error code; a shutting-down instance is still live.

Source: internal/service/ec2/instance_rsrc.go:46

Example usage:

imports: {
  aws: 'github.com/cloudboss/unobin-library-aws'
}

resources: {
  example: aws.ec2-instance {
    # Set input fields here.
  }
}

Inputs

ami

optional(string)

instance-type

optional(string)

subnet-id

optional(string)

availability-zone

optional(string)

key-name

optional(string)

vpc-security-group-ids

list(string)

iam-instance-profile

optional(string)

user-data

optional(string)

user-data-base64

optional(string)

private-ip

optional(string)

associate-public-ip-address

optional(boolean)

monitoring

optional(boolean)

ebs-optimized

optional(boolean)

disable-api-termination

optional(boolean)

disable-api-stop

optional(boolean)

instance-initiated-shutdown-behavior

optional(string)

source-dest-check

optional(boolean)

tenancy

optional(string)

metadata-options

optional(object)
optional(
  object({
    http-endpoint: optional(string)
    http-protocol-ipv6: optional(string)
    http-put-response-hop-limit: optional(integer)
    http-tokens: optional(string)
    instance-metadata-tags: optional(string)
  })
)

root-block-device

optional(object)
optional(
  object({
    delete-on-termination: optional(boolean)
    encrypted: optional(boolean)
    iops: optional(integer)
    kms-key-id: optional(string)
    tags: optional(map(string))
    throughput: optional(integer)
    volume-size: optional(integer)
    volume-type: optional(string)
  })
)

ebs-block-device

list(object)
list(
  object({
    device-name: string
    delete-on-termination: optional(boolean)
    encrypted: optional(boolean)
    iops: optional(integer)
    kms-key-id: optional(string)
    snapshot-id: optional(string)
    throughput: optional(integer)
    volume-size: optional(integer)
    volume-type: optional(string)
  })
)

ephemeral-block-device

list(object)
list(
  object({
    device-name: string
    no-device: optional(boolean)
    virtual-name: optional(string)
  })
)

launch-template

optional(object)
optional(
  object({
    id: optional(string)
    name: optional(string)
    version: optional(string)
  })
)

volume-tags

map(string)

VolumeTags are applied to every EBS volume the instance creates, at create time and reconciled per volume on Update. Per-block-device tags are a future addition; this one flat map tags all of the instance's volumes alike.

tags

map(string)

force-destroy

optional(boolean)

ForceDestroy is read only at delete time. When true, Delete first clears the stop- and termination-protection attributes so a protected instance can be terminated. It backs no RunInstances field and is never reconciled after create.

Input Constraints

Field combinations

At least one of ami or launch-template.

At least one of instance-type or launch-template.

At most one of user-data or user-data-base64.

Tenancy rules

tenancy must be default, dedicated, or host.

Rule logic
When
input.tenancy != null
Require
input.tenancy == 'default'
|| input.tenancy == 'dedicated'
|| input.tenancy == 'host'

Launch template rules

launch-template requires exactly one of id and name.

Rule logic
When
input.launch-template != null
Require
((input.launch-template.id != null) && (input.launch-template.name == null))
|| ((input.launch-template.id == null) && (input.launch-template.name != null))

Metadata options rules

metadata-options http-endpoint must be enabled or disabled.

Rule logic
When
input.metadata-options.http-endpoint != null
Require
input.metadata-options.http-endpoint == 'enabled'
|| input.metadata-options.http-endpoint == 'disabled'

metadata-options http-tokens must be optional or required.

Rule logic
When
input.metadata-options.http-tokens != null
Require
input.metadata-options.http-tokens == 'optional'
|| input.metadata-options.http-tokens == 'required'

metadata-options http-protocol-ipv6 must be enabled or disabled.

Rule logic
When
input.metadata-options.http-protocol-ipv6 != null
Require
input.metadata-options.http-protocol-ipv6 == 'enabled'
|| input.metadata-options.http-protocol-ipv6 == 'disabled'

metadata-options instance-metadata-tags must be enabled or disabled.

Rule logic
When
input.metadata-options.instance-metadata-tags != null
Require
input.metadata-options.instance-metadata-tags == 'enabled'
|| input.metadata-options.instance-metadata-tags == 'disabled'

metadata-options http-put-response-hop-limit must be 1 to 64.

Rule logic
When
input.metadata-options.http-put-response-hop-limit != null
Require
(input.metadata-options.http-put-response-hop-limit == null || input.metadata-options.http-put-response-hop-limit >= 1)
&& (input.metadata-options.http-put-response-hop-limit == null || input.metadata-options.http-put-response-hop-limit <= 64)

Root block device rules

root-block-device iops is valid only for gp3, io1, or io2 volume types.

Rule logic
When
input.root-block-device.iops != null
&& input.root-block-device.volume-type != null
Require
input.root-block-device.volume-type == 'gp3'
|| input.root-block-device.volume-type == 'io1'
|| input.root-block-device.volume-type == 'io2'

root-block-device iops is required when volume-type is io1 or io2.

Rule logic
When
input.root-block-device.volume-type == 'io1'
|| input.root-block-device.volume-type == 'io2'
Require
input.root-block-device.iops != null

root-block-device throughput is valid only for gp3 volumes.

Rule logic
When
input.root-block-device.throughput != null
&& input.root-block-device.volume-type != null
Require
input.root-block-device.volume-type == 'gp3'

root-block-device tags cannot combine with volume-tags.

Rule logic
When
input.root-block-device.tags != null
Require
input.volume-tags == null

Ebs block device rules

iops is valid only for gp3, io1, or io2 volume types.

Rule logic
For each
input.ebs-block-device
When
@each.value.iops != null
&& @each.value.volume-type != null
Require
@each.value.volume-type == 'gp3'
|| @each.value.volume-type == 'io1'
|| @each.value.volume-type == 'io2'

iops is required when volume-type is io1 or io2.

Rule logic
For each
input.ebs-block-device
When
@each.value.volume-type == 'io1'
|| @each.value.volume-type == 'io2'
Require
@each.value.iops != null

throughput is valid only for gp3 volumes.

Rule logic
For each
input.ebs-block-device
When
@each.value.throughput != null
&& @each.value.volume-type != null
Require
@each.value.volume-type == 'gp3'

Ephemeral block device rules

virtual-name is required unless no-device is true.

Rule logic
For each
input.ephemeral-block-device
When
!(@each.value.no-device == true)
Require
@each.value.virtual-name != null
&& @core.length(@each.value.virtual-name) >= 1

Outputs

instance-id

string

instance-state

string

availability-zone

string

subnet-id

string

private-ip

string

public-ip

string

private-dns

string

public-dns

string

primary-network-interface-id

string

root-volume-id

string

root-device-name

string