Updraft ExtensionsPreview
Amazon EC2Compute Stable

AWS::EC2::Instance

Launches a single EC2 instance. Straightforward to write and unforgiving to update — over half its properties replace the instance when changed, which is why most production capacity is defined by a launch template instead.

Required properties 1 of 20
Ref returns Instance IDi-0abcdef1234567890
Fn::GetAtt 5 attributes
Replacement risk 10 10 properties force replacement

Minimal template

Every required property, nothing else
Resources:
  Jumpbox:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref LatestAmazonLinuxAmi
      InstanceType: t3.micro
      SubnetId: !Ref PrivateSubnetA
Strictly, only ImageId is required — but an instance with no SubnetId lands in the default VPC, which may not exist, and gets a security group you did not choose. Always be explicit about placement.

Overview #

AWS::EC2::Instance launches exactly one instance and manages it for the life of the stack. It is the most direct way to get a server, and the least manageable way to keep one.

The difficulty is not the resource — it is the mismatch between what the EC2 API can change on a running instance and what CloudFormation can express. EC2 can resize an EBS volume live; CloudFormation replaces the instance. EC2 can attach an instance profile to a running host; CloudFormation can too, but only for that one property. The result is that a template which looks like a small edit turns into a rebuild.

What replaces the instance #

The single most useful thing to know before editing a template. Switch the property explorer below to Table view and read the Update column, or take the summary:

ChangeEffect
InstanceTypeStop, modify, start. Instance store contents and any non-Elastic public IP are lost.
SecurityGroupIds, Monitoring, Tags, MetadataOptions, IamInstanceProfileUpdates in place.
ImageId, UserData, BlockDeviceMappings, SubnetId, KeyName, AvailabilityZone, PrivateIpAddress, TenancyReplacement. New instance, new instance ID, old one terminated.

An instance you would actually deploy #

Parameters:
  LatestAmi:
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Default: /aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64

Resources:
  Jumpbox:
    Type: AWS::EC2::Instance
    Properties:
      ImageId: !Ref LatestAmi
      InstanceType: t3.micro
      SubnetId: !Ref PrivateSubnetA
      SecurityGroupIds:
        - !Ref JumpboxSecurityGroup

      # Session Manager instead of SSH: no inbound port, no key to rotate,
      # and every session is logged. Note the absence of KeyName.
      IamInstanceProfile: !Ref JumpboxInstanceProfile

      # IMDSv2 only. This is the control that turns an application-level SSRF
      # from a credential theft into an error message.
      MetadataOptions:
        HttpTokens: required
        HttpPutResponseHopLimit: 1

      BlockDeviceMappings:
        - DeviceName: /dev/xvda        # Amazon Linux; Ubuntu uses /dev/sda1
          Ebs:
            VolumeSize: 30
            VolumeType: gp3            # cheaper and faster than the gp2 default
            Encrypted: true
            DeleteOnTermination: true

      Monitoring: true
      PropagateTagsToVolumeOnCreation: true

      Tags:
        - Key: Name
          Value: acme-jumpbox
        - Key: Environment
          Value: production

Referencing an instance #

!Ref Jumpbox → i-0abcdef1234567890

!GetAtt Jumpbox.PrivateIp → 10.0.1.42

!GetAtt Jumpbox.PublicIp → (empty string)the attribute exists in a private subnet, and resolves to nothing

Properties

Expand a row for the full reference; nested types open in place

20 top-level properties

  • ImageId StringThe AMI to launch from. Required Replacement — CloudFormation creates a new resource and deletes the old one Create-only
    AMI IDs are region-specific. The same image has a different ID in every region, which is why templates either carry a region map or resolve the ID at deploy time.
    Type
    String
    Required
    Yes
    Update behaviour
    Replacement
    Pattern
    ^ami-[0-9a-f]{8}([0-9a-f]{9})?$

    Example values

    • ami-0abcdef1234567890
  • InstanceType StringThe instance family and size. Some interruption — the resource may be briefly unavailable
    Changing the type stops the instance, changes it, and starts it again. The instance keeps its EBS volumes and its private IP; it loses everything in instance store and, without an Elastic IP, its public IP.
    Type
    String
    Required
    No
    Update behaviour
    Some interruption
    Default
    m1.small

    Example values

    • t3.micro
    • m6i.large
  • SubnetId StringThe subnet, which determines the VPC and the availability zone. Replacement — CloudFormation creates a new resource and deletes the old one Create-only
    Setting the subnet implies the availability zone; setting both and disagreeing fails. Moving an instance between subnets is a replacement, because an ENI cannot change subnet.
    Type
    String
    Required
    No
    Update behaviour
    Replacement

    Example values

    • subnet-0abcdef1234567890
  • AvailabilityZone StringThe zone to launch in. Implied by SubnetId, and must agree with it. Replacement — CloudFormation creates a new resource and deletes the old one Create-only

    The zone to launch in. Implied by SubnetId, and must agree with it.

    Type
    String
    Required
    No
    Update behaviour
    Replacement

    Example values

    • us-west-2a
  • BlockDeviceMappings Array of BlockDeviceMappingVolumes attached at launch, including the root volume's size and type. Replacement — CloudFormation creates a new resource and deletes the old one Create-only

    Volumes attached at launch, including the root volume's size and type.

    Type
    Array of BlockDeviceMapping
    Required
    No
    Update behaviour
    Replacement

    BlockDeviceMapping properties

    • DeviceName StringDevice name as the OS will see it. Required Replacement — CloudFormation creates a new resource and deletes the old one
      The root device name depends on the AMI: /dev/xvda for Amazon Linux, /dev/sda1 for most Ubuntu images. Getting it wrong attaches an extra volume instead of configuring the root one, and the mistake is only visible from inside the instance.
      Type
      String
      Required
      Yes
      Update behaviour
      Replacement

      Example values

      • /dev/xvda
    • Ebs EbsBlockDeviceEBS volume settings for this device. Replacement — CloudFormation creates a new resource and deletes the old one

      EBS volume settings for this device.

      Type
      EbsBlockDevice
      Required
      No
      Update behaviour
      Replacement

      EbsBlockDevice properties

      • Iops IntegerProvisioned IOPS. Conditional Replacement — CloudFormation creates a new resource and deletes the old one

        Provisioned IOPS.

        Type
        Integer
        Required
        ConditionalRequired for io1 and io2.
        Update behaviour
        Replacement
        Range
        100 – 256000
      • VolumeSize IntegerSize in GiB. Must be at least the AMI snapshot's size. Replacement — CloudFormation creates a new resource and deletes the old one

        Size in GiB. Must be at least the AMI snapshot's size.

        Type
        Integer
        Required
        No
        Update behaviour
        Replacement
        Range
        1 – 65536

        Example values

        • 30
      • VolumeType StringVolume type. Replacement — CloudFormation creates a new resource and deletes the old one
        gp3 is cheaper than gp2 per gigabyte, has a 3,000 IOPS baseline independent of size, and lets throughput be set separately. There is no workload where gp2 is the better choice on a new volume; the default here is simply old.
        Type
        String
        Required
        No
        Update behaviour
        Replacement
        Default
        gp2

        Allowed values

        • gp2
        • gp3
        • io1
        • io2
        • st1
        • sc1
        • standard
      • Encrypted BooleanWhether the volume is encrypted at rest. Replacement — CloudFormation creates a new resource and deletes the old one
        A volume restored from an unencrypted snapshot cannot be encrypted at launch. Enable EBS encryption by default at the account level and the question stops arising.
        Type
        Boolean
        Required
        No
        Update behaviour
        Replacement
      • DeleteOnTermination BooleanWhether the volume is destroyed with the instance. Replacement — CloudFormation creates a new resource and deletes the old one

        Whether the volume is destroyed with the instance.

        Type
        Boolean
        Required
        No
        Update behaviour
        Replacement
        Default
        true
      • KmsKeyId StringKMS key for encryption. Requires `Encrypted`. Replacement — CloudFormation creates a new resource and deletes the old one

        KMS key for encryption. Requires `Encrypted`.

        Type
        String
        Required
        No
        Update behaviour
        Replacement
      • SnapshotId StringSnapshot to create the volume from. Replacement — CloudFormation creates a new resource and deletes the old one

        Snapshot to create the volume from.

        Type
        String
        Required
        No
        Update behaviour
        Replacement

        Example values

        • snap-0abcdef1234567890
      • Throughput IntegerThroughput in MiB/s. Only valid for `gp3`. Replacement — CloudFormation creates a new resource and deletes the old one

        Throughput in MiB/s. Only valid for `gp3`.

        Type
        Integer
        Required
        No
        Update behaviour
        Replacement
        Range
        125 – 1000
    • NoDevice JSONSuppress a device the AMI would otherwise map. Written as an empty object. Replacement — CloudFormation creates a new resource and deletes the old one

      Suppress a device the AMI would otherwise map. Written as an empty object.

      Type
      JSON
      Required
      No
      Update behaviour
      Replacement
    • VirtualName StringInstance store volume name, such as `ephemeral0`. Replacement — CloudFormation creates a new resource and deletes the old one

      Instance store volume name, such as `ephemeral0`.

      Type
      String
      Required
      No
      Update behaviour
      Replacement
  • DisableApiTermination BooleanPrevent termination through the EC2 API. No interruption — updates in place

    Prevent termination through the EC2 API.

    Type
    Boolean
    Required
    No
    Update behaviour
    No interruption
    Default
    false
  • EbsOptimized BooleanDedicated throughput between the instance and EBS. Some interruption — the resource may be briefly unavailable
    Enabled by default and not billable on current-generation types. The property exists for older families where it was optional and charged.
    Type
    Boolean
    Required
    No
    Update behaviour
    Some interruption
  • IamInstanceProfile StringName of the instance profile granting the instance a role. No interruption — updates in place
    Takes an instance profile, not a role. Every role used by EC2 needs a profile wrapping it; the console creates one implicitly and CloudFormation does not, which is why AWS::IAM::InstanceProfile exists as its own resource.
    Type
    String
    Required
    No
    Update behaviour
    No interruption

    Example values

    • acme-payments-instance-profile
  • InstanceInitiatedShutdownBehavior StringWhat happens when the guest OS shuts itself down. No interruption — updates in place

    What happens when the guest OS shuts itself down.

    Type
    String
    Required
    No
    Update behaviour
    No interruption
    Default
    stop

    Allowed values

    • stop
    • terminate
  • KeyName StringName of the EC2 key pair injected for SSH access. Replacement — CloudFormation creates a new resource and deletes the old one Create-only

    Name of the EC2 key pair injected for SSH access.

    Type
    String
    Required
    No
    Update behaviour
    Replacement

    Example values

    • acme-ops-2026
  • LaunchTemplate LaunchTemplateSpecificationLaunch from a template, with any properties set here overriding it. Replacement — CloudFormation creates a new resource and deletes the old one Create-only
    The template supplies defaults; properties set directly on this resource win. Mixing the two is legal and consistently confusing — pick one place to define each setting.
    Type
    LaunchTemplateSpecification
    Required
    No
    Update behaviour
    Replacement

    LaunchTemplateSpecification properties

    • Version StringTemplate version, or `$Latest` / `$Default`. Required Replacement — CloudFormation creates a new resource and deletes the old one

      Template version, or `$Latest` / `$Default`.

      Type
      String
      Required
      Yes
      Update behaviour
      Replacement

      Example values

      • $Latest
    • LaunchTemplateId StringID of the launch template. Conditional Replacement — CloudFormation creates a new resource and deletes the old one

      ID of the launch template.

      Type
      String
      Required
      ConditionalExactly one of LaunchTemplateId or LaunchTemplateName is required.
      Update behaviour
      Replacement
    • LaunchTemplateName StringName of the launch template. Conditional Replacement — CloudFormation creates a new resource and deletes the old one

      Name of the launch template.

      Type
      String
      Required
      ConditionalExactly one of LaunchTemplateId or LaunchTemplateName is required.
      Update behaviour
      Replacement
  • MetadataOptions MetadataOptionsInstance metadata service configuration, including IMDSv2 enforcement. No interruption — updates in place

    Instance metadata service configuration, including IMDSv2 enforcement.

    Type
    MetadataOptions
    Required
    No
    Update behaviour
    No interruption

    MetadataOptions properties

    • HttpTokens StringWhether IMDSv2 session tokens are mandatory. No interruption — updates in place
      Set this to required. IMDSv1 is a plain unauthenticated GET, which means any server-side request forgery in an application on the instance can read the instance’s IAM credentials — the mechanism behind several well-known breaches.
      Type
      String
      Required
      No
      Update behaviour
      No interruption
      Default
      optional

      Allowed values

      • optional
      • required
    • HttpPutResponseHopLimit IntegerIP TTL for metadata responses, which limits how far a token can travel. No interruption — updates in place
      The default of 1 stops a container on the instance from reaching the metadata service, because the packet crosses the bridge and expires. Containerised workloads that legitimately need instance credentials require 2 — and a workload that needs its own identity should use a task or pod role instead.
      Type
      Integer
      Required
      No
      Update behaviour
      No interruption
      Default
      1
      Range
      1 – 64
    • HttpEndpoint StringWhether the metadata service is reachable at all. No interruption — updates in place

      Whether the metadata service is reachable at all.

      Type
      String
      Required
      No
      Update behaviour
      No interruption
      Default
      enabled

      Allowed values

      • enabled
      • disabled
  • Monitoring BooleanEnable one-minute CloudWatch metrics instead of five-minute. No interruption — updates in place
    Billed per instance per month. Worth it for anything autoscaling on CPU, where five-minute granularity means reacting to load ten minutes late.
    Type
    Boolean
    Required
    No
    Update behaviour
    No interruption
    Default
    false
  • PrivateIpAddress StringA specific private address within the subnet. Replacement — CloudFormation creates a new resource and deletes the old one Create-only
    The address must be inside the subnet’s CIDR and outside the five reserved addresses AWS holds in every subnet — the first four and the last.
    Type
    String
    Required
    No
    Update behaviour
    Replacement

    Example values

    • 10.0.1.42
  • PropagateTagsToVolumeOnCreation BooleanCopy the instance's tags onto volumes created at launch. Replacement — CloudFormation creates a new resource and deletes the old one Create-only
    Applies at launch only. Volumes attached later, and tags added later, are not propagated.
    Type
    Boolean
    Required
    No
    Update behaviour
    Replacement
    Default
    false
  • SecurityGroupIds Array of StringSecurity groups attached to the primary network interface. No interruption — updates in place
    Use this, not SecurityGroups. The latter takes group names and only works outside a VPC, which has not been a real option since 2013.
    Type
    Array of String
    Required
    No
    Update behaviour
    No interruption

    Example values

    • ["sg-0abcdef1234567890"]
  • SourceDestCheck BooleanWhether the instance may send and receive traffic not addressed to it. No interruption — updates in place
    Must be disabled for any instance acting as a NAT device, router, or transparent proxy. Otherwise leave it on.
    Type
    Boolean
    Required
    No
    Update behaviour
    No interruption
    Default
    true
  • Tags Array of TagTags applied to the instance. No interruption — updates in place

    Tags applied to the instance.

    Type
    Array of Tag
    Required
    No
    Update behaviour
    No interruption
    Items
    0 – 50

    Tag properties

    • Key StringTag key. Required No interruption — updates in place

      Tag key.

      Type
      String
      Required
      Yes
      Update behaviour
      No interruption
      Length
      1 – 128
    • Value StringTag value. Required No interruption — updates in place

      Tag value.

      Type
      String
      Required
      Yes
      Update behaviour
      No interruption
      Length
      0 – 256
  • Tenancy StringWhether the instance shares hardware with other accounts. Replacement — CloudFormation creates a new resource and deletes the old one Create-only
    dedicated and host carry substantial cost premiums and exist for licensing and compliance requirements, not for performance.
    Type
    String
    Required
    No
    Update behaviour
    Replacement
    Default
    default

    Allowed values

    • default
    • dedicated
    • host
  • UserData StringBase64-encoded data made available to the instance at first boot. Replacement — CloudFormation creates a new resource and deletes the old one Create-only
    In CloudFormation, wrap the script in Fn::Base64; the property expects encoded content and does not encode for you.
    Type
    String
    Required
    No
    Update behaviour
    Replacement
updates in place some interruption replacement create-only read-only write-only

Return values

What other resources can read from this one
Ref
Returns the instance ID.

!Ref MyResource → i-0abcdef1234567890

Fn::GetAtt attributes

AttributeTypeDescriptionExample value
AvailabilityZoneStringThe zone the instance actually launched in.us-west-2a
PrivateDnsNameStringInternal DNS name, resolvable within the VPC.ip-10-0-1-42.us-west-2.compute.internal
PrivateIpStringPrimary private IPv4 address.10.0.1.42
PublicDnsNameStringPublic DNS name, if the VPC has DNS hostnames enabled.ec2-203-0-113-42.us-west-2.compute.amazonaws.com
PublicIpStringPublic IPv4 address, if one was assigned. Empty for instances in private subnets, and it changes on stop/start unless it is an Elastic IP.203.0.113.42

Required permissions

For the principal running the stack operation

create

  • ec2:RunInstances
  • ec2:DescribeInstances
  • ec2:CreateTags
  • iam:PassRole

read

  • ec2:DescribeInstances
  • ec2:DescribeInstanceAttribute
  • ec2:DescribeTags

update

  • ec2:ModifyInstanceAttribute
  • ec2:StopInstances
  • ec2:StartInstances
  • ec2:CreateTags
  • ec2:DeleteTags
  • ec2:ModifyInstanceMetadataOptions

delete

  • ec2:TerminateInstances
  • ec2:DescribeInstances

list

  • ec2:DescribeInstances
{
  "Statement": [
    {
      "Action": [
        "ec2:CreateTags",
        "ec2:DeleteTags",
        "ec2:DescribeInstanceAttribute",
        "ec2:DescribeInstances",
        "ec2:DescribeTags",
        "ec2:ModifyInstanceAttribute",
        "ec2:ModifyInstanceMetadataOptions",
        "ec2:RunInstances",
        "ec2:StartInstances",
        "ec2:StopInstances",
        "ec2:TerminateInstances",
        "iam:PassRole"
      ],
      "Effect": "Allow",
      "Resource": "*",
      "Sid": "ManageResource"
    }
  ],
  "Version": "2012-10-17"
}