

# Security in Amazon EC2
<a name="ec2-security"></a>

Cloud security at AWS is the highest priority. As an AWS customer, you benefit from a data center and network architecture that are built to meet the requirements of the most security-sensitive organizations.

Security is a shared responsibility between AWS and you. The [shared responsibility model](https://aws.amazon.com/compliance/shared-responsibility-model/) describes this as security of the cloud and security in the cloud:
+ **Security of the cloud** – AWS is responsible for protecting the infrastructure that runs AWS services in the AWS Cloud. AWS also provides you with services that you can use securely. Third-party auditors regularly test and verify the effectiveness of our security as part of the [AWS Compliance Programs](https://aws.amazon.com/compliance/programs/). To learn about the compliance programs that apply to Amazon EC2, see [AWS Services in Scope by Compliance Program](https://aws.amazon.com/compliance/services-in-scope/).
+ **Security in the cloud** – Your responsibility includes the following areas:
  + Controlling network access to your instances, for example, through configuring your VPC and security groups. For more information, see [Controlling network traffic](infrastructure-security.md#control-network-traffic).
  + Managing the credentials used to connect to your instances.
  + Managing the guest operating system and software deployed to the guest operating system, including updates and security patches. For more information, see [Update management for Amazon EC2 instances](update-management.md).
  + Configuring the IAM roles that are attached to the instance and the permissions associated with those roles. For more information, see [IAM roles for Amazon EC2](iam-roles-for-amazon-ec2.md).

This documentation helps you understand how to apply the shared responsibility model when using Amazon EC2. It shows you how to configure Amazon EC2 to meet your security and compliance objectives. You also learn how to use other AWS services that help you to monitor and secure your Amazon EC2 resources.

**Topics**
+ [Data protection](data-protection.md)
+ [Infrastructure security](infrastructure-security.md)
+ [Resilience](disaster-recovery-resiliency.md)
+ [Compliance validation](compliance-validation.md)
+ [Identity and access management](security-iam.md)
+ [Update management](update-management.md)
+ [Best practices for Windows instances](ec2-windows-security-best-practices.md)
+ [Key pairs](ec2-key-pairs.md)
+ [Security groups](ec2-security-groups.md)
+ [NitroTPM](nitrotpm.md)
+ [EC2 instance attestation](nitrotpm-attestation.md)
+ [Credential Guard for Windows instances](credential-guard.md)
+ [AWS PrivateLink](interface-vpc-endpoints.md)

# Data protection in Amazon EC2
<a name="data-protection"></a>

The AWS [shared responsibility model](https://aws.amazon.com/compliance/shared-responsibility-model/) applies to data protection in Amazon Elastic Compute Cloud. As described in this model, AWS is responsible for protecting the global infrastructure that runs all of the AWS Cloud. You are responsible for maintaining control over your content that is hosted on this infrastructure. You are also responsible for the security configuration and management tasks for the AWS services that you use. For more information about data privacy, see the [Data Privacy FAQ](https://aws.amazon.com/compliance/data-privacy-faq/). For information about data protection in Europe, see the [AWS Shared Responsibility Model and GDPR](https://aws.amazon.com/blogs/security/the-aws-shared-responsibility-model-and-gdpr/) blog post on the *AWS Security Blog*.

For data protection purposes, we recommend that you protect AWS account credentials and set up individual users with AWS IAM Identity Center or AWS Identity and Access Management (IAM). That way, each user is given only the permissions necessary to fulfill their job duties. We also recommend that you secure your data in the following ways:
+ Use multi-factor authentication (MFA) with each account.
+ Use SSL/TLS to communicate with AWS resources. We require TLS 1.2 and recommend TLS 1.3.
+ Set up API and user activity logging with AWS CloudTrail. For information about using CloudTrail trails to capture AWS activities, see [Working with CloudTrail trails](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-trails.html) in the *AWS CloudTrail User Guide*.
+ Use AWS encryption solutions, along with all default security controls within AWS services.
+ Use advanced managed security services such as Amazon Macie, which assists in discovering and securing sensitive data that is stored in Amazon S3.
+ If you require FIPS 140-3 validated cryptographic modules when accessing AWS through a command line interface or an API, use a FIPS endpoint. For more information about the available FIPS endpoints, see [Federal Information Processing Standard (FIPS) 140-3](https://aws.amazon.com/compliance/fips/).

We strongly recommend that you never put confidential or sensitive information, such as your customers' email addresses, into tags or free-form text fields such as a **Name** field. This includes when you work with Amazon EC2 or other AWS services using the console, API, AWS CLI, or AWS SDKs. Any data that you enter into tags or free-form text fields used for names may be used for billing or diagnostic logs. If you provide a URL to an external server, we strongly recommend that you do not include credentials information in the URL to validate your request to that server.

**Topics**
+ [Amazon EBS data security](#ebs-data-security)
+ [Encryption at rest](#encryption-rest)
+ [Encryption in transit](#encryption-transit)

## Amazon EBS data security
<a name="ebs-data-security"></a>

Amazon EBS volumes are presented to you as raw, unformatted block devices. These devices are logical devices that are created on the EBS infrastructure and the Amazon EBS service ensures that the devices are logically empty (that is, the raw blocks are zeroed or they contain cryptographically pseudorandom data) prior to any use or re-use by a customer.

If you have procedures that require that all data be erased using a specific method, either after or before use (or both), such as those detailed in **DoD 5220.22-M** (National Industrial Security Program Operating Manual) or **NIST 800-88** (Guidelines for Media Sanitization), you have the ability to do so on Amazon EBS. That block-level activity will be reflected down to the underlying storage media within the Amazon EBS service.

## Encryption at rest
<a name="encryption-rest"></a>

**EBS volumes**  
Amazon EBS encryption is an encryption solution for your EBS volumes and snapshots. It uses AWS KMS keys. For more information, see [Amazon EBS encryption](https://docs.aws.amazon.com/ebs/latest/userguide/ebs-encryption.html) in the *Amazon EBS User Guide*.

[Windows instances] You can also use Microsoft EFS and NTFS permissions for folder- and file-level encryption.

**Instance store volumes**  
The data on NVMe instance store volumes is encrypted using an XTS-AES-256 cipher, implemented on a hardware module on the instance. The keys used to encrypt data that's written to locally-attached NVMe storage devices are per-customer, and per volume. The keys are generated by, and only reside within, the hardware module, which is inaccessible to AWS personnel. The encryption keys are destroyed when the instance is stopped or terminated and cannot be recovered. You cannot disable this encryption and you cannot provide your own encryption key.

The data on HDD instance store volumes on H1, D3, and D3en instances is encrypted using XTS-AES-256 and one-time keys.

When you stop, hibernate, or terminate an instance, every block of storage in the instance store volume is reset. Therefore, your data cannot be accessed through the instance store of another instance.

**Memory**

Memory encryption is enabled on the following instances:
+ Instances with AWS Graviton2 or later AWS Graviton processors support always-on memory encryption. The encryption keys are securely generated within the host system, do not leave the host system, and are destroyed when the host is rebooted or powered down. For more information, see [AWS Graviton Processors](https://aws.amazon.com/ec2/graviton/).
+ Instances with 3rd generation Intel Xeon Scalable processors (Ice Lake), such as M6i instances, and 4th generation Intel Xeon Scalable processors (Sapphire Rapids), such as M7i instances. These processors support always-on memory encryption using Intel Total Memory Encryption (TME).
+ Instances with 3rd generation AMD EPYC processors (Milan), such as M6a instances, and 4th generation AMD EPYC processors (Genoa), such as M7a instances. These processors support always-on memory encryption using AMD Secure Memory Encryption (SME).
+ AMD Secure Encrypted Virtualization-Secure Nested Paging (SEV-SNP) is supported for some AMD-based instance types. For more information, see [Find EC2 instance types that support AMD SEV-SNP](snp-find-instance-types.md).

## Encryption in transit
<a name="encryption-transit"></a>

**Encryption at the physical layer**  
All data flowing across AWS Regions over the AWS global network is automatically encrypted at the physical layer before it leaves AWS secured facilities. All traffic between AZs is encrypted. Additional layers of encryption, including those listed in this section, may provide additional protections.

**Encryption provided by Amazon VPC peering and Transit Gateway cross-Region peering**  
All cross-Region traffic that uses Amazon VPC peering and Transit Gateway peering is automatically bulk-encrypted when it exits a Region. An additional layer of encryption is automatically provided at the physical layer for all traffic before it leaves AWS secured facilities, as previously noted in this section.

**Encryption between instances**  
AWS provides secure and private connectivity between EC2 instances of all types. In addition, some instance types use the offload capabilities of the underlying Nitro System hardware to automatically encrypt in-transit traffic between instances. This encryption uses Authenticated Encryption with Associated Data (AEAD) algorithms, with 256-bit encryption. There is no impact on network performance. To support this additional in-transit traffic encryption between instances, the following requirements must be met:
+ The instances use the following instance types:
  + **General purpose**: M5dn, M5n, M5zn, M6a, M6i, M6id, M6idn, M6in, M7a, M7g, M7gd, M7i, M7i-flex, M8a, M8azn, M8g, M8gb, M8gd, M8gn, M8i, M8id, M8i-flex, Mac-m4, Mac-m4pro
  + **Compute optimized:** C5n, C6a, C6gn, C6i, C6id, C6in, C7a, C7g, C7gd, C7gn, C7i, C7i-flex, C8a, C8g, C8gb, C8gd, C8gn, C8i, C8ib, C8id, C8in, C8i-flex
  + **Memory optimized:** R5dn, R5n, R6a, R6i, R6id, R6idn, R6in, R7a, R7g, R7gd, R7i, R7iz, R8a, R8g, R8gb, R8gd, R8gn, R8i, R8id, R8i-flex, U-3tb1, U-6tb1, U-9tb1, U-12tb1, U-18tb1, U-24tb1, U7i-6tb, U7i-8tb, U7i-12tb, U7in-16tb, U7in-24tb, U7in-32tb, U7inh-32tb, X2idn, X2iedn, X2iezn, X8g, X8aedz, X8i
  + **Storage optimized:** D3, D3en, I3en, I4g, I4i, I7i, I7ie, I8g, I8ge, Im4gn, Is4gen
  + **Accelerated computing:** DL1, DL2q, F2, G4ad, G4dn, G5, G6, G6e, G6f, Gr6, Gr6f, G7e, Inf1, Inf2, P3dn, P4d, P4de, P5, P5e, P5en, P6-B200, P6-B300, P6e-GB200, Trn1, Trn1n, Trn2, Trn2u, VT1
  + **High-performance computing:** Hpc6a, Hpc6id, Hpc7a, Hpc7g, Hpc8a
+ The instances are in the same Region.
+ The instances are in the same VPC or peered VPCs, and the traffic does not pass through a virtual network device or service, such as a load balancer or a transit gateway.

An additional layer of encryption is automatically provided at the physical layer for all traffic before it leaves AWS secured facilities, as previously noted in this section.

**To view the instance types that encrypt in-transit traffic between instances using the AWS CLI**  
Use the following [ describe-instance-types](https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-instance-types.html) command.

```
aws ec2 describe-instance-types \
    --filters Name=network-info.encryption-in-transit-supported,Values=true \
    --query "InstanceTypes[*].[InstanceType]" \
    --output text | sort
```

**Encryption to and from AWS Outposts**  
An Outpost creates special network connections called *service links* to its AWS home Region and, optionally, private connectivity to a VPC subnet that you specify. All traffic over those connection is fully encrypted. For more information, see [Connectivity through service links](https://docs.aws.amazon.com/outposts/latest/userguide/region-connectivity.html#service-links) and [Encryption in transit](https://docs.aws.amazon.com/outposts/latest/userguide/data-protection.html#encryption-transit) in the *AWS Outposts User Guide*.

**Remote access encryption**  
The SSH and RDP protocols provides secure communications channels for remote access to your instances, whether directly or through EC2 Instance Connect. Remote access to your instances using AWS Systems Manager Session Manager or the Run Command is encrypted using TLS 1.2, and requests to create a connection are signed using [SigV4](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv.html), and authenticated and authorized by [AWS Identity and Access Management](https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction.html).

It is your responsibility to use an encryption protocol, such as Transport Layer Security (TLS), to encrypt sensitive data in transit between clients and your Amazon EC2 instances.

(Windows instances) Make sure to allow only encrypted connections between EC2 instances and the AWS API endpoints or other sensitive remote network services. You can enforce this through an outbound security group or [Windows Firewall](https://learn.microsoft.com/en-us/windows/security/operating-system-security/network-security/windows-firewall/) rules.

# Infrastructure security in Amazon EC2
<a name="infrastructure-security"></a>

As a managed service, Amazon Elastic Compute Cloud is protected by AWS global network security. For information about AWS security services and how AWS protects infrastructure, see [AWS Cloud Security](https://aws.amazon.com/security/). To design your AWS environment using the best practices for infrastructure security, see [Infrastructure Protection](https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/infrastructure-protection.html) in *Security Pillar AWS Well‐Architected Framework*.

You use AWS published API calls to access Amazon EC2 through the network. Clients must support the following:
+ Transport Layer Security (TLS). We require TLS 1.2 and recommend TLS 1.3.
+ Cipher suites with perfect forward secrecy (PFS) such as DHE (Ephemeral Diffie-Hellman) or ECDHE (Elliptic Curve Ephemeral Diffie-Hellman). Most modern systems such as Java 7 and later support these modes.

For more information, see [ Infrastructure Protection](https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/infrastructure-protection.html) in the *Security Pillar – AWS Well-Architected Framework*.

## Network isolation
<a name="network-isolation"></a>

A virtual private cloud (VPC) is a virtual network in your own logically isolated area in the AWS Cloud. Use separate VPCs to isolate infrastructure by workload or organizational entity.

A subnet is a range of IP addresses in a VPC. When you launch an instance, you launch it into a subnet in your VPC. Use subnets to isolate the tiers of your application (for example, web, application, and database) within a single VPC. Use private subnets for your instances if they should not be accessed directly from the internet.

To call the Amazon EC2 API from your VPC using private IP addresses, use AWS PrivateLink. For more information, see [Access Amazon EC2 using an interface VPC endpoint](interface-vpc-endpoints.md).

## Isolation on physical hosts
<a name="physical-isolation"></a>

Different EC2 instances on the same physical host are isolated from each other as though they are on separate physical hosts. The hypervisor isolates CPU and memory, and the instances are provided virtualized disks instead of access to the raw disk devices.

When you stop or terminate an instance, the memory allocated to it is scrubbed (set to zero) by the hypervisor before it is allocated to a new instance, and every block of storage is reset. This ensures that your data is not unintentionally exposed to another instance.

Network MAC addresses are dynamically assigned to instances by the AWS network infrastructure. IP addresses are either dynamically assigned to instances by the AWS network infrastructure, or assigned by an EC2 administrator through authenticated API requests. The AWS network allows instances to send traffic only from the MAC and IP addresses assigned to them. Otherwise, the traffic is dropped.

By default, an instance cannot receive traffic that is not specifically addressed to it. If you need to run network address translation (NAT), routing, or firewall services on your instance, you can disable source/destination checking for the network interface.

## Controlling network traffic
<a name="control-network-traffic"></a>

Consider the following options for controlling network traffic to your EC2 instances:
+ Restrict access to your instances using [security groups](ec2-security-groups.md). Configure rules that allow the minimum required network traffic. For example, you can allow traffic only from the address ranges for your corporate network or only for specific protocols, such as HTTPS. For Windows instances, allow Windows management traffic and minimal outbound connections.
+ Leverage security groups as the primary mechanism for controlling network access to Amazon EC2 instances. When necessary, use network ACLs sparingly to provide stateless, coarse-grain network control. Security groups are more versatile than network ACLs due to their ability to perform stateful packet filtering and create rules that reference other security groups. However, network ACLs can be effective as a secondary control for denying a specific subset of traffic or providing high-level subnet guard rails. Also, because network ACLs apply to an entire subnet, they can be used as defense-in-depth in case an instance is ever launched unintentionally without a correct security group.
+ [Windows instances] Centrally manage Windows Firewall settings with Group Policy Objects (GPO) to further enhance network controls. Customers often use the Windows Firewall for further visibility into network traffic and to complement security group filters, creating advanced rules to block specific applications from accessing the network or to filter traffic from a subset IP addresses. For example, the Windows Firewall can limit access to the EC2 metadata service IP address to specific users or applications. Alternatively, a public-facing service might use security groups to restrict traffic to specific ports and the Windows Firewall to maintain a list of explicitly blocked IP addresses.
+ Use private subnets for your instances if they should not be accessed directly from the internet. Use a bastion host or NAT gateway for internet access from an instance in a private subnet.
+ [Windows instances] Use secure administration protocols like RDP encapsulation over SSL/TLS. The Remote Desktop Gateway Quick Start provides best practices for deploying remote desktop gateway, including configuring RDP to use SSL/TLS.
+ [Windows instances] Use Active Directory or Directory Service to tightly and centrally control and monitor interactive user and group access to Windows instances, and avoid local user permissions. Also avoid using Domain Administrators and instead create more granular, application-specific role-based accounts. Just Enough Administration (JEA) allows changes to Windows instances to be managed without interactive or administrator access. In addition, JEA enables organizations to lock down administrative access to the subset of Windows PowerShell commands required for instance administration. For additional information, see the section on "Managing OS-level Access to Amazon EC2" in the [AWS Security Best Practices](https://d1.awsstatic.com/whitepapers/Security/AWS_Security_Best_Practices.pdf) whitepaper.
+ [Windows instances] System Administrators should use Windows accounts with limited access to perform daily activities, and only elevate access when necessary to perform specific configuration changes. Additionally, only access Windows instances directly when absolutely necessary. Instead, leverage central configuration management systems such as EC2 Run Command, Systems Center Configuration Manager (SCCM), Windows PowerShell DSC, or Amazon EC2 Systems Manager (SSM) to push changes to Windows servers.
+ Configure Amazon VPC subnet route tables with the minimal required network routes. For example, place only Amazon EC2 instances that require direct Internet access into subnets with routes to an internet gateway, and place only Amazon EC2 instances that need direct access to internal networks into subnets with routes to a virtual private gateway.
+ Consider using additional security groups or network interfaces to control and audit Amazon EC2 instance management traffic separately from regular application traffic. This approach allows customers to implement special IAM policies for change control, making it easier to audit changes to security group rules or automated rule-verification scripts. Using multiple network interfaces also provides additional options for controlling network traffic, including the ability to create host-based routing policies or leverage different VPC subnet routing rules based on the assigned subnet of the network interface.
+ Use AWS Virtual Private Network or Direct Connect to establish private connections from your remote networks to your VPCs. For more information, see [Network-to-Amazon VPC Connectivity Options](https://docs.aws.amazon.com/whitepapers/latest/aws-vpc-connectivity-options/network-to-amazon-vpc-connectivity-options.html).
+ Use [VPC Flow Logs](https://docs.aws.amazon.com/vpc/latest/userguide/flow-logs.html) to monitor the traffic that reaches your instances.
+ Use [GuardDuty Malware Protection](https://docs.aws.amazon.com/guardduty/latest/ug/malware-protection.html) to identify suspicious behavior indicative of malicious software on your instances that might compromise your workload, repurpose resources for malicious use, and gain unauthorized access to your data.
+ Use [GuardDuty Runtime Monitoring](https://docs.aws.amazon.com/guardduty/latest/ug/runtime-monitoring.html) to identify and respond to potential threats to your instances. For more information, see [How Runtime Monitoring works with Amazon EC2 instances](https://docs.aws.amazon.com/guardduty/latest/ug/how-runtime-monitoring-works-ec2.html).
+ Use [AWS Security Hub CSPM](https://docs.aws.amazon.com/securityhub/latest/userguide/), [Reachability Analyzer](https://docs.aws.amazon.com/vpc/latest/reachability/), or [Network Access Analyzer](https://docs.aws.amazon.com/vpc/latest/network-access-analyzer/) to check for unintended network accessibility from your instances.
+ Use [EC2 Instance Connect](connect-linux-inst-eic.md) to connect to your instances using Secure Shell (SSH) without the need to share and manage SSH keys.
+ Use [AWS Systems Manager Session Manager](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager.html) to access your instances remotely instead of opening inbound SSH or RDP ports and managing key pairs.
+ Use [AWS Systems Manager Run Command](https://docs.aws.amazon.com/systems-manager/latest/userguide/run-command.html) to automate common administrative tasks instead of connecting to your instances.
+ [Windows instances] Many of the Windows OS roles and Microsoft business applications also provide enhanced functionality such as IP Address Range restrictions within IIS, TCP/IP filtering policies in Microsoft SQL Server, and connection filter policies in Microsoft Exchange. Network restriction functionality within the application layer can provide additional layers of defense for critical business application servers.

Amazon VPC supports additional network security controls, such as gateways, proxy servers, and network monitoring options. For more information, see [Control network traffic](https://docs.aws.amazon.com/vpc/latest/userguide/infrastructure-security.html#control-network-traffic) in the *Amazon VPC User Guide*.

# Resilience in Amazon EC2
<a name="disaster-recovery-resiliency"></a>

The AWS global infrastructure is built around AWS Regions and Availability Zones. Regions provide multiple physically separated and isolated Availability Zones, which are connected through low-latency, high-throughput, and highly redundant networking. With Availability Zones, you can design and operate applications and databases that automatically fail over between zones without interruption. Availability Zones are more highly available, fault tolerant, and scalable than traditional single or multiple data center infrastructures.

If you need to replicate your data or applications over greater geographic distances, use AWS Local Zones. An AWS Local Zone is an extension of an AWS Region in geographic proximity to your users. Local Zones have their own connections to the internet and support Direct Connect. Like all AWS Regions, AWS Local Zones are completely isolated from other AWS Zones.

If you need to replicate your data or applications in an AWS Local Zone, AWS recommends that you use one of the following zones as the failover zone:
+ Another Local Zone
+ An Availability Zone in the Region that is not the parent zone. You can use the [describe-availability-zones](https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-availability-zones.html) command to view the parent zone.

For more information about AWS Regions and Availability Zones, see [AWS Global Infrastructure](https://aws.amazon.com/about-aws/global-infrastructure/).

In addition to the AWS global infrastructure, Amazon EC2 offers the following features to support your data resiliency:
+ Copying AMIs across Regions
+ Copying EBS snapshots across Regions
+ Automating EBS-backed AMIs using Amazon Data Lifecycle Manager
+ Automating EBS snapshots using Amazon Data Lifecycle Manager
+ Maintaining the health and availability of your fleet using Amazon EC2 Auto Scaling
+ Distributing incoming traffic across multiple instances in a single Availability Zone or multiple Availability Zones using Elastic Load Balancing

# Compliance validation for Amazon EC2
<a name="compliance-validation"></a>

To learn whether an AWS service is within the scope of specific compliance programs, see [AWS services in Scope by Compliance Program](https://aws.amazon.com/compliance/services-in-scope/) and choose the compliance program that you are interested in. For general information, see [AWS Compliance Programs](https://aws.amazon.com/compliance/programs/).

You can download third-party audit reports using AWS Artifact. For more information, see [Downloading Reports in AWS Artifact](https://docs.aws.amazon.com/artifact/latest/ug/downloading-documents.html).

Your compliance responsibility when using AWS services is determined by the sensitivity of your data, your company's compliance objectives, and applicable laws and regulations. For more information about your compliance responsibility when using AWS services, see [AWS Security Documentation](https://docs.aws.amazon.com/security/).

# Identity and access management for Amazon EC2
<a name="security-iam"></a>

AWS Identity and Access Management (IAM) is an AWS service that helps an administrator securely control access to AWS resources. IAM administrators control who can be *authenticated* (signed in) and *authorized* (have permissions) to use Amazon EC2 resources. IAM is an AWS service that you can use with no additional charge.

Your security credentials identify you to services in AWS and grant you access to AWS resources, such as your Amazon EC2 resources. You can use features of Amazon EC2 and IAM to allow other users, services, and applications to use your Amazon EC2 resources without sharing your security credentials. You can use IAM to control how other users use resources in your AWS account, and you can use security groups to control access to your Amazon EC2 instances. You can choose to allow full or limited use of your Amazon EC2 resources.

If you are a developer, you can use IAM roles to manage the security credentials needed by the applications that you run on your EC2 instances. After you attach an IAM role to your instance, your applications running on the instance can retrieve the credentials from the Instance Metadata Service (IMDS).

For best practices for securing your AWS resources using IAM, see [Security best practices in IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html) in the *IAM User Guide*.

**Topics**
+ [Identity-based policies for Amazon EC2](iam-policies-for-amazon-ec2.md)
+ [Example policies to control access the Amazon EC2 API](ExamplePolicies_EC2.md)
+ [Example policies to control access to the Amazon EC2 console](iam-policies-ec2-console.md)
+ [AWS managed policies for Amazon EC2](security-iam-awsmanpol.md)
+ [IAM roles for Amazon EC2](iam-roles-for-amazon-ec2.md)

# Identity-based policies for Amazon EC2
<a name="iam-policies-for-amazon-ec2"></a>

By default, users don't have permission to create or modify Amazon EC2 resources, or perform tasks using the Amazon EC2 API, Amazon EC2 console, or CLI. To allow users to create or modify resources and perform tasks, you must create IAM policies that grant users permission to use the specific resources and API actions they'll need, and then attach those policies to the users, groups, or IAM roles that require those permissions.

When you attach a policy to a user, group of users, or role it allows or denies the users permission to perform the specified tasks on the specified resources. For more general information about IAM policies, see [Policies and permissions in IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html) in the *IAM User Guide*. For more information about managing and creating IAM policies, see [Manage IAM policies](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage.html).

An IAM policy must grant or deny permissions to use one or more Amazon EC2 actions. It must also specify the resources that can be used with the action, which can be all resources, or in some cases, specific resources. The policy can also include conditions that you apply to the resource.

To get started, you can check whether the AWS managed policies for Amazon EC2 meet your needs. Otherwise, you can create your own custom policies. For more information, see [AWS managed policies for Amazon EC2](security-iam-awsmanpol.md).

**Topics**
+ [Policy syntax](#policy-syntax)
+ [Actions for Amazon EC2](#UsingWithEC2_Actions)
+ [Supported resource-level permissions for Amazon EC2 API actions](#ec2-supported-iam-actions-resources)
+ [Amazon Resource Names (ARNs) for Amazon EC2](#EC2_ARN_Format)
+ [Condition keys for Amazon EC2](#amazon-ec2-keys)
+ [Control access using attribute-based access](#control-access-with-tags)
+ [Grant permissions to users, groups, and roles](#granting-iam-permissions)
+ [Check that users have the required permissions](#check-required-permissions)

## Policy syntax
<a name="policy-syntax"></a>

An IAM policy is a JSON document that consists of one or more statements. Each statement is structured as follows.

```
{
  "Statement":[{
    "Effect":"effect",
    "Action":"action",
    "Resource":"arn",
    "Condition":{
      "condition":{
        "key":"value"
        }
      }
    }
  ]
}
```

There are various elements that make up a statement:
+ **Effect:** The *effect* can be `Allow` or `Deny`. By default, users don't have permission to use resources and API actions, so all requests are denied. An explicit allow overrides the default. An explicit deny overrides any allows.
+ **Action**: The *action* is the specific API action for which you are granting or denying permission. To learn about specifying *action*, see [Actions for Amazon EC2](#UsingWithEC2_Actions). 
+ **Resource**: The resource that's affected by the action. Some Amazon EC2 API actions allow you to include specific resources in your policy that can be created or modified by the action. You specify a resource using an Amazon Resource Name (ARN) or using the wildcard (\$1) to indicate that the statement applies to all resources. For more information, see [Supported resource-level permissions for Amazon EC2 API actions](#ec2-supported-iam-actions-resources). 
+ **Condition**: Conditions are optional. They can be used to control when your policy is in effect. For more information about specifying conditions for Amazon EC2, see [Condition keys for Amazon EC2](#amazon-ec2-keys).

For more information about policy requirements, see the [IAM JSON policy reference](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies.html) in the *IAM User Guide*. For example IAM policy statements for Amazon EC2, see [Example policies to control access the Amazon EC2 API](ExamplePolicies_EC2.md). 

## Actions for Amazon EC2
<a name="UsingWithEC2_Actions"></a>

In an IAM policy statement, you can specify any API action from any service that supports IAM. For Amazon EC2, use the following prefix with the name of the API action: `ec2:`. For example: `ec2:RunInstances` and `ec2:CreateImage`.

To specify multiple actions in a single statement, separate them with commas as follows:

```
"Action": ["ec2:action1", "ec2:action2"]
```

You can also specify multiple actions using wildcards. For example, you can specify all actions whose name begins with the word "Describe" as follows:

```
"Action": "ec2:Describe*"
```

**Note**  
Currently, the Amazon EC2 Describe\$1 API actions do not support resource-level permissions. For more information about resource-level permissions for Amazon EC2, see [Identity-based policies for Amazon EC2](#iam-policies-for-amazon-ec2).

To specify all Amazon EC2 API actions, use the \$1 wildcard as follows:

```
"Action": "ec2:*"
```

For a list of Amazon EC2 actions, see [Actions defined by Amazon EC2](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonec2.html#amazonec2-actions-as-permissions) in the *Service Authorization Reference*.

## Supported resource-level permissions for Amazon EC2 API actions
<a name="ec2-supported-iam-actions-resources"></a>

*Resource-level permissions* refers to the ability to specify which resources users are allowed to perform actions on. Amazon EC2 has partial support for resource-level permissions. This means that for certain Amazon EC2 actions, you can control when users are allowed to use those actions based on conditions that have to be fulfilled, or specific resources that users are allowed to use. For example, you can grant users permissions to launch instances, but only of a specific type, and only using a specific AMI.

To specify a resource in an IAM policy statement, use its Amazon Resource Name (ARN). For more information about specifying the ARN value, see [Amazon Resource Names (ARNs) for Amazon EC2](#EC2_ARN_Format). If an API action does not support individual ARNs, you must use a wildcard (\$1) to specify that all resources can be affected by the action. 

To see tables that identify which Amazon EC2 API actions support resource-level permissions, and the ARNs and condition keys that you can use in a policy, see [Actions, resources, and condition keys for Amazon EC2](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonec2.html).

Keep in mind that you can apply tag-based resource-level permissions in the IAM policies you use for Amazon EC2 API actions. This gives you better control over which resources a user can create, modify, or use. For more information, see [Grant permission to tag Amazon EC2 resources during creation](supported-iam-actions-tagging.md). 

## Amazon Resource Names (ARNs) for Amazon EC2
<a name="EC2_ARN_Format"></a>

Each IAM policy statement applies to the resources that you specify using their ARNs. 

An ARN has the following general syntax:

```
arn:aws:[service]:[region]:[account-id]:resourceType/resourcePath
```

*service*  
The service (for example, `ec2`).

*region*  
The Region for the resource (for example, `us-east-1`).

*account-id*  
The AWS account ID, with no hyphens (for example, `123456789012`).

*resourceType*  
The type of resource (for example, `instance`).

*resourcePath*  
A path that identifies the resource. You can use the \$1 wildcard in your paths.

For example, you can indicate a specific instance (`i-1234567890abcdef0`) in your statement using its ARN as follows. 

```
"Resource": "arn:aws:ec2:us-east-1:123456789012:instance/i-1234567890abcdef0"
```

You can specify all instances that belong to a specific account by using the \$1 wildcard as follows.

```
"Resource": "arn:aws:ec2:us-east-1:123456789012:instance/*"
```

You can also specify all Amazon EC2 resources that belong to a specific account by using the \$1 wildcard as follows.

```
"Resource": "arn:aws:ec2:us-east-1:123456789012:*"
```

To specify all resources, or if a specific API action does not support ARNs, use the \$1 wildcard in the `Resource` element as follows.

```
"Resource": "*"
```

Many Amazon EC2 API actions involve multiple resources. For example, `AttachVolume` attaches an Amazon EBS volume to an instance, so a user must have permissions to use the volume and the instance. To specify multiple resources in a single statement, separate their ARNs with commas, as follows.

```
"Resource": ["arn1", "arn2"]
```

For a list of ARNs for Amazon EC2 resources, see [Resource types defined by Amazon EC2](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonec2.html#amazonec2-resources-for-iam-policies).

## Condition keys for Amazon EC2
<a name="amazon-ec2-keys"></a>

In a policy statement, you can optionally specify conditions that control when it is in effect. Each condition contains one or more key-value pairs. Condition keys are not case-sensitive. We've defined AWS global condition keys, plus additional service-specific condition keys.

For a list of service-specific condition keys for Amazon EC2, see [Condition keys for Amazon EC2](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonec2.html#amazonec2-policy-keys). Amazon EC2 also implements the AWS global condition keys. For more information, see [Information available in all requests](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_variables.html#policy-vars-infoallreqs) in the *IAM User Guide*.

All Amazon EC2 actions support the `aws:RequestedRegion` and `ec2:Region` condition keys. For more information, see [Example: Restrict access to a specific Region](ExamplePolicies_EC2.md#iam-example-region).

To use a condition key in your IAM policy, use the `Condition` statement. For example, the following policy grants users permission to add and remove inbound and outbound rules for any security group. It uses the `ec2:Vpc` condition key to specify that these actions can only be performed on security groups in a specific VPC.

------
#### [ JSON ]

****  

```
{
"Version":"2012-10-17",		 	 	 
  "Statement":[{
    "Effect":"Allow",
    "Action": [
       "ec2:AuthorizeSecurityGroupIngress",
       "ec2:AuthorizeSecurityGroupEgress",
       "ec2:RevokeSecurityGroupIngress",
       "ec2:RevokeSecurityGroupEgress"],
     "Resource": "arn:aws:ec2:us-east-1:111122223333:security-group/*",
      "Condition": {
        "StringEquals": {
          "ec2:Vpc": "arn:aws:ec2:us-east-1:111122223333:vpc/vpc-11223344556677889"
        }
      }
    }
  ]
}
```

------

If you specify multiple conditions, or multiple keys in a single condition, we evaluate them using a logical AND operation. If you specify a single condition with multiple values for one key, we evaluate the condition using a logical OR operation. For permissions to be granted, all conditions must be met.

You can also use placeholders when you specify conditions. For more information, see [IAM policy elements: Variables and tags](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_variables.html) in the *IAM User Guide*.

**Important**  
Many condition keys are specific to a resource, and some API actions use multiple resources. If you write a policy with a condition key, use the `Resource` element of the statement to specify the resource to which the condition key applies. If not, the policy may prevent users from performing the action at all, because the condition check fails for the resources to which the condition key does not apply. If you do not want to specify a resource, or if you've written the `Action` element of your policy to include multiple API actions, then you must use the `...IfExists` condition type to ensure that the condition key is ignored for resources that do not use it. For more information, see [...IfExists Conditions](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements.html#Conditions_IfExists) in the *IAM User Guide*.

**Topics**
+ [ec2:Attribute condition key](#attribute-key)
+ [ec2:ResourceID condition keys](#imageId-key)
+ [ec2:SourceInstanceARN condition key](#SourceInstanceARN)

### ec2:Attribute condition key
<a name="attribute-key"></a>

The `ec2:Attribute` condition key can be used for conditions that filter access by an attribute of a resource.

This condition key supports only properties that are of a primitive data type (such as strings or integers), or complex **[AttributeValue](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_AttributeValue.html)** objects that contain only a **Value** property (such as the **Description** or **ImdsSupport** objects of the [ ModifyImageAttribute](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_ModifyImageAttribute.html) API action). The condition key can't be used with complex objects that contain multiple properties, such as the **LaunchPermission** object of [ModifyImageAttribute](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_ModifyImageAttribute.html).

For example, the following policy uses the `ec2:Attribute/Description` condition key to filter access by the complex **Description** object of the **ModifyImageAttribute** API action. The condition key allows only requests that modify an image's description to either `Production` or `Development`. 

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "ec2:ModifyImageAttribute",
      "Resource": "arn:aws:ec2:us-east-1::image/ami-*",
      "Condition": {
        "StringEquals": {
          "ec2:Attribute/Description": [
            "Production",
            "Development"
          ]
        }
      }
    }
  ]
}
```

------

The following example policy uses the `ec2:Attribute` condition key to filter access by the primitive **Attribute** property of the ** ModifyImageAttribute** API action. The condition key denies all requests that attempt to modify an image's description.

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Deny",
      "Action": "ec2:ModifyImageAttribute",
      "Resource": "arn:aws:ec2:us-east-1::image/ami-*",
      "Condition": {
        "StringEquals": {
          "ec2:Attribute": "Description"
        }
      }
    }
  ]
}
```

------

### ec2:ResourceID condition keys
<a name="imageId-key"></a>

When using the following `ec2:ResourceID` condition keys with the specified API actions, the condition key value is used to specify the resulting resource that is created by the API action. `ec2:ResourceID` condition keys can't be used to specify a source resource that is specified in the API request. If you use one of the following `ec2:ResourceID` condition keys with a specified API, then you must always specify the wildcard (`*`). If you specify a different value, the condition always resolves to `*` during runtime. For example, to use the `ec2:ImageId` condition key with the **CopyImage** API, then you must specify the condition key as follows:

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "ec2:CopyImage",
      "Resource": "arn:aws:ec2:us-east-1::image/ami-*",
      "Condition": {
        "StringEquals": {
          "ec2:ImageID": "*"
        }
      }
    }
  ]
}
```

------

We recommend that you avoid using these condition keys with these API actions:
+ `ec2:DhcpOptionsID` – `CreateDhcpOptions`
+ `ec2:ImageID` – `CopyImage`, `CreateImage`, `ImportImage`, and `RegisterImage`
+ `ec2:InstanceID` – `RunInstances` and `ImportInstance`
+ `ec2:InternetGatewayID` – `CreateInternetGateway`
+ `ec2:NetworkAclID` – `CreateNetworkAcl`
+ `ec2:NetworkInterfaceID` – `CreateNetworkInterface`
+ `ec2:PlacementGroupName` – `CreatePlacementGroup`
+ `ec2:RouteTableID` – `CreateRouteTable`
+ `ec2:SecurityGroupID` – `CreateSecurityGroup`
+ `ec2:SnapshotID` – `CopySnapshot`, `CreateSnapshot`, `CreateSnapshots`, and `ImportSnapshots`
+ `ec2:SubnetID` – `CreateSubnet`
+ `ec2:VolumeID` – `CreateVolume` and `ImportVolume`
+ `ec2:VpcID` – `CreateVpc`
+ `ec2:VpcPeeringConnectionID` – `CreateVpcPeeringConnection`

To filter access based on specific resource IDs, we recommend that you use the `Resource` policy element as follows.

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "ec2:CopyImage",
      "Resource": "arn:aws:ec2:us-east-1::image/ami-01234567890abcdef"
    }
  ]
}
```

------

### ec2:SourceInstanceARN condition key
<a name="SourceInstanceARN"></a>

Use `ec2:SourceInstanceARN` to specify the ARN of the instance from which a request is made. This is an [AWS global condition key](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html), which means that you can use it with services other than Amazon EC2. For a policy example, see [Example: Allow a specific instance to view resources in other AWS services](ExamplePolicies_EC2.md#iam-example-source-instance).

## Control access using attribute-based access
<a name="control-access-with-tags"></a>

When you create an IAM policy that grants users permission to use EC2 resources, you can include tag information in the `Condition` element of the policy to control access based on tags. This is known as attribute-based access control (ABAC). ABAC provides better control over which resources a user can modify, use, or delete. For more information, see [What is ABAC for AWS?](https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction_attribute-based-access-control.html)

For example, you can create a policy that allows users to terminate an instance, but denies the action if the instance has the tag `environment=production`. To do this, you use the `aws:ResourceTag` condition key to allow or deny access to the resource based on the tags that are attached to the resource.

```
"StringEquals": { "aws:ResourceTag/environment": "production" }
```

To learn whether an Amazon EC2 API action supports controlling access using the `aws:ResourceTag` condition key, see [Actions, resources, and condition keys for Amazon EC2](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonec2.html). Note that the `Describe` actions do not support resource-level permissions, so you must specify them in a separate statement without conditions.

For example IAM policies, see [Example policies to control access the Amazon EC2 API](ExamplePolicies_EC2.md). 

If you allow or deny users access to resources based on tags, you must consider explicitly denying users the ability to add those tags to or remove them from the same resources. Otherwise, it's possible for a user to circumvent your restrictions and gain access to a resource by modifying its tags.

## Grant permissions to users, groups, and roles
<a name="granting-iam-permissions"></a>

To provide access, add permissions to your users, groups, or roles:
+ Users and groups in AWS IAM Identity Center:

  Create a permission set. Follow the instructions in [Create a permission set](https://docs.aws.amazon.com//singlesignon/latest/userguide/howtocreatepermissionset.html) in the *AWS IAM Identity Center User Guide*.
+ Users managed in IAM through an identity provider:

  Create a role for identity federation. Follow the instructions in [Create a role for a third-party identity provider (federation)](https://docs.aws.amazon.com//IAM/latest/UserGuide/id_roles_create_for-idp.html) in the *IAM User Guide*.
+ IAM users:
  + Create a role that your user can assume. Follow the instructions in [Create a role for an IAM user](https://docs.aws.amazon.com//IAM/latest/UserGuide/id_roles_create_for-user.html) in the *IAM User Guide*.
  + (Not recommended) Attach a policy directly to a user or add a user to a user group. Follow the instructions in [Adding permissions to a user (console)](https://docs.aws.amazon.com//IAM/latest/UserGuide/id_users_change-permissions.html#users_change_permissions-add-console) in the *IAM User Guide*.

## Check that users have the required permissions
<a name="check-required-permissions"></a>

After you've created an IAM policy, we recommend that you check whether it grants users the permissions to use the particular API actions and resources they need before you put the policy into production.

First, create a user for testing purposes, and then attach the IAM policy that you created to the test user. Then, make a request as the test user.

If the Amazon EC2 action that you are testing creates or modifies a resource, you should make the request using the `DryRun` parameter (or run the AWS CLI command with the `--dry-run` option). In this case, the call completes the authorization check, but does not complete the operation. For example, you can check whether the user can terminate a particular instance without actually terminating it. If the test user has the required permissions, the request returns `DryRunOperation`; otherwise, it returns `UnauthorizedOperation`.

If the policy doesn't grant the user the permissions that you expected, or is overly permissive, you can adjust the policy as needed and retest until you get the desired results. 

**Important**  
It can take several minutes for policy changes to propagate before they take effect. Therefore, we recommend that you allow five minutes to pass before you test your policy updates.

If an authorization check fails, the request returns an encoded message with diagnostic information. You can decode the message using the `DecodeAuthorizationMessage` action. For more information, see [DecodeAuthorizationMessage](https://docs.aws.amazon.com/STS/latest/APIReference/API_DecodeAuthorizationMessage.html) in the *AWS Security Token Service API Reference*, and [decode-authorization-message](https://docs.aws.amazon.com/cli/latest/reference/sts/decode-authorization-message.html).

# Example policies to control access the Amazon EC2 API
<a name="ExamplePolicies_EC2"></a>

You can use IAM policies to grant users the permissions required to work with Amazon EC2. For step-by-step directions, see [Creating IAM policies](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_create.html) in the *IAM User Guide*.

The following examples show policy statements that you could use to grant users permissions to use Amazon EC2. These policies are designed for requests that are made using the AWS CLI or an AWS SDK. In the following examples, replace each *user input placeholder* with your own information.

**Topics**
+ [Read-only access](#iam-example-read-only)
+ [Restrict access to a specific Region](#iam-example-region)
+ [Work with instances](#iam-example-instances)
+ [Launch instances (RunInstances)](#iam-example-runinstances)
+ [Work with Spot Instances](#iam-example-spot-instances)
+ [Work with Reserved Instances](#iam-example-reservedinstances)
+ [Tag resources](#iam-example-taggingresources)
+ [Work with IAM roles](#iam-example-iam-roles)
+ [Work with route tables](#iam-example-route-tables)
+ [Allow a specific instance to view resources in other AWS services](#iam-example-source-instance)
+ [Work with launch templates](#iam-example-launch-templates)
+ [Work with instance metadata](#iam-example-instance-metadata)
+ [Work with Amazon EBS volumes and snapshots](#iam-example-ebs)

For example policies for working in the Amazon EC2 console, see [Example policies to control access to the Amazon EC2 console](iam-policies-ec2-console.md).

## Example: Read-only access
<a name="iam-example-read-only"></a>

The following policy grants users permissions to use all Amazon EC2 API actions whose names begin with `Describe`. The `Resource` element uses a wildcard to indicate that users can specify all resources with these API actions. The \$1 wildcard is also necessary in cases where the API action does not support resource-level permissions. For more information about which ARNs you can use with which Amazon EC2 API actions, see [Actions, resources, and condition keys for Amazon EC2](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonec2.html).

Users don't have permission to perform any actions on the resources (unless another statement grants them permission to do so) because they're denied permission to use API actions by default.

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement": [
    {
      "Effect": "Allow",
      "Action": "ec2:Describe*",
      "Resource": "*"
    }
   ]
}
```

------

## Example: Restrict access to a specific Region
<a name="iam-example-region"></a>

The following policy denies users permission to use all Amazon EC2 API actions unless the Region is Europe (Frankfurt). It uses the global condition key `aws:RequestedRegion`, which is supported by all Amazon EC2 API actions.

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
       {
      "Effect": "Deny",
      "Action": "ec2:*",
      "Resource": "*",
      "Condition": {
        "StringNotEquals": {
          "aws:RequestedRegion": "eu-central-1"
        }
      }
    }  
  ]
}
```

------

Alternatively, you can use the condition key `ec2:Region`, which is specific to Amazon EC2 and is supported by all Amazon EC2 API actions.

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
       {
      "Effect": "Deny",
      "Action": "ec2:*",
      "Resource": "*",
      "Condition": {
        "StringNotEquals": {
          "ec2:Region": "eu-central-1"
        }
      }
    }  
  ]
}
```

------

## Work with instances
<a name="iam-example-instances"></a>

**Topics**
+ [Example: Describe, launch, stop, start, and terminate all instances](#iam-example-instances-all)
+ [Example: Describe all instances, and stop, start, and terminate only particular instances](#iam-example-instances-specific)

### Example: Describe, launch, stop, start, and terminate all instances
<a name="iam-example-instances-all"></a>

The following policy grants users permissions to use the API actions specified in the `Action` element. The `Resource` element uses a \$1 wildcard to indicate that users can specify all resources with these API actions. The \$1 wildcard is also necessary in cases where the API action does not support resource-level permissions. For more information about which ARNs you can use with which Amazon EC2 API actions, see [Actions, resources, and condition keys for Amazon EC2](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonec2.html).

The users don't have permission to use any other API actions (unless another statement grants them permission to do so) because users are denied permission to use API actions by default.

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ec2:DescribeInstances", 
        "ec2:DescribeImages",
        "ec2:DescribeKeyPairs", 
        "ec2:DescribeSecurityGroups",
        "ec2:DescribeAvailabilityZones",
        "ec2:RunInstances", 
        "ec2:TerminateInstances",
        "ec2:StopInstances", 
        "ec2:StartInstances"
      ],
      "Resource": "*"
    }
   ]
}
```

------

### Example: Describe all instances, and stop, start, and terminate only particular instances
<a name="iam-example-instances-specific"></a>

The following policy allows users to describe all instances, to start and stop only instances i-1234567890abcdef0 and i-0598c7d356eba48d7, and to terminate only instances in the `us-east-1` Region, with the resource tag "`purpose=test`". 

The first statement uses a \$1 wildcard for the `Resource` element to indicate that users can specify all resources with the action; in this case, they can list all instances. The \$1 wildcard is also necessary in cases where the API action does not support resource-level permissions (in this case, `ec2:DescribeInstances`). For more information about which ARNs you can use with which Amazon EC2 API actions, see [Actions, resources, and condition keys for Amazon EC2](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonec2.html).

The second statement uses resource-level permissions for the `StopInstances` and `StartInstances` actions. The specific instances are indicated by their ARNs in the `Resource` element.

The third statement allows users to terminate all instances in the `us-east-1` Region that belong to the specified AWS account, but only where the instance has the tag `"purpose=test"`. The `Condition` element qualifies when the policy statement is in effect. 

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement": [
   {
   "Effect": "Allow",
      "Action": "ec2:DescribeInstances",
      "Resource": "*"
   },
   {
      "Effect": "Allow",
      "Action": [
        "ec2:StopInstances", 
        "ec2:StartInstances"
      ],
      "Resource": [
        "arn:aws:ec2:us-east-1:111122223333:instance/i-1234567890abcdef0",
        "arn:aws:ec2:us-east-1:111122223333:instance/i-0598c7d356eba48d7"
      ]
    },
    {
      "Effect": "Allow",
      "Action": "ec2:TerminateInstances",
      "Resource": "arn:aws:ec2:us-east-1:111122223333:instance/*",
      "Condition": {
         "StringEquals": {
            "aws:ResourceTag/purpose": "test"
         }
      }
   }

   ]
}
```

------

## Launch instances (RunInstances)
<a name="iam-example-runinstances"></a>

The [RunInstances](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_RunInstances.html) API action launches one or more On-Demand Instances or one or more Spot Instances. `RunInstances` requires an AMI and creates an instance. Users can specify a key pair and security group in the request. Launching into a VPC requires a subnet, and creates a network interface. Launching from an Amazon EBS-backed AMI creates a volume. Therefore, the user must have permissions to use these Amazon EC2 resources. You can create a policy statement that requires users to specify an optional parameter on `RunInstances`, or restricts users to particular values for a parameter.

For more information about the resource-level permissions that are required to launch an instance, see [Actions, resources, and condition keys for Amazon EC2](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonec2.html).

By default, users don't have permissions to describe, start, stop, or terminate the resulting instances. One way to grant the users permission to manage the resulting instances is to create a specific tag for each instance, and then create a statement that enables them to manage instances with that tag. For more information, see [Work with instances](#iam-example-instances).

**Topics**
+ [AMIs](#iam-example-runinstances-ami)
+ [Instance types](#iam-example-runinstances-instance-type)
+ [Subnets](#iam-example-runinstances-subnet)
+ [EBS volumes](#iam-example-runinstances-volumes)
+ [Tags](#iam-example-runinstances-tags)
+ [Tags in a launch template](#iam-example-tags-launch-template)
+ [Elastic GPUs](#iam-example-runinstances-egpu)
+ [Launch templates](#iam-example-runinstances-launch-templates)

### AMIs
<a name="iam-example-runinstances-ami"></a>

The following policy allows users to launch instances using only the specified AMIs, `ami-9e1670f7` and `ami-45cf5c3c`. The users can't launch an instance using other AMIs (unless another statement grants the users permission to do so).

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement": [
   {
      "Effect": "Allow",
      "Action": "ec2:RunInstances",
      "Resource": [
        "arn:aws:ec2:us-east-1::image/ami-9e1670f7",
        "arn:aws:ec2:us-east-1::image/ami-45cf5c3c",
        "arn:aws:ec2:us-east-1:111122223333:instance/*",
        "arn:aws:ec2:us-east-1:111122223333:volume/*",
        "arn:aws:ec2:us-east-1:111122223333:key-pair/*",
        "arn:aws:ec2:us-east-1:111122223333:security-group/*",
        "arn:aws:ec2:us-east-1:111122223333:subnet/*",
        "arn:aws:ec2:us-east-1:111122223333:network-interface/*"
      ]
    }
   ]
}
```

------

Alternatively, the following policy allows users to launch instances from all AMIs owned by Amazon, or certain trusted and verified partners. The `Condition` element of the first statement tests whether `ec2:Owner` is `amazon`. The users can't launch an instance using other AMIs (unless another statement grants the users permission to do so).

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement": [
         {
      "Effect": "Allow",
      "Action": "ec2:RunInstances",
      "Resource": [ 
         "arn:aws:ec2:us-east-1::image/ami-*"
      ],
      "Condition": {
         "StringEquals": {
            "ec2:Owner": "amazon"
         }
      }
   },
   {
      "Effect": "Allow",
      "Action": "ec2:RunInstances",
      "Resource": [ 
         "arn:aws:ec2:us-east-1:111122223333:instance/*",
         "arn:aws:ec2:us-east-1:111122223333:subnet/*",
         "arn:aws:ec2:us-east-1:111122223333:volume/*",
         "arn:aws:ec2:us-east-1:111122223333:network-interface/*",
         "arn:aws:ec2:us-east-1:111122223333:key-pair/*",
         "arn:aws:ec2:us-east-1:111122223333:security-group/*"
         ]
      }
   ]
}
```

------

### Instance types
<a name="iam-example-runinstances-instance-type"></a>

The following policy allows users to launch instances using only the `t2.micro` or `t2.small` instance type, which you might do to control costs. The users can't launch larger instances because the `Condition` element of the first statement tests whether `ec2:InstanceType` is either `t2.micro` or `t2.small`. 

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement": [
        {
      "Effect": "Allow",
      "Action": "ec2:RunInstances",
      "Resource": [
         "arn:aws:ec2:us-east-1:111122223333:instance/*"
      ],
      "Condition": {
         "StringEquals": {
            "ec2:InstanceType": ["t2.micro", "t2.small"]
         }
      }
   },
   {
      "Effect": "Allow",
      "Action": "ec2:RunInstances",
      "Resource": [
         "arn:aws:ec2:us-east-1::image/ami-*",
         "arn:aws:ec2:us-east-1:111122223333:subnet/*",
         "arn:aws:ec2:us-east-1:111122223333:network-interface/*",
         "arn:aws:ec2:us-east-1:111122223333:volume/*",
         "arn:aws:ec2:us-east-1:111122223333:key-pair/*",
         "arn:aws:ec2:us-east-1:111122223333:security-group/*"
         ]
      }
   ]
}
```

------

Alternatively, you can create a policy that denies users permissions to launch any instances except `t2.micro` and `t2.small` instance types.

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement": [
        { 
      "Effect": "Deny",
      "Action": "ec2:RunInstances",
      "Resource": [
         "arn:aws:ec2:us-east-1:111122223333:instance/*"
      ],
      "Condition": {
         "StringNotEquals": {
            "ec2:InstanceType": ["t2.micro", "t2.small"]
         }
      }
   },
   {
      "Effect": "Allow",
      "Action": "ec2:RunInstances",
      "Resource": [
         "arn:aws:ec2:us-east-1::image/ami-*",
         "arn:aws:ec2:us-east-1:111122223333:network-interface/*",
         "arn:aws:ec2:us-east-1:111122223333:instance/*",
         "arn:aws:ec2:us-east-1:111122223333:subnet/*",
         "arn:aws:ec2:us-east-1:111122223333:volume/*",
         "arn:aws:ec2:us-east-1:111122223333:key-pair/*",
         "arn:aws:ec2:us-east-1:111122223333:security-group/*"
         ]
      }
   ]
}
```

------

### Subnets
<a name="iam-example-runinstances-subnet"></a>

The following policy allows users to launch instances using only the specified subnet, `subnet-12345678`. The group can't launch instances into any another subnet (unless another statement grants the users permission to do so).

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement": [
    {
      "Effect": "Allow",
      "Action": "ec2:RunInstances",
      "Resource": [
        "arn:aws:ec2:us-east-1:111122223333:subnet/subnet-12345678",
        "arn:aws:ec2:us-east-1:111122223333:network-interface/*",
        "arn:aws:ec2:us-east-1:111122223333:instance/*",
        "arn:aws:ec2:us-east-1:111122223333:volume/*",
        "arn:aws:ec2:us-east-1::image/ami-*",
        "arn:aws:ec2:us-east-1:111122223333:key-pair/*",
        "arn:aws:ec2:us-east-1:111122223333:security-group/*"
      ]
    }
   ]
}
```

------

Alternatively, you could create a policy that denies users permissions to launch an instance into any other subnet. The statement does this by denying permission to create a network interface, except where subnet `subnet-12345678` is specified. This denial overrides any other policies that are created to allow launching instances into other subnets.

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement": [
         {
      "Effect": "Deny",
      "Action": "ec2:RunInstances",
      "Resource": [
         "arn:aws:ec2:us-east-1:111122223333:network-interface/*"
      ],
      "Condition": {
         "ArnNotEquals": {
            "ec2:Subnet": "arn:aws:ec2:us-east-1:111122223333:subnet/subnet-12345678"
         }
      }
   },
   {
      "Effect": "Allow",
      "Action": "ec2:RunInstances",
      "Resource": [
         "arn:aws:ec2:us-east-1::image/ami-*",
         "arn:aws:ec2:us-east-1:111122223333:network-interface/*",
         "arn:aws:ec2:us-east-1:111122223333:instance/*",
         "arn:aws:ec2:us-east-1:111122223333:subnet/*",
         "arn:aws:ec2:us-east-1:111122223333:volume/*",
         "arn:aws:ec2:us-east-1:111122223333:key-pair/*",
         "arn:aws:ec2:us-east-1:111122223333:security-group/*"
         ]
      }
   ]
}
```

------

### EBS volumes
<a name="iam-example-runinstances-volumes"></a>

The following policy allows users to launch instances only if the EBS volumes for the instance are encrypted. The user must launch an instance from an AMI that was created with encrypted snapshots, to ensure that the root volume is encrypted. Any additional volume that the user attaches to the instance during launch must also be encrypted.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
                {
            "Effect": "Allow",
            "Action": "ec2:RunInstances",
            "Resource": [
                "arn:aws:ec2:*:*:volume/*"
            ],
            "Condition": {
                "Bool": {
                    "ec2:Encrypted": "true"
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": "ec2:RunInstances",
            "Resource": [
                "arn:aws:ec2:*::image/ami-*",
                "arn:aws:ec2:*:*:network-interface/*",
                "arn:aws:ec2:*:*:instance/*",
                "arn:aws:ec2:*:*:subnet/*",
                "arn:aws:ec2:*:*:key-pair/*",
                "arn:aws:ec2:*:*:security-group/*"
            ]
        }
    ]
}
```

------

### Tags
<a name="iam-example-runinstances-tags"></a>

**Tag instances on creation**

The following policy allows users to launch instances and tag the instances during creation. For resource-creating actions that apply tags, users must have permissions to use the `CreateTags` action. The second statement uses the `ec2:CreateAction` condition key to allow users to create tags only in the context of `RunInstances`, and only for instances. Users cannot tag existing resources, and users cannot tag volumes using the `RunInstances` request. 

For more information, see [Grant permission to tag Amazon EC2 resources during creation](supported-iam-actions-tagging.md).

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	  
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
         "ec2:RunInstances"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": [
         "ec2:CreateTags"
      ],
      "Resource": "arn:aws:ec2:us-east-1:111122223333:instance/*",
      "Condition": {
         "StringEquals": {
             "ec2:CreateAction" : "RunInstances"
          }
       }
    }
  ]
}
```

------

**Tag instances and volumes on creation with specific tags**

The following policy includes the `aws:RequestTag` condition key that requires users to tag any instances and volumes that are created by `RunInstances` with the tags `environment=production` and `purpose=webserver`. If users don't pass these specific tags, or if they don't specify tags at all, the request fails.

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	  
  "Statement": [
   {
      "Effect": "Allow",
      "Action": [
         "ec2:RunInstances"
      ],
      "Resource": [
         "arn:aws:ec2:us-east-1::image/*",
         "arn:aws:ec2:us-east-1:111122223333:subnet/*",
         "arn:aws:ec2:us-east-1:111122223333:network-interface/*",
         "arn:aws:ec2:us-east-1:111122223333:security-group/*",
         "arn:aws:ec2:us-east-1:111122223333:key-pair/*"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
         "ec2:RunInstances"
      ],
      "Resource": [
          "arn:aws:ec2:us-east-1:111122223333:volume/*",
          "arn:aws:ec2:us-east-1:111122223333:instance/*"
      ],
      "Condition": {
         "StringEquals": {
             "aws:RequestTag/environment": "production" ,
             "aws:RequestTag/purpose": "webserver"
          }
       }
    },
    {
      "Effect": "Allow",
      "Action": [
         "ec2:CreateTags"
      ],
      "Resource": "arn:aws:ec2:us-east-1:111122223333:*/*",
      "Condition": {
         "StringEquals": {
             "ec2:CreateAction" : "RunInstances"
          }
       }
    }
  ]
}
```

------

**Tag instances and volumes on creation with at least one specific tag**

The following policy uses the `ForAnyValue` modifier on the `aws:TagKeys` condition to indicate that at least one tag must be specified in the request, and it must contain the key `environment` or `webserver`. The tag must be applied to both instances and volumes. Any tag values can be specified in the request. 

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	  
  "Statement": [
   {
      "Effect": "Allow",
      "Action": [
         "ec2:RunInstances"
      ],
      "Resource": [
         "arn:aws:ec2:us-east-1::image/*",
         "arn:aws:ec2:us-east-1:111122223333:subnet/*",
         "arn:aws:ec2:us-east-1:111122223333:network-interface/*",
         "arn:aws:ec2:us-east-1:111122223333:security-group/*",
         "arn:aws:ec2:us-east-1:111122223333:key-pair/*"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
          "ec2:RunInstances"
      ],
      "Resource": [
          "arn:aws:ec2:us-east-1:111122223333:volume/*",
          "arn:aws:ec2:us-east-1:111122223333:instance/*"
      ],
      "Condition": {
          "ForAnyValue:StringEquals": {
              "aws:TagKeys": ["environment","webserver"]
          }
       }
    },
    {
      "Effect": "Allow",
      "Action": [
          "ec2:CreateTags"
      ],
      "Resource": "arn:aws:ec2:us-east-1:111122223333:*/*",
      "Condition": {
          "StringEquals": {
              "ec2:CreateAction" : "RunInstances"
          }
       }
    }
  ]
}
```

------

**If instances are tagged on creation, they must be tagged with a specific tag**

In the following policy, users do not have to specify tags in the request, but if they do, the tag must be `purpose=test`. No other tags are allowed. Users can apply the tags to any taggable resource in the `RunInstances` request.

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	  
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
         "ec2:RunInstances"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": [
         "ec2:CreateTags"
      ],
      "Resource": "arn:aws:ec2:us-east-1:111122223333:*/*",
      "Condition": {
         "StringEquals": {
             "aws:RequestTag/purpose": "test",
             "ec2:CreateAction" : "RunInstances"
          },
          "ForAllValues:StringEquals": {
              "aws:TagKeys": "purpose"
          }
       }
    }
  ]
}
```

------

To disallow anyone called tag on create for RunInstances



------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "AllowRun",
            "Effect": "Allow",
            "Action": [
                "ec2:RunInstances"
            ],
            "Resource": [
                "arn:aws:ec2:us-east-1::image/*",
                "arn:aws:ec2:us-east-1:*:subnet/*",
                "arn:aws:ec2:us-east-1:*:network-interface/*",
                "arn:aws:ec2:us-east-1:*:security-group/*",
                "arn:aws:ec2:us-east-1:*:key-pair/*",
                "arn:aws:ec2:us-east-1:*:volume/*",
                "arn:aws:ec2:us-east-1:*:instance/*",
                "arn:aws:ec2:us-east-1:*:spot-instances-request/*"
            ]
        },
        {
            "Effect": "Deny",
            "Action": "ec2:CreateTags",
            "Resource": "*"
        }
    ]
}
```

------

Only allow specific tags for spot-instances-request. Surprise inconsistency number 2 comes into play here. Under normal circumstances, specifying no tags will result in Unauthenticated. In the case of spot-instances-request, this policy will not be evaluated if there are no spot-instances-request tags, so a non-tag Spot on Run request will succeed. 

### Tags in a launch template
<a name="iam-example-tags-launch-template"></a>

In the following example, users can launch instances, but only if they use a specific launch template (`lt-09477bcd97b0d310e`). The `ec2:IsLaunchTemplateResource` condition key prevents users from overriding any of the resources specified in the launch template. The second part of the statement allows users to tag instances on creation—this part of the statement is necessary if tags are specified for the instance in the launch template.

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	  
  "Statement": [
   {
      "Effect": "Allow",
      "Action": "ec2:RunInstances",
      "Resource": "*",
      "Condition": {
         "ArnLike": {
             "ec2:LaunchTemplate": "arn:aws:ec2:us-east-1:111122223333:launch-template/lt-09477bcd97b0d310e" 
          },
          "Bool": {
             "ec2:IsLaunchTemplateResource": "true"
          }
       }
    },
    {
      "Effect": "Allow",
      "Action": [
         "ec2:CreateTags"
      ],
      "Resource": "arn:aws:ec2:us-east-1:111122223333:instance/*",
      "Condition": {
         "StringEquals": {
             "ec2:CreateAction" : "RunInstances"
          }
       }
    }
  ]
}
```

------

### Elastic GPUs
<a name="iam-example-runinstances-egpu"></a>

In the following policy, users can launch an instance and specify an elastic GPU to attach to the instance. Users can launch instances in any Region, but they can only attach an elastic GPU during a launch in the `us-east-2` Region. 

The `ec2:ElasticGpuType` condition key ensures that instances use either the `eg1.medium` or `eg1.large` elastic GPU type.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
             {
            "Effect": "Allow",
            "Action": [
                "ec2:RunInstances"
            ],
            "Resource": [
                "arn:aws:ec2:*:111122223333:elastic-gpu/*"
            ],
            "Condition": {
                "StringEquals": {
                    "ec2:Region": "us-east-2",
                    "ec2:ElasticGpuType": [
                        "eg1.medium",
                        "eg1.large"
                    ]
                }  
            }
        },
        {
            "Effect": "Allow",
            "Action": "ec2:RunInstances",
            "Resource": [
                "arn:aws:ec2:*::image/ami-*",
                "arn:aws:ec2:*:111122223333:network-interface/*",
                "arn:aws:ec2:*:111122223333:instance/*",
                "arn:aws:ec2:*:111122223333:subnet/*",
                "arn:aws:ec2:*:111122223333:volume/*",
                "arn:aws:ec2:*:111122223333:key-pair/*",
                "arn:aws:ec2:*:111122223333:security-group/*"
            ]
        }
    ]
}
```

------

### Launch templates
<a name="iam-example-runinstances-launch-templates"></a>

In the following example, users can launch instances, but only if they use a specific launch template (`lt-09477bcd97b0d310e`). Users can override any parameters in the launch template by specifying the parameters in the `RunInstances` action.

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	  
  "Statement": [
         {
      "Effect": "Allow",
      "Action": "ec2:RunInstances",
      "Resource": "*",
      "Condition": {
         "ArnLike": {
             "ec2:LaunchTemplate": "arn:aws:ec2:us-east-1:111122223333:launch-template/lt-09477bcd97b0d310e" 
          }
       }
    }
  ]
}
```

------

In this example, users can launch instances only if they use a launch template. The policy uses the `ec2:IsLaunchTemplateResource` condition key to prevent users from overriding any pre-existing ARNs in the launch template.

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	  
  "Statement": [
         {
      "Effect": "Allow",
      "Action": "ec2:RunInstances",
      "Resource": "*",
      "Condition": {
         "ArnLike": {
             "ec2:LaunchTemplate": "arn:aws:ec2:us-east-1:111122223333:launch-template/*" 
          },
          "Bool": {
             "ec2:IsLaunchTemplateResource": "true"
          }
       }
    }
  ]
}
```

------

The following example policy allows user to launch instances, but only if they use a launch template. Users cannot override the subnet and network interface parameters in the request; these parameters can only be specified in the launch template. The first part of the statement uses the [NotResource](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_notresource.html) element to allow all other resources except subnets and network interfaces. The second part of the statement allows the subnet and network interface resources, but only if they are sourced from the launch template.

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	  
  "Statement": [
        {
      "Effect": "Allow",
      "Action": "ec2:RunInstances",
      "NotResource": ["arn:aws:ec2:us-east-1:111122223333:subnet/*",
                      "arn:aws:ec2:us-east-1:111122223333:network-interface/*" ],
      "Condition": {
         "ArnLike": {
             "ec2:LaunchTemplate": "arn:aws:ec2:us-east-1:111122223333:launch-template/*" 
          }
       }
    },
   {
      "Effect": "Allow",
      "Action": "ec2:RunInstances",
      "Resource": ["arn:aws:ec2:us-east-1:111122223333:subnet/*",
                   "arn:aws:ec2:us-east-1:111122223333:network-interface/*" ],
      "Condition": {
         "ArnLike": {
             "ec2:LaunchTemplate": "arn:aws:ec2:us-east-1:111122223333:launch-template/*" 
          },
          "Bool": {
             "ec2:IsLaunchTemplateResource": "true"
          }
       }
    }
  ]
}
```

------

The following example allows users to launch instances only if they use a launch template, and only if the launch template has the tag `Purpose=Webservers`. Users cannot override any of the launch template parameters in the `RunInstances` action.

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	  
  "Statement": [
        {
      "Effect": "Allow",
      "Action": "ec2:RunInstances",
      "NotResource": "arn:aws:ec2:us-east-1:111122223333:launch-template/*",
      "Condition": {
         "ArnLike": {
             "ec2:LaunchTemplate": "arn:aws:ec2:us-east-1:111122223333:launch-template/*" 
          },
         "Bool": {
             "ec2:IsLaunchTemplateResource": "true"
          }
       }
    },
    {
      "Effect": "Allow",
      "Action": "ec2:RunInstances",
      "Resource": "arn:aws:ec2:us-east-1:111122223333:launch-template/*",
      "Condition": {
       "StringEquals": {
           "aws:ResourceTag/Purpose": "Webservers" 
        }
       }
     }
  ]
}
```

------

## Work with Spot Instances
<a name="iam-example-spot-instances"></a>

You can use the RunInstances action to create Spot Instance requests, and tag the Spot Instance requests on create. The resource to specify for RunInstances is `spot-instances-request`.

The `spot-instances-request` resource is evaluated in the IAM policy as follows:
+ If you don't tag a Spot Instance request on create, Amazon EC2 does not evaluate the `spot-instances-request` resource in the RunInstances statement.
+ If you tag a Spot Instance request on create, Amazon EC2 evaluates the `spot-instances-request` resource in the RunInstances statement.

Therefore, for the `spot-instances-request` resource, the following rules apply to the IAM policy:
+ If you use RunInstances to create a Spot Instance request and you don't intend to tag the Spot Instance request on create, you don’t need to explicitly allow the `spot-instances-request` resource; the call will succeed.
+ If you use RunInstances to create a Spot Instance request and intend to tag the Spot Instance request on create, you must include the `spot-instances-request` resource in the RunInstances allow statement, otherwise the call will fail.
+ If you use RunInstances to create a Spot Instance request and intend to tag the Spot Instance request on create, you must specify the `spot-instances-request` resource or `*` wildcard in the CreateTags allow statement, otherwise the call will fail. 

You can request Spot Instances using RunInstances or RequestSpotInstances. The following example IAM policies apply only when requesting Spot Instances using RunInstances.

**Example: Request Spot Instances using RunInstances**

The following policy allows users to request Spot Instances by using the RunInstances action. The `spot-instances-request` resource, which is created by RunInstances, requests Spot Instances.

**Note**  
To use RunInstances to create Spot Instance requests, you can omit `spot-instances-request` from the `Resource` list if you do not intend to tag the Spot Instance requests on create. This is because Amazon EC2 does not evaluate the `spot-instances-request` resource in the RunInstances statement if the Spot Instance request is not tagged on create.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "AllowRun",
            "Effect": "Allow",
            "Action": [
                "ec2:RunInstances"
            ],
            "Resource": [
                "arn:aws:ec2:us-east-1::image/*",
                "arn:aws:ec2:us-east-1:*:subnet/*",
                "arn:aws:ec2:us-east-1:*:network-interface/*",
                "arn:aws:ec2:us-east-1:*:security-group/*",
                "arn:aws:ec2:us-east-1:*:key-pair/*",
                "arn:aws:ec2:us-east-1:*:volume/*",
                "arn:aws:ec2:us-east-1:*:instance/*",
                "arn:aws:ec2:us-east-1:*:spot-instances-request/*"
            ]
        }
    ]
}
```

------

**Warning**  
**NOT SUPPORTED – Example: Deny users permission to request Spot Instances using RunInstances**  
The following policy is not supported for the `spot-instances-request` resource.  
The following policy is meant to give users the permission to launch On-Demand Instances, but deny users the permission to request Spot Instances. The `spot-instances-request` resource, which is created by RunInstances, is the resource that requests Spot Instances. The second statement is meant to deny the RunInstances action for the `spot-instances-request` resource. However, this condition is not supported because Amazon EC2 does not evaluate the `spot-instances-request` resource in the RunInstances statement if the Spot Instance request is not tagged on create.  

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "AllowRun",
            "Effect": "Allow",
            "Action": [
                "ec2:RunInstances"
            ],
            "Resource": [
                "arn:aws:ec2:us-east-1::image/*",
                "arn:aws:ec2:us-east-1:*:subnet/*",
                "arn:aws:ec2:us-east-1:*:network-interface/*",
                "arn:aws:ec2:us-east-1:*:security-group/*",
                "arn:aws:ec2:us-east-1:*:key-pair/*",
                "arn:aws:ec2:us-east-1:*:volume/*",
                "arn:aws:ec2:us-east-1:*:instance/*"
            ]
        },
        {
            "Sid": "DenySpotInstancesRequestsNOTSUPPORTEDDONOTUSE",
            "Effect": "Deny",
            "Action": "ec2:RunInstances",
            "Resource": "arn:aws:ec2:us-east-1:*:spot-instances-request/*"
        }
    ]
}
```

**Example: Tag Spot Instance requests on create**

The following policy allows users to tag all resources that are created during instance launch. The first statement allows RunInstances to create the listed resources. The `spot-instances-request` resource, which is created by RunInstances, is the resource that requests Spot Instances. The second statement provides a `*` wildcard to allow all resources to be tagged when they are created at instance launch.

**Note**  
If you tag a Spot Instance request on create, Amazon EC2 evaluates the `spot-instances-request` resource in the RunInstances statement. Therefore, you must explicitly allow the `spot-instances-request` resource for the RunInstances action, otherwise the call will fail.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "AllowRun",
            "Effect": "Allow",
            "Action": [
                "ec2:RunInstances"
            ],
            "Resource": [
                "arn:aws:ec2:us-east-1::image/*",
                "arn:aws:ec2:us-east-1:*:subnet/*",
                "arn:aws:ec2:us-east-1:*:network-interface/*",
                "arn:aws:ec2:us-east-1:*:security-group/*",
                "arn:aws:ec2:us-east-1:*:key-pair/*",
                "arn:aws:ec2:us-east-1:*:volume/*",
                "arn:aws:ec2:us-east-1:*:instance/*",
                "arn:aws:ec2:us-east-1:*:spot-instances-request/*"
            ]
        },
        {
            "Sid": "TagResources",
            "Effect": "Allow",
            "Action": "ec2:CreateTags",
            "Resource": "*"
        }
    ]
}
```

------

**Example: Deny tag on create for Spot Instance requests**

The following policy denies users the permission to tag the resources that are created during instance launch.

The first statement allows RunInstances to create the listed resources. The `spot-instances-request` resource, which is created by RunInstances, is the resource that requests Spot Instances. The second statement provides a `*` wildcard to deny all resources being tagged when they are created at instance launch. If `spot-instances-request` or any other resource is tagged on create, the RunInstances call will fail.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "AllowRun",
            "Effect": "Allow",
            "Action": [
                "ec2:RunInstances"
            ],
            "Resource": [
                "arn:aws:ec2:us-east-1::image/*",
                "arn:aws:ec2:us-east-1:*:subnet/*",
                "arn:aws:ec2:us-east-1:*:network-interface/*",
                "arn:aws:ec2:us-east-1:*:security-group/*",
                "arn:aws:ec2:us-east-1:*:key-pair/*",
                "arn:aws:ec2:us-east-1:*:volume/*",
                "arn:aws:ec2:us-east-1:*:instance/*",
                "arn:aws:ec2:us-east-1:*:spot-instances-request/*"
            ]
        },
        {
            "Sid": "DenyTagResources",
            "Effect": "Deny",
            "Action": "ec2:CreateTags",
            "Resource": "*"
        }
    ]
}
```

------

**Warning**  
**NOT SUPPORTED – Example: Allow creating a Spot Instance request only if it is assigned a specific tag**  
The following policy is not supported for the `spot-instances-request` resource.  
The following policy is meant to grant RunInstances the permission to create a Spot Instance request only if the request is tagged with a specific tag.   
The first statement allows RunInstances to create the listed resources.  
The second statement is meant to grant users the permission to create a Spot Instance request only if the request has the tag `environment=production`. If this condition is applied to other resources created by RunInstances, specifying no tags results in an `Unauthenticated` error. However, if no tags are specified for the Spot Instance request, Amazon EC2 does not evaluate the `spot-instances-request` resource in the RunInstances statement, which results in non-tagged Spot Instance requests being created by RunInstances.  
Note that specifying another tag other than `environment=production` results in an `Unauthenticated` error, because if a user tags a Spot Instance request, Amazon EC2 evaluates the `spot-instances-request` resource in the RunInstances statement.  

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "AllowRun",
            "Effect": "Allow",
            "Action": [
                "ec2:RunInstances"
            ],
            "Resource": [
                "arn:aws:ec2:us-east-1::image/*",
                "arn:aws:ec2:us-east-1:*:subnet/*",
                "arn:aws:ec2:us-east-1:*:network-interface/*",
                "arn:aws:ec2:us-east-1:*:security-group/*",
                "arn:aws:ec2:us-east-1:*:key-pair/*",
                "arn:aws:ec2:us-east-1:*:volume/*",
                "arn:aws:ec2:us-east-1:*:instance/*"
            ]
        },
        {
            "Sid": "RequestSpotInstancesOnlyIfTagIsEnvironmentProductionNOTSUPPORTEDDONOTUSE",
            "Effect": "Allow",
            "Action": "ec2:RunInstances",
            "Resource": "arn:aws:ec2:us-east-1:*:spot-instances-request/*",
            "Condition": {
                "StringEquals": {
                    "aws:RequestTag/environment": "production"
                }
            }
        },
        {
            "Sid": "TagResources",
            "Effect": "Allow",
            "Action": "ec2:CreateTags",
            "Resource": "*"
        }

    ]
}
```

**Example: Deny creating a Spot Instance request if it is assigned a specific tag**

The following policy denies RunInstances the permission to create a Spot Instance request if the request is tagged with `environment=production`. 

The first statement allows RunInstances to create the listed resources.

The second statement denies users the permission to create a Spot Instance request if the request has the tag `environment=production`. Specifying `environment=production` as a tag results in an `Unauthenticated` error. Specifying other tags or specifying no tags will result in the creation of a Spot Instance request.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "AllowRun",
            "Effect": "Allow",
            "Action": [
                "ec2:RunInstances"
            ],
            "Resource": [
                "arn:aws:ec2:us-east-1::image/*",
                "arn:aws:ec2:us-east-1:*:subnet/*",
                "arn:aws:ec2:us-east-1:*:network-interface/*",
                "arn:aws:ec2:us-east-1:*:security-group/*",
                "arn:aws:ec2:us-east-1:*:key-pair/*",
                "arn:aws:ec2:us-east-1:*:volume/*",
                "arn:aws:ec2:us-east-1:*:instance/*",
                "arn:aws:ec2:us-east-1:*:spot-instances-request/*"
            ]
        },
        {
            "Sid": "DenySpotInstancesRequests",
            "Effect": "Deny",
            "Action": "ec2:RunInstances",
            "Resource": "arn:aws:ec2:us-east-1:*:spot-instances-request/*",
            "Condition": {
                "StringEquals": {
                    "aws:RequestTag/environment": "production"
                }
            }
        },
        {
            "Sid": "TagResources",
            "Effect": "Allow",
            "Action": "ec2:CreateTags",
            "Resource": "*"
        }
    ]
}
```

------

## Example: Work with Reserved Instances
<a name="iam-example-reservedinstances"></a>

The following policy gives users permission to view, modify, and purchase Reserved Instances in your account.

It is not possible to set resource-level permissions for individual Reserved Instances. This policy means that users have access to all the Reserved Instances in the account.

The `Resource` element uses a \$1 wildcard to indicate that users can specify all resources with the action; in this case, they can list and modify all Reserved Instances in the account. They can also purchase Reserved Instances using the account credentials. The \$1 wildcard is also necessary in cases where the API action does not support resource-level permissions.

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ec2:DescribeReservedInstances", 
        "ec2:ModifyReservedInstances",
        "ec2:PurchaseReservedInstancesOffering", 
        "ec2:DescribeAvailabilityZones",
        "ec2:DescribeReservedInstancesOfferings"
      ],
      "Resource": "*"
    }
   ]
}
```

------

To allow users to view and modify the Reserved Instances in your account, but not purchase new Reserved Instances.

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
   "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ec2:DescribeReservedInstances", 
        "ec2:ModifyReservedInstances",
        "ec2:DescribeAvailabilityZones"
      ],
      "Resource": "*"
    }
  ]
}
```

------

## Example: Tag resources
<a name="iam-example-taggingresources"></a>

The following policy allows users to use the `CreateTags` action to apply tags to an instance only if the tag contains the key`environment` and the value `production`. No other tags are allowed and the user cannot tag any other resource types.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
              {
            "Effect": "Allow",
            "Action": [
                "ec2:CreateTags"
            ],
            "Resource": "arn:aws:ec2:us-east-1:111122223333:instance/*",
            "Condition": {
                "StringEquals": {
                    "aws:RequestTag/environment": "production"
                }
            }
        }
    ]
}
```

------

The following policy allows users to tag any taggable resource that already has a tag with a key of `owner` and a value of the username. In addition, users must specify a tag with a key of `anycompany:environment-type` and a value of either `test` or `prod` in the request. Users can specify additional tags in the request.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
               {
            "Effect": "Allow",
            "Action": [
                "ec2:CreateTags"
            ],
            "Resource": "arn:aws:ec2:us-east-1:111122223333:*/*",
            "Condition": {
                "StringEquals": {
                    "aws:RequestTag/anycompany:environment-type": ["test","prod"],
                    "aws:ResourceTag/owner": "${aws:username}"
                } 
            }
        }
    ]
}
```

------

You can create an IAM policy that allows users to delete specific tags for a resource. For example, the following policy allows users to delete tags for a volume if the tag keys specified in the request are `environment` or `cost-center`. Any value can be specified for the tag but the tag key must match either of the specified keys.

**Note**  
If you delete a resource, all tags associated with the resource are also deleted. Users do not need permissions to use the `ec2:DeleteTags` action to delete a resource that has tags; they only need permissions to perform the deleting action.

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
       {
      "Effect": "Allow",
      "Action": "ec2:DeleteTags",
      "Resource": "arn:aws:ec2:us-east-1:111122223333:volume/*",
      "Condition": {
        "ForAllValues:StringEquals": {
          "aws:TagKeys": ["environment","cost-center"]
        }
      }
    }
  ]
}
```

------

This policy allows users to delete only the `environment=prod` tag on any resource, and only if the resource is already tagged with a key of `owner` and a value of the username. Users can't delete any other tags for a resource.

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
      {
      "Effect": "Allow",
      "Action": [
        "ec2:DeleteTags"
      ],
      "Resource": "arn:aws:ec2:us-east-1:111122223333:*/*",
      "Condition": {
        "StringEquals": {
          "aws:RequestTag/environment": "prod",
          "aws:ResourceTag/owner": "${aws:username}"
        },
        "ForAllValues:StringEquals": {
          "aws:TagKeys": ["environment"]
        }
      }
    }
  ]
}
```

------

## Example: Work with IAM roles
<a name="iam-example-iam-roles"></a>

The following policy allows users to attach, replace, and detach an IAM role to instances that have the tag `department=test`. Replacing or detaching an IAM role requires an association ID, therefore the policy also grants users permission to use the `ec2:DescribeIamInstanceProfileAssociations` action. 

Users must have permission to use the `iam:PassRole` action in order to pass the role to the instance. 

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ec2:AssociateIamInstanceProfile",
        "ec2:ReplaceIamInstanceProfileAssociation",
        "ec2:DisassociateIamInstanceProfile"
      ],
      "Resource": "arn:aws:ec2:us-east-1:111122223333:instance/*",
      "Condition": {
        "StringEquals": {
          "aws:ResourceTag/department":"test"
        }
      }
    },
    {
      "Effect": "Allow",
      "Action": "ec2:DescribeIamInstanceProfileAssociations",
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": "iam:PassRole",
      "Resource": "arn:aws:iam::111122223333:role/DevTeam*"
    }
  ]
}
```

------

The following policy allows users to attach or replace an IAM role for any instance. Users can only attach or replace IAM roles with names that begin with `TestRole-`. For the `iam:PassRole` action, ensure that you specify the name of the IAM role and not the instance profile (if the names are different). For more information, see [Instance profiles](iam-roles-for-amazon-ec2.md#ec2-instance-profile).

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ec2:AssociateIamInstanceProfile",
                "ec2:ReplaceIamInstanceProfileAssociation"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": "ec2:DescribeIamInstanceProfileAssociations",
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": "iam:PassRole",
            "Resource": "arn:aws:iam::111122223333:role/TestRole-*"
        }
    ]
}
```

------

## Example: Work with route tables
<a name="iam-example-route-tables"></a>

The following policy allows users to add, remove, and replace routes for route tables that are associated with VPC `vpc-ec43eb89` only. To specify a VPC for the `ec2:Vpc` condition key, you must specify the full ARN of the VPC.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
              {
            "Effect": "Allow",
            "Action": [
                "ec2:DeleteRoute",
                "ec2:CreateRoute",
                "ec2:ReplaceRoute"
            ],
            "Resource": [
                "arn:aws:ec2:us-east-1:111122223333:route-table/*"
            ],
            "Condition": {
                "StringEquals": {
                    "ec2:Vpc": "arn:aws:ec2:us-east-1:111122223333:vpc/vpc-ec43eb89"
                }
            }
        }
    ]
}
```

------

## Example: Allow a specific instance to view resources in other AWS services
<a name="iam-example-source-instance"></a>

The following is an example of a policy that you might attach to an IAM role. The policy allows an instance to view resources in various AWS services. It uses the `ec2:SourceInstanceARN` global condition key to specify that the instance from which the request is made must be instance `i-093452212644b0dd6`. If the same IAM role is associated with another instance, the other instance cannot perform any of these actions.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
              {
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeVolumes",
                "s3:ListAllMyBuckets",
                "dynamodb:ListTables",
                "rds:DescribeDBInstances"
            ],
            "Resource": [
                "*"
            ],
            "Condition": {
                "ArnEquals": {
                    "ec2:SourceInstanceARN": "arn:aws:ec2:us-east-1:111122223333:instance/i-093452212644b0dd6"
                }
            }
        }
    ]
}
```

------

## Example: Work with launch templates
<a name="iam-example-launch-templates"></a>

The following policy allows users to create a launch template version and modify a launch template, but only for a specific launch template (`lt-09477bcd97b0d3abc`). Users cannot work with other launch templates.

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
   {
      "Action": [
        "ec2:CreateLaunchTemplateVersion",
        "ec2:ModifyLaunchTemplate"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:ec2:us-east-1:111122223333:launch-template/lt-09477bcd97b0d3abc"
    }
  ]
}
```

------

The following policy allows users to delete any launch template and launch template version, provided that the launch template has the tag `Purpose`=`Testing`.

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
       {
      "Action": [
        "ec2:DeleteLaunchTemplate",
        "ec2:DeleteLaunchTemplateVersions"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:ec2:us-east-1:111122223333:launch-template/*",
      "Condition": {
        "StringEquals": {
          "aws:ResourceTag/Purpose": "Testing"
        }
      }
    }
  ]
}
```

------

## Work with instance metadata
<a name="iam-example-instance-metadata"></a>

The following policies ensure that users can only retrieve [instance metadata](ec2-instance-metadata.md) using Instance Metadata Service Version 2 (IMDSv2). You can combine the following four policies into one policy with four statements. When combined as one policy, you can use the policy as a service control policy (SCP). It can work equally well as a *deny* policy that you apply to an existing IAM policy (taking away and limiting existing permission), or as an SCP that is applied globally across an account, an organizational unit (OU), or an entire organization.

**Note**  
The following RunInstances metadata options policies must be used in conjunction with a policy that gives the principal permissions to launch an instance with RunInstances. If the principal does not also have RunInstances permissions, it will not be able to launch an instance. For more information, see the policies in [Work with instances](#iam-example-instances) and [Launch instances (RunInstances)](#iam-example-runinstances).

**Important**  
If you use Auto Scaling groups and you need to require the use of IMDSv2 on all new instances, your Auto Scaling groups must use *launch templates*.  
When an Auto Scaling group uses a launch template, the `ec2:RunInstances` permissions of the IAM principal are checked when a new Auto Scaling group is created. They are also checked when an existing Auto Scaling group is updated to use a new launch template or a new version of a launch template.  
Restrictions on the use of IMDSv1 on IAM principals for `RunInstances` are only checked when an Auto Scaling group that is using a launch template, is created or updated. For an Auto Scaling group that is configured to use the `Latest` or `Default` launch template, the permissions are not checked when a new version of the launch template is created. For permissions to be checked, you must configure the Auto Scaling group to use a *specific version* of the launch template.  
Disable the use of launch configurations for all accounts in your organization by using either service control policies (SCPs) or IAM permissions boundaries for new principals that are created. For existing IAM principals with Auto Scaling group permissions, update their associated policies with this condition key. To disable the use of launch configurations, create or modify the relevant SCP, permissions boundary, or IAM policy with the `"autoscaling:LaunchConfigurationName"` condition key with the value specified as `null`.
For new launch templates, configure the instance metadata options in the launch template. For existing launch templates, create a new version of the launch template and configure the instance metadata options in the new version.
In the policy that gives any principal the permission to use a launch template, restrict association of `$latest` and `$default` by specifying `"autoscaling:LaunchTemplateVersionSpecified": "true"`. By restricting the use to a specific version of a launch template, you can ensure that new instances will be launched using the version in which the instance metadata options are configured. For more information, see [LaunchTemplateSpecification](https://docs.aws.amazon.com/autoscaling/ec2/APIReference/API_LaunchTemplateSpecification.html) in the *Amazon EC2 Auto Scaling API Reference*, specifically the `Version` parameter.
For an Auto Scaling group that uses a launch configuration, replace the launch configuration with a launch template. For more information, see [Migrate your Auto Scaling groups to launch templates](https://docs.aws.amazon.com/autoscaling/ec2/userguide/migrate-to-launch-templates.html) in the *Amazon EC2 Auto Scaling User Guide*.
For an Auto Scaling group that uses a launch template, make sure that it uses a new launch template with the instance metadata options configured, or uses a new version of the current launch template with the instance metadata options configured. For more information, see [update-auto-scaling-group](https://docs.aws.amazon.com/cli/latest/reference/autoscaling/update-auto-scaling-group.html).

**Topics**
+ [Require the use of IMDSv2](#iam-example-instance-metadata-requireIMDSv2)
+ [Deny opt-out of IMDSv2](#iam-example-instance-metadata-denyoptoutIMDSv2)
+ [Specify maximum hop limit](#iam-example-instance-metadata-maxHopLimit)
+ [Limit who can modify the instance metadata options](#iam-example-instance-metadata-limit-modify-IMDS-options)
+ [Require role credentials to be retrieved from IMDSv2](#iam-example-instance-metadata-require-roles-to-use-IMDSv2-credentials)

### Require the use of IMDSv2
<a name="iam-example-instance-metadata-requireIMDSv2"></a>

The following policy specifies that you can’t call the RunInstances API unless the instance is also opted in to require the use of IMDSv2 (indicated by `"ec2:MetadataHttpTokens": "required"`). If you do not specify that the instance requires IMDSv2, you get an `UnauthorizedOperation` error when you call the RunInstances API.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
               {
            "Sid": "RequireImdsV2",
            "Effect": "Deny",
            "Action": "ec2:RunInstances",
            "Resource": "arn:aws:ec2:*:*:instance/*",
            "Condition": {
                "StringNotEquals": {
                    "ec2:MetadataHttpTokens": "required"
                }
            }
        }
    ]
}
```

------

### Deny opt-out of IMDSv2
<a name="iam-example-instance-metadata-denyoptoutIMDSv2"></a>

The following policy specifies that you cannot call the `ModifyInstanceMetadataOptions` API and allow the option of IMDSv1 or IMDSv2. If you call the `ModifyInstanceMetadataOptions` API, the `HttpTokens` attribute must be set to `required`. 

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [{
        "Sid": "DenyIMDSv1HttpTokensModification",
        "Effect": "Deny",
        "Action": "ec2:ModifyInstanceMetadataOptions",
        "Resource": "arn:aws:ec2:*:*:instance/*",
        "Condition": {
            "StringNotEquals": {
                "ec2:Attribute/HttpTokens": "required"
            },
            "Null": {
                "ec2:Attribute/HttpTokens": false
            }
        }
    }]
}
```

------

### Specify maximum hop limit
<a name="iam-example-instance-metadata-maxHopLimit"></a>

The following policy specifies that you can’t call the RunInstances API unless you also specify a hop limit, and the hop limit can’t be more than 3. If you fail to do that, you get an `UnauthorizedOperation` error when you call the RunInstances API.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
               {
            "Sid": "MaxImdsHopLimit",
            "Effect": "Deny",
            "Action": "ec2:RunInstances",
            "Resource": "arn:aws:ec2:*:*:instance/*",
            "Condition": {
                "NumericGreaterThan": {
                    "ec2:MetadataHttpPutResponseHopLimit": "3"
                }
            }
        }
    ]
}
```

------

### Limit who can modify the instance metadata options
<a name="iam-example-instance-metadata-limit-modify-IMDS-options"></a>

The following policy permits only users with the role `ec2-imds-admins` to make changes to the instance metadata options. If any principal other than the `ec2-imds-admins` role tries to call the ModifyInstanceMetadataOptions API, it will get an `UnauthorizedOperation` error. This statement could be used to control the use of the ModifyInstanceMetadataOptions API; there are currently no fine-grained access controls (conditions) for the ModifyInstanceMetadataOptions API.

### Require role credentials to be retrieved from IMDSv2
<a name="iam-example-instance-metadata-require-roles-to-use-IMDSv2-credentials"></a>

The following policy specifies that if this policy is applied to a role, and the role is assumed by the EC2 service and the resulting credentials are used to sign a request, then the request must be signed by EC2 role credentials retrieved from IMDSv2. Otherwise, all of its API calls will get an `UnauthorizedOperation` error. This statement/policy can be applied generally because, if the request is not signed by EC2 role credentials, it has no effect.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
               {
            "Sid": "RequireAllEc2RolesToUseV2",
            "Effect": "Deny",
            "Action": "*",
            "Resource": "*",
            "Condition": {
                "NumericLessThan": {
                    "ec2:RoleDelivery": "2.0"
                }
            }
        }
    ]
}
```

------

## Work with Amazon EBS volumes and snapshots
<a name="iam-example-ebs"></a>

For example policies for working with Amazon EBS volumes and snapshots, see [Identity-based policy examples for Amazon EBS](https://docs.aws.amazon.com/ebs/latest/userguide/security_iam_id-based-policy-examples.html).

# Example policies to control access to the Amazon EC2 console
<a name="iam-policies-ec2-console"></a>

You can use IAM policies to grant users the permissions required to work with Amazon EC2. For step-by-step directions, see [Creating IAM policies](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_create.html) in the *IAM User Guide*.

The console uses additional API actions for its features, so these policies may not work as expected. For example, a user that has permission to use only the `DescribeVolumes` API action will encounter errors when trying to view volumes in the console. This section demonstrates policies that enable users to work with specific parts of the console. For additional information about creating policies for the Amazon EC2 console, see the following AWS Security Blog post: [Granting Users Permission to Work in the Amazon EC2 Console](https://aws.amazon.com/blogs/security/granting-users-permission-to-work-in-the-amazon-ec2-console/).

The following examples show policy statements that you could use to grant users permissions to use Amazon EC2. Replace each *user input placeholder* with your own information. These policies are designed for requests that are made using the AWS Management Console. The Amazon EC2 console might call multiple API actions to display a single resource, and it might not be obvious until the user attempts a task and the console displays an error. For more information, see the following AWS Security Blog post: [Granting Users Permission to Work in the Amazon EC2 Console](https://aws.amazon.com/blogs/security/granting-users-permission-to-work-in-the-amazon-ec2-console/).

**Topics**
+ [Read-only access](#ex-read-only)
+ [Use the EC2 launch instance wizard](#ex-launch-wizard)
+ [Work with security groups](#ex-security-groups)
+ [Work with Elastic IP addresses](#ex-eip)
+ [Work with Reserved Instances](#ex-reservedinstances)

To help you work out which API actions are required to perform tasks in the console, you can use a service that logs calls, such as AWS CloudTrail. If your policy does not grant permission to create or modify a specific resource, the console displays an encoded message with diagnostic information. You can decode the message using the [DecodeAuthorizationMessage](https://docs.aws.amazon.com/STS/latest/APIReference/API_DecodeAuthorizationMessage.html) API action for AWS STS, or the [decode-authorization-message](https://docs.aws.amazon.com/cli/latest/reference/sts/decode-authorization-message.html) command in the AWS CLI.

## Example: Read-only access
<a name="ex-read-only"></a>

To allow users to view all resources in the Amazon EC2 console, you can use the same policy as the following example: [Example: Read-only access](ExamplePolicies_EC2.md#iam-example-read-only). Users cannot perform any actions on those resources or create new resources, unless another statement grants them permission to do so.

**View instances, AMIs, and snapshots**

Alternatively, you can provide read-only access to a subset of resources. To do this, replace the \$1 wildcard in the `ec2:Describe` API action with specific `ec2:Describe` actions for each resource. The following policy allows users to view all instances, AMIs, and snapshots in the Amazon EC2 console. The `ec2:DescribeTags` action allows users to view public AMIs. The console requires the tagging information to display public AMIs; however, you can remove this action to allow users to view only private AMIs.

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement": [{
      "Effect": "Allow",
      "Action": [
         "ec2:DescribeInstances", 
         "ec2:DescribeImages",
         "ec2:DescribeTags", 
         "ec2:DescribeSnapshots"
      ],
      "Resource": "*"
   }
   ]
}
```

------

**Note**  
The Amazon EC2 `ec2:Describe*` API actions do not support resource-level permissions, so you cannot control which individual resources users can view in the console. Therefore, the \$1 wildcard is necessary in the `Resource` element of the above statement. For more information about which ARNs you can use with which Amazon EC2 API actions, see [Actions, resources, and condition keys for Amazon EC2](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonec2.html).

**View instances and CloudWatch metrics**

The following policy allows users to view instances in the Amazon EC2 console, as well as CloudWatch alarms and metrics in the **Monitoring** tab of the **Instances** page. The Amazon EC2 console uses the CloudWatch API to display the alarms and metrics, so you must grant users permission to use the `cloudwatch:DescribeAlarms`, `cloudwatch:DescribeAlarmsForMetric`, `cloudwatch:ListMetrics`, `cloudwatch:GetMetricStatistics`, and `cloudwatch:GetMetricData` actions.

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement": [{
      "Effect": "Allow",
      "Action": [
         "ec2:DescribeInstances",
         "ec2:DescribeInstanceTypes",
         "cloudwatch:DescribeAlarms",
         "cloudwatch:DescribeAlarmsForMetric",
         "cloudwatch:ListMetrics",
         "cloudwatch:GetMetricStatistics",
         "cloudwatch:GetMetricData"
      ],
      "Resource": "*"
   }
   ]
}
```

------

## Example: Use the EC2 launch instance wizard
<a name="ex-launch-wizard"></a>

The Amazon EC2 launch instance wizard is a screen with options to configure and launch an instance. Your policy must include permission to use the API actions that allow users to work with the wizard's options. If your policy does not include permission to use those actions, some items in the wizard cannot load properly, and users cannot complete a launch.

**Basic launch instance wizard access**

To complete a launch successfully, users must be given permission to use the `ec2:RunInstances` API action, and at least the following API actions:
+ `ec2:DescribeImages`: To view and select an AMI.
+ `ec2:DescribeInstanceTypes`: To view and select an instance type.
+ `ec2:DescribeVpcs`: To view the available network options.
+ `ec2:DescribeSubnets`: To view all available subnets for the chosen VPC. 
+ `ec2:DescribeSecurityGroups` or `ec2:CreateSecurityGroup`: To view and select an existing security group, or to create a new one. 
+ `ec2:DescribeKeyPairs` or `ec2:CreateKeyPair`: To select an existing key pair, or to create a new one.
+ `ec2:AuthorizeSecurityGroupIngress`: To add inbound rules.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeInstances",
                "ec2:DescribeImages",
                "ec2:DescribeInstanceTypes",
                "ec2:DescribeKeyPairs",
                "ec2:DescribeVpcs",
                "ec2:DescribeSubnets",
                "ec2:DescribeSecurityGroups",
                "ec2:CreateSecurityGroup",
                "ec2:AuthorizeSecurityGroupIngress",
                "ec2:CreateKeyPair"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": "ec2:RunInstances",
            "Resource": "*"
        }
    ]
}
```

------

You can add API actions to your policy to provide more options for users, for example:
+ `ec2:DescribeAvailabilityZones`: To view and select a specific Availability Zone.
+ `ec2:DescribeNetworkInterfaces`: To view and select existing network interfaces for the selected subnet.
+ To add outbound rules to VPC security groups, users must be granted permission to use the `ec2:AuthorizeSecurityGroupEgress` API action. To modify or delete existing rules, users must be granted permission to use the relevant `ec2:RevokeSecurityGroup*` API action.
+ `ec2:CreateTags`: To tag the resources that are created by `RunInstances`. For more information, see [Grant permission to tag Amazon EC2 resources during creation](supported-iam-actions-tagging.md). If users do not have permission to use this action and they attempt to apply tags on the tagging page of the launch instance wizard, the launch fails.
**Important**  
Specifying a **Name** while launching an instance creates a tag and requires the `ec2:CreateTags` action. Be careful about granting users permission to use the `ec2:CreateTags` action, because doing so limits your ability to use the `aws:ResourceTag` condition key to restrict their use of other resources. If you grant users permission to use the `ec2:CreateTags` action, they can change a resource's tag in order to bypass those restrictions. For more information, see [Control access using attribute-based access](iam-policies-for-amazon-ec2.md#control-access-with-tags).
+ To use Systems Manager parameters when selecting an AMI, you must add `ssm:DescribeParameters` and `ssm:GetParameters` to your policy. `ssm:DescribeParameters` grants your users the permission to view and select Systems Manager parameters. `ssm:GetParameters` grants your users the permission to get the values of the Systems Manager parameters. You can also restrict access to specific Systems Manager parameters. For more information, see **Restrict access to specific Systems Manager parameters** later in this section.

Currently, the Amazon EC2 `Describe*` API actions do not support resource-level permissions, so you cannot restrict which individual resources users can view in the launch instance wizard. However, you can apply resource-level permissions on the `ec2:RunInstances` API action to restrict which resources users can use to launch an instance. The launch fails if users select options that they are not authorized to use. 

**Restrict access to a specific instance type, subnet, and Region**

The following policy allows users to launch `t2.micro` instances using AMIs owned by Amazon, and only into a specific subnet (`subnet-1a2b3c4d`). Users can only launch in the specified Region. If users select a different Region, or select a different instance type, AMI, or subnet in the launch instance wizard, the launch fails. 

The first statement grants users permission to view the options in the launch instance wizard or to create new ones, as explained in the example above. The second statement grants users permission to use the network interface, volume, key pair, security group, and subnet resources for the `ec2:RunInstances` action, which are required to launch an instance into a VPC. For more information about using the `ec2:RunInstances` action, see [Launch instances (RunInstances)](ExamplePolicies_EC2.md#iam-example-runinstances). The third and fourth statements grant users permission to use the instance and AMI resources respectively, but only if the instance is a `t2.micro` instance, and only if the AMI is owned by Amazon, or certain trusted and verified partners.

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement": [{
      "Effect": "Allow",
      "Action": [
         "ec2:DescribeInstances",
         "ec2:DescribeImages",
         "ec2:DescribeInstanceTypes",
         "ec2:DescribeKeyPairs", 
         "ec2:CreateKeyPair", 
         "ec2:DescribeVpcs", 
         "ec2:DescribeSubnets", "ec2:DescribeSecurityGroups", 
         "ec2:CreateSecurityGroup", 
         "ec2:AuthorizeSecurityGroupIngress"
	  ],
	  "Resource": "*"
   },
   {
      "Effect": "Allow",
      "Action":"ec2:RunInstances",
      "Resource": [
         "arn:aws:ec2:us-east-2:111122223333:network-interface/*",
         "arn:aws:ec2:us-east-2:111122223333:volume/*",
         "arn:aws:ec2:us-east-2:111122223333:key-pair/*",
         "arn:aws:ec2:us-east-2:111122223333:security-group/*",
         "arn:aws:ec2:us-east-2:111122223333:subnet/subnet-1a2b3c4d"
      ]
   },
   {
      "Effect": "Allow",
      "Action": "ec2:RunInstances",
      "Resource": [
         "arn:aws:ec2:us-east-2:111122223333:instance/*"
      ],
      "Condition": {
         "StringEquals": {
            "ec2:InstanceType": "t2.micro"
         }
      }
   },
   {
      "Effect": "Allow",
      "Action": "ec2:RunInstances",
      "Resource": [ 
            "arn:aws:ec2:us-east-2::image/ami-*"
      ],
      "Condition": {
         "StringEquals": {
            "ec2:Owner": "amazon"
         }
      }
   }
   ]
}
```

------

**Restrict access to specific Systems Manager parameters**

The following policy grants access to use Systems Manager parameters with a specific name.

The first statement grants users the permission to view Systems Manager parameters when selecting an AMI in the launch instance wizard. The second statement grants users the permission to only use parameters that are named `prod-*`.

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement": [{
      "Effect": "Allow",
      "Action": [
         "ssm:DescribeParameters"
      ],
      "Resource": "*"
   },
   {
      "Effect": "Allow",
      "Action": [
         "ssm:GetParameters"
      ],
     "Resource": "arn:aws:ssm:us-east-2:123456123456:parameter/prod-*"
   }
   ]
}
```

------

## Example: Work with security groups
<a name="ex-security-groups"></a>

**View security groups and add and remove rules**

The following policy grants users permission to view security groups in the Amazon EC2 console, to add and remove inbound and outbound rules, and to list and modify rule descriptions for existing security groups that have the tag `Department=Test`.

In the first statement, the `ec2:DescribeTags` action allows users to view tags in the console, which makes it easier for users to identify the security groups that they are allowed to modify.

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement": [{
      "Effect": "Allow",
      "Action": [
         "ec2:DescribeSecurityGroups", 
         "ec2:DescribeSecurityGroupRules", 
         "ec2:DescribeTags"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": [
         "ec2:AuthorizeSecurityGroupIngress", 
         "ec2:RevokeSecurityGroupIngress", 
         "ec2:AuthorizeSecurityGroupEgress", 
         "ec2:RevokeSecurityGroupEgress", 
         "ec2:ModifySecurityGroupRules", 
         "ec2:UpdateSecurityGroupRuleDescriptionsIngress", 
         "ec2:UpdateSecurityGroupRuleDescriptionsEgress"
      ],
      "Resource": [
         "arn:aws:ec2:us-east-2:111122223333:security-group/*"
      ],
      "Condition": {
         "StringEquals": {
            "aws:ResourceTag/Department": "Test"
         }
      }
   },
   {
      "Effect": "Allow",
      "Action": [
         "ec2:ModifySecurityGroupRules"
      ],
      "Resource": [
         "arn:aws:ec2:us-east-2:111122223333:security-group-rule/*"
      ]
   }
]}
```

------

**Work with the Create Security Group dialog box**

You can create a policy that allows users to work with the **Create Security Group** dialog box in the Amazon EC2 console. To use this dialog box, users must be granted permission to use at the least the following API actions:
+ `ec2:CreateSecurityGroup`: To create a new security group. 
+ `ec2:DescribeVpcs`: To view a list of existing VPCs in the **VPC** list.

With these permissions, users can create a new security group successfully, but they cannot add any rules to it. To work with rules in the **Create Security Group** dialog box, you can add the following API actions to your policy:
+ `ec2:AuthorizeSecurityGroupIngress`: To add inbound rules.
+ `ec2:AuthorizeSecurityGroupEgress`: To add outbound rules to VPC security groups.
+ `ec2:RevokeSecurityGroupIngress`: To modify or delete existing inbound rules. This is useful to allow users to use the **Copy to new** feature in the console. This feature opens the **Create Security Group** dialog box and populates it with the same rules as the security group that was selected. 
+ `ec2:RevokeSecurityGroupEgress`: To modify or delete outbound rules for VPC security groups. This is useful to allow users to modify or delete the default outbound rule that allows all outbound traffic.
+ `ec2:DeleteSecurityGroup`: To cater for when invalid rules cannot be saved. The console first creates the security group, and then adds the specified rules. If the rules are invalid, the action fails, and the console attempts to delete the security group. The user remains in the **Create Security Group** dialog box so that they can correct the invalid rule and try to create the security group again. This API action is not required, but if a user is not granted permission to use it and attempts to create a security group with invalid rules, the security group is created without any rules, and the user must add them afterward.
+ `ec2:UpdateSecurityGroupRuleDescriptionsIngress`: To add or update descriptions of ingress (inbound) security group rules.
+ `ec2:UpdateSecurityGroupRuleDescriptionsEgress`: To add or update descriptions of egress (outbound) security group rules.
+ `ec2:ModifySecurityGroupRules`: To modify security group rules.
+ `ec2:DescribeSecurityGroupRules`: To list security group rules.

The following policy grants users permission to use the **Create Security Group** dialog box, and to create inbound and outbound rules for security groups that are associated with a specific VPC (`vpc-1a2b3c4d`). Users can create security groups for a VPC, but they cannot add any rules to them. Similarly, users cannot add any rules to any existing security group that's not associated with VPC `vpc-1a2b3c4d`. Users are also granted permission to view all security groups in the console. This makes it easier for users to identify the security groups to which they can add inbound rules. This policy also grants users permission to delete security groups that are associated with VPC `vpc-1a2b3c4d`. 

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement": [{
      "Effect": "Allow",
      "Action": [
        "ec2:DescribeSecurityGroups", 
        "ec2:CreateSecurityGroup", 
        "ec2:DescribeVpcs"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "ec2:DeleteSecurityGroup", 
        "ec2:AuthorizeSecurityGroupIngress", 
        "ec2:AuthorizeSecurityGroupEgress"
      ],
      "Resource": "arn:aws:ec2:us-east-2:111122223333:security-group/*",
      "Condition":{
         "ArnEquals": {
            "ec2:Vpc": "arn:aws:ec2:us-east-2:111122223333:vpc/vpc-1a2b3c4d"
         }
      }
    }
   ]
}
```

------

## Example: Work with Elastic IP addresses
<a name="ex-eip"></a>

To allow users to view Elastic IP addresses in the Amazon EC2 console, you must grant users permission to use the `ec2:DescribeAddresses` action.

To allow users to work with Elastic IP addresses, you can add the following actions to your policy.
+ `ec2:AllocateAddress`: To allocate an Elastic IP address.
+ `ec2:ReleaseAddress`: To release an Elastic IP address.
+ `ec2:AssociateAddress`: To associate an Elastic IP address with an instance or a network interface.
+ `ec2:DescribeNetworkInterfaces` and `ec2:DescribeInstances`: To work with the **Associate address** screen. The screen displays the available instances or network interfaces to which you can associate an Elastic IP address.
+ `ec2:DisassociateAddress`: To disassociate an Elastic IP address from an instance or a network interface.

The following policy allows users to view, allocate, and associate Elastic IP addresses with instances. Users cannot associate Elastic IP addresses with network interfaces, disassociate Elastic IP addresses, or release them.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeAddresses",
                "ec2:AllocateAddress",
                "ec2:DescribeInstances",
                "ec2:AssociateAddress"
            ],
            "Resource": "*"
        }
    ]
}
```

------

## Example: Work with Reserved Instances
<a name="ex-reservedinstances"></a>

The following policy allows users to view and modify Reserved Instances in your account, as well as purchase new Reserved Instances in the AWS Management Console.

This policy allows users to view all the Reserved Instances, as well as On-Demand Instances, in the account. It's not possible to set resource-level permissions for individual Reserved Instances.

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement": [{
      "Effect": "Allow",
      "Action": [
         "ec2:DescribeReservedInstances", 
         "ec2:ModifyReservedInstances",
         "ec2:PurchaseReservedInstancesOffering", 
         "ec2:DescribeInstances",
         "ec2:DescribeInstanceTypes",
         "ec2:DescribeAvailabilityZones", 
         "ec2:DescribeReservedInstancesOfferings"
      ],
      "Resource": "*"
   }
   ]
}
```

------

The `ec2:DescribeAvailabilityZones` action is necessary to ensure that the Amazon EC2 console can display information about the Availability Zones in which you can purchase Reserved Instances. The `ec2:DescribeInstances` action is not required, but ensures that the user can view the instances in the account and purchase reservations to match the correct specifications.

You can adjust the API actions to limit user access, for example removing `ec2:DescribeInstances` and `ec2:DescribeAvailabilityZones` means the user has read-only access.

# AWS managed policies for Amazon EC2
<a name="security-iam-awsmanpol"></a>

To add permissions to users, groups, and roles, it is easier to use AWS managed policies than to write policies yourself. It takes time and expertise to [create IAM customer managed policies](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_create-console.html) that provide your team with only the permissions they need. To get started quickly, you can use our AWS managed policies. These policies cover common use cases and are available in your AWS account. For more information about AWS managed policies, see [AWS managed policies](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html#aws-managed-policies) in the *IAM User Guide*.

AWS services maintain and update AWS managed policies. You can't change the permissions in AWS managed policies. Services occasionally add additional permissions to an AWS managed policy to support new features. This type of update affects all identities (users, groups, and roles) where the policy is attached. Services are most likely to update an AWS managed policy when a new feature is launched or when new operations become available. Services do not remove permissions from an AWS managed policy, so policy updates won't break your existing permissions.

Additionally, AWS supports managed policies for job functions that span multiple services. For example, the **ReadOnlyAccess** AWS managed policy provides read-only access to all AWS services and resources. When a service launches a new feature, AWS adds read-only permissions for new operations and resources. For a list and descriptions of job function policies, see [AWS managed policies for job functions](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_job-functions.html) in the *IAM User Guide*.

## AWS managed policy: AmazonEC2FullAccess
<a name="security-iam-awsmanpol-AmazonEC2FullAccess"></a>

You can attach the `AmazonEC2FullAccess` policy to your IAM identities. This policy grants permissions that allow full access to Amazon EC2.

To view the permissions for this policy, see [https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonEC2FullAccess.html](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonEC2FullAccess.html) in the *AWS Managed Policy Reference*.

## AWS managed policy: AmazonEC2ReadOnlyAccess
<a name="security-iam-awsmanpol-AmazonEC2ReadOnlyAccess"></a>

You can attach the `AmazonEC2ReadOnlyAccess` policy to your IAM identities. This policy grants permissions that allow read-only access to Amazon EC2.

To view the permissions for this policy, see [https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonEC2ReadOnlyAccess.html](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonEC2ReadOnlyAccess.html) in the *AWS Managed Policy Reference*.

## AWS managed policy: AmazonEC2ImageReferencesAccessPolicy
<a name="security-iam-awsmanpol-AmazonEC2ImageReferencesAccessPolicy"></a>

You can attach the `AmazonEC2ImageReferencesAccessPolicy` policy to your IAM identities. This policy grants the permissions needed to use the EC2 DescribeImageReferences API, including permission to view EC2 instances, launch templates, Systems Manager parameters, and Image Builder recipes. The policy supports the `IncludeAllResourceTypes` flag and will continue to work when AWS adds support for new resource types, removing the need for future policy updates.

To view the permissions for this policy, see [https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonEC2ImageReferencesAccessPolicy.html](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonEC2ImageReferencesAccessPolicy.html) in the *AWS Managed Policy Reference*.

## AWS managed policy: AWSEC2CapacityReservationFleetRolePolicy
<a name="security-iam-awsmanpol-AWSEC2CapacityReservationFleetRolePolicy"></a>

This policy is attached to the service-linked role named **AWSServiceRoleForEC2CapacityReservationFleet** to allow the service to create, modify, and cancel Capacity Reservations in a Capacity Reservation Fleet on your behalf. For more information, see [Using service-linked roles for Capacity Reservation FleetUsing service-linked roles for EC2 Capacity Manager](using-service-linked-roles.md).

To view the permissions for this policy, see [https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AWSEC2CapacityReservationFleetRolePolicy.html](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AWSEC2CapacityReservationFleetRolePolicy.html) in the *AWS Managed Policy Reference*.

## AWS managed policy: AWSEC2FleetServiceRolePolicy
<a name="security-iam-awsmanpol-AWSEC2FleetServiceRolePolicy"></a>

This policy is attached to the service-linked role named **AWSServiceRoleForEC2Fleet** to allow EC2 Fleet to request, launch, terminate, and tag instances on your behalf. For more information, see [Service-linked role for EC2 Fleet](ec2-fleet-prerequisites.md#ec2-fleet-service-linked-role).

To view the permissions for this policy, see [https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AWSEC2FleetServiceRolePolicy.html](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AWSEC2FleetServiceRolePolicy.html) in the *AWS Managed Policy Reference*.

## AWS managed policy: AWSEC2SpotFleetServiceRolePolicy
<a name="security-iam-awsmanpol-AWSEC2SpotFleetServiceRolePolicy"></a>

This policy is attached to the service-linked role named **AWSServiceRoleForEC2SpotFleet** to allow Spot Fleet to launch and manage instances on your behalf. For more information, see [Service-linked role for Spot Fleet](spot-fleet-prerequisites.md#service-linked-roles-spot-fleet-requests).

To view the permissions for this policy, see [https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AWSEC2SpotFleetServiceRolePolicy.html](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AWSEC2SpotFleetServiceRolePolicy.html) in the *AWS Managed Policy Reference*.

## AWS managed policy: AWSEC2SpotServiceRolePolicy
<a name="security-iam-awsmanpol-AWSEC2SpotServiceRolePolicy"></a>

This policy is attached to the service-linked role named **AWSServiceRoleForEC2Spot** to allow Amazon EC2 to launch and manage Spot Instances on your behalf. For more information, see [Service-linked role for Spot Instance requests](service-linked-roles-spot-instance-requests.md).

To view the permissions for this policy, see [https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AWSEC2SpotServiceRolePolicy.html](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AWSEC2SpotServiceRolePolicy.html) in the *AWS Managed Policy Reference*.

## AWS managed policy: AWSEC2VssSnapshotPolicy
<a name="security-iam-awsmanpol-AWSEC2VssSnapshotPolicy"></a>

You can attach this managed policy to the IAM instance profile role that you use for your Amazon EC2 Windows instances. The policy grants permissions to allow Amazon EC2 to create and manage VSS snapshots on your behalf.

To view the permissions for this policy, see [https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AWSEC2VssSnapshotPolicy.html](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AWSEC2VssSnapshotPolicy.html) in the *AWS Managed Policy Reference*.

## AWS managed policy: DeclarativePoliciesEC2Report
<a name="security-iam-awsmanpol-DeclarativePoliciesEC2Report"></a>

This policy is attached to the service-linked role named `AWSServiceRoleForDeclarativePoliciesEC2Report` to provide access to read-only APIs needed to generate the account status report for declarative policies.

To view the permissions for this policy, see [https://docs.aws.amazon.com/aws-managed-policy/latest/reference/DeclarativePoliciesEC2Report.html](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/DeclarativePoliciesEC2Report.html) in the *AWS Managed Policy Reference*.

## AWS managed policy: EC2FastLaunchFullAccess
<a name="security-iam-awsmanpol-EC2FastLaunchFullAccess"></a>

You can attach the `EC2FastLaunchFullAccess` policy to your instance profile or other IAM role. This policy grants full access to EC2 Fast Launch actions, and targeted permissions as follows.

**Permissions details**
+ **EC2 Fast Launch** – Administrative access is granted, so that the role can enable or disable EC2 Fast Launch, and describe EC2 Fast Launch images.
+ **Amazon EC2** – Access is granted for Amazon EC2 RunInstances, CreateTags, Describe, and Create and Modify Launch Template operations. Access is also granted to create network and security group resources, authorize ingress rules, and delete resources that EC2 Fast Launch created.
+ **IAM** – Access is granted to get and use instance profiles whose name contains `ec2fastlaunch` to create the EC2FastLaunchServiceRolePolicy service-linked role.
+ **CloudFormation** – Access is granted for EC2 Fast Launch to describe and create CloudFormation stacks, and to delete stacks that it created.

To view the permissions for this policy, see [https://docs.aws.amazon.com/aws-managed-policy/latest/reference/EC2FastLaunchFullAccess.html](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/EC2FastLaunchFullAccess.html) in the *AWS Managed Policy Reference*.

## AWS managed policy: AWSEC2CapacityManagerServiceRolePolicy
<a name="security-iam-awsmanpol-AWSEC2CapacityManagerServiceRolePolicy"></a>

This policy is attached to the service-linked role named **AWSServiceRoleForEC2CapacityManager** to allow EC2 Capacity Manager to manage capacity resources and integrate with AWS Organizations on your behalf. For more information, see [Service-linked roles for EC2 Capacity Manager](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-service-linked-roles-cm.html).

To view the permissions for this policy, see [https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AWSEC2CapacityManagerServiceRolePolicy.html](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AWSEC2CapacityManagerServiceRolePolicy.html) in the *AWS Managed Policy Reference*.

## AWS managed policy: EC2FastLaunchServiceRolePolicy
<a name="security-iam-awsmanpol-EC2FastLaunchServiceRolePolicy"></a>

This policy is attached to the service-linked role named **AWSServiceRoleForEC2FastLaunch** to allow Amazon EC2 to create and manage a set of pre-provisioned snapshots that reduce the time it takes to launch instances from your EC2 Fast Launch-enabled AMI. For more information, see [Service-linked role for EC2 Fast Launch](slr-windows-fast-launch.md).

To view the permissions for this policy, see [https://docs.aws.amazon.com/aws-managed-policy/latest/reference/EC2FastLaunchServiceRolePolicy.html](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/EC2FastLaunchServiceRolePolicy.html) in the *AWS Managed Policy Reference*.

## AWS managed policy: Ec2InstanceConnect
<a name="Ec2InstanceConnect"></a>

You can attach the `Ec2InstanceConnect` policy to your IAM identities. This policy grants permissions that allows customers to call EC2 Instance Connect to publish ephemeral keys to their EC2 instances and connect via ssh or the EC2 Instance Connect CLI.

To view the permissions for this policy, see [https://docs.aws.amazon.com/aws-managed-policy/latest/reference/EC2InstanceConnect.html](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/EC2InstanceConnect.html) in the *AWS Managed Policy Reference*.

## AWS managed policy: Ec2InstanceConnectEndpoint
<a name="Ec2InstanceConnectEndpoint"></a>

This policy is attached to a service-linked role named **AWSServiceRoleForEC2InstanceConnect** to allow EC2 Instance Connect Endpoint to perform actions on your behalf. For more information, see [Service-linked role for EC2 Instance Connect Endpoint](eice-slr.md).

To view the permissions for this policy, see [https://docs.aws.amazon.com/aws-managed-policy/latest/reference/Ec2InstanceConnectEndpoint.html](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/Ec2InstanceConnectEndpoint.html) in the *AWS Managed Policy Reference*. For a description of the updates to this policy, see [Amazon EC2 updates to AWS managed policies](#security-iam-awsmanpol-updates).

## Amazon EC2 updates to AWS managed policies
<a name="security-iam-awsmanpol-updates"></a>

View details about updates to AWS managed policies for Amazon EC2 since this service began tracking these changes.


| Change | Description | Date | 
| --- | --- | --- | 
|  [AWSEC2CapacityManagerServiceRolePolicy](#security-iam-awsmanpol-AWSEC2CapacityManagerServiceRolePolicy) – New policy  | Amazon EC2 added this policy to allow you to manage capacity resources and integrate with AWS Organizations on your behalf. | October 15, 2025 | 
|  [AmazonEC2ImageReferencesAccessPolicy](#security-iam-awsmanpol-AmazonEC2ImageReferencesAccessPolicy) – New policy  | Amazon EC2 added this policy to provide permission to scan all resources types supported by the EC2 DescribeImageReferences API. | August 26, 2025 | 
| [Ec2InstanceConnectEndpoint](#Ec2InstanceConnectEndpoint) – Updated policy | To support the modification of existing Instance Connect Endpoints, Amazon EC2 updated this policy to add permissions to assign and unassign IPv6 addresses and modify security groups on network interfaces created by EC2 Instance Connect Endpoint. Amazon EC2 also updated this policy to replace the Null condition operator with the StringLike condition operator. | July 31, 2025 | 
| [EC2FastLaunchServiceRolePolicy](#security-iam-awsmanpol-EC2FastLaunchServiceRolePolicy) – Updated policy | To help prevent orphaned resources, Amazon EC2 updated this policy to add permission to describe volumes, volume attributes and network interfaces, and to delete volumes and network interfaces that EC2 Fast Launch created. | July 17, 2025 | 
| [EC2FastLaunchFullAccess](#security-iam-awsmanpol-EC2FastLaunchFullAccess) – Updated policy | Amazon EC2 updated this policy to include Create and Modify Launch Template operations, to create network and security group resources, authorize ingress rules, and delete resources that EC2 Fast Launch created. It can additionally describe and create CloudFormation stacks, and delete stacks that EC2 Fast Launch created. | May 14, 2025 | 
| [EC2FastLaunchServiceRolePolicy](#security-iam-awsmanpol-EC2FastLaunchServiceRolePolicy) – Updated policy | Amazon EC2 updated this policy to add Amazon EventBridge access to create and manage event rules for EC2 Fast Launch. Additionally, EC2 Fast Launch can now describe CloudFormation stacks, launch an instance from an AMI that's associated with AWS License Manager, get a list of AWS KMS grants it created that can be retired, and delete launch templates that it created. | May 14, 2025 | 
| [AWSEC2CapacityReservationFleetRolePolicy](#security-iam-awsmanpol-AWSEC2CapacityReservationFleetRolePolicy) – Updated permissions | Amazon EC2 updated the AWSEC2CapacityReservationFleetRolePolicy managed policy to use the ArnLike condition operator instead of the StringLike condition operator. | March 03, 2025 | 
| [AmazonEC2ReadOnlyAccess](#security-iam-awsmanpol-AmazonEC2ReadOnlyAccess) – Added permissions | Amazon EC2 added a permission that allows you to retrieve security groups using the GetSecurityGroupsForVpc operation. | December 27, 2024 | 
| [EC2FastLaunchFullAccess](#security-iam-awsmanpol-EC2FastLaunchFullAccess) – New policy | Amazon EC2 added this policy to perform API actions related to the EC2 Fast Launch feature from an instance. The policy can be attached to the instance profile for an instance that's launched from a EC2 Fast Launch enabled AMI. | May 14, 2024 | 
| [AWSEC2VssSnapshotPolicy](#security-iam-awsmanpol-AWSEC2VssSnapshotPolicy) – New policy | Amazon EC2 added the AWSEC2VssSnapshotPolicy policy that contains permissions to create and add tags to Amazon Machine Images (AMIs) and EBS snapshots. | March 28, 2024 | 
| [Ec2InstanceConnectEndpoint](#Ec2InstanceConnectEndpoint) – New policy | Amazon EC2 added the Ec2InstanceConnectEndpoint policy. This policy is attached to the AWSServiceRoleForEC2InstanceConnect service-linked role, to allow Amazon EC2 to perform actions on your behalf when you create an EC2 Instance Connect Endpoint. | January 24, 2023 | 
| [EC2FastLaunchServiceRolePolicy](#security-iam-awsmanpol-EC2FastLaunchServiceRolePolicy) – New policy | Amazon EC2 added the EC2 Fast Launch feature to enable Windows AMIs to launch instances faster by creating a set of pre-provisioned snapshots. | November 26, 2021 | 
| Amazon EC2 started tracking changes | Amazon EC2 started tracking changes to its AWS managed policies | March 1, 2021 | 

# IAM roles for Amazon EC2
<a name="iam-roles-for-amazon-ec2"></a>

Applications must sign their API requests with AWS credentials. Therefore, if you are an application developer, you need a strategy for managing credentials for your applications that run on EC2 instances. For example, you can securely distribute your AWS credentials to the instances, enabling the applications on those instances to use your credentials to sign requests, while protecting your credentials from other users. However, it's challenging to securely distribute credentials to each instance, especially those that AWS creates on your behalf, such as Spot Instances or instances in Auto Scaling groups. You must also be able to update the credentials on each instance when you rotate your AWS credentials.

We designed IAM roles so that your applications can securely make API requests from your instances, without requiring you to manage the security credentials that the applications use. Instead of creating and distributing your AWS credentials, you can delegate permission to make API requests using IAM roles as follows:

1. Create an IAM role.

1. Define which accounts or AWS services can assume the role.

1. Define which API actions and resources the application can use after assuming the role.

1. Specify the role when you launch your instance, or attach the role to an existing instance.

1. Have the application retrieve a set of temporary credentials and use them.

For example, you can use IAM roles to grant permissions to applications running on your instances that need to use a bucket in Amazon S3. You can specify permissions for IAM roles by creating a policy in JSON format. These are similar to the policies that you create for users. If you change a role, the change is propagated to all instances.

**Note**  
Amazon EC2 IAM role credentials are not subject to maximum session durations configured in the role. For more information, see [Methods to assume a role](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_manage-assume.html) in the *IAM User Guide*.

When creating IAM roles, associate least privilege IAM policies that restrict access to the specific API calls the application requires. For Windows-to-Windows communication, use well-defined and well-documented Windows groups and roles to grant application-level access between Windows instances. Groups and roles allow customers to define least privilege application and NTFS folder-level permissions to limit access to application-specific requirements.

You can only attach one IAM role to an instance, but you can attach the same role to many instances. For more information about creating and using IAM roles, see [Roles](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html) in the *IAM User Guide*.

You can apply resource-level permissions to your IAM policies to control the users' ability to attach, replace, or detach IAM roles for an instance. For more information, see [Supported resource-level permissions for Amazon EC2 API actions](iam-policies-for-amazon-ec2.md#ec2-supported-iam-actions-resources) and the following example: [Example: Work with IAM roles](ExamplePolicies_EC2.md#iam-example-iam-roles).

**Topics**
+ [Instance profiles](#ec2-instance-profile)
+ [Permissions for your use case](#generate-policy-for-iam-role)
+ [Retrieve security credentials](instance-metadata-security-credentials.md)
+ [Permissions to attach a role to an instance](permission-to-pass-iam-roles.md)
+ [Attach a role to an instance](attach-iam-role.md)
+ [Instance identity roles](#ec2-instance-identity-roles)

## Instance profiles
<a name="ec2-instance-profile"></a>

Amazon EC2 uses an *instance profile* as a container for an IAM role. When you create an IAM role using the IAM console, the console creates an instance profile automatically and gives it the same name as the role to which it corresponds. If you use the Amazon EC2 console to launch an instance with an IAM role or to attach an IAM role to an instance, you choose the role based on a list of instance profile names. 

If you use the AWS CLI, API, or an AWS SDK to create a role, you create the role and instance profile as separate actions, with potentially different names. If you then use the AWS CLI, API, or an AWS SDK to launch an instance with an IAM role or to attach an IAM role to an instance, specify the instance profile name. 

An instance profile can contain only one IAM role. You can include an IAM role in multiple instance profiles.

To update permissions for an instance, replace its instance profile. We do not recommend removing a role from an instance profile, because there is a delay of up to one hour before this change takes effect.

For more information, see [Use instance profiles](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2_instance-profiles.html) in the *IAM User Guide*.

## Permissions for your use case
<a name="generate-policy-for-iam-role"></a>

When you first create an IAM role for your applications, you might sometimes grant permissions beyond what is required. Before launching your application in your production environment, you can generate an IAM policy that is based on the access activity for an IAM role. IAM Access Analyzer reviews your AWS CloudTrail logs and generates a policy template that contains the permissions that have been used by the role in your specified date range. You can use the template to create a managed policy with fine-grained permissions and then attach it to the IAM role. That way, you grant only the permissions that the role needs to interact with AWS resources for your specific use case. This helps you adhere to the best practice of [granting least privilege](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege). For more information, see [IAM Access Analyzer policy generation](https://docs.aws.amazon.com/IAM/latest/UserGuide/access-analyzer-policy-generation.html) in the *IAM User Guide*.

# Retrieve security credentials from instance metadata
<a name="instance-metadata-security-credentials"></a>

An application on the instance retrieves the security credentials provided by the role from the instance metadata item `iam/security-credentials/`*role-name*. The application is granted the permissions for the actions and resources that you've defined for the role through the security credentials associated with the role. These security credentials are temporary and we rotate them automatically. We make new credentials available at least five minutes before the expiration of the old credentials.

For more information about instance metadata, see [Use instance metadata to manage your EC2 instance](ec2-instance-metadata.md).

**Warning**  
If you use services that use instance metadata with IAM roles, ensure that you don't expose your credentials when the services make HTTP calls on your behalf. The types of services that could expose your credentials include HTTP proxies, HTML/CSS validator services, and XML processors that support XML inclusion.

For your Amazon EC2 workloads, we recommend that you retrieve session credentials using the method described below. These credentials should enable your workload to make AWS API requests, without needing to use `sts:AssumeRole` to assume the same role that is already associated with the instance. Unless you need to pass session tags for attribute-based access control (ABAC) or pass a session policy to further restrict permissions of the role, such role assumption calls are unnecessary as they create a new set of the same temporary role session credentials.

If your workload uses a role to assume itself, you must create a trust policy that explicitly allows that role to assume itself. If you do not create the trust policy, you get an `AccessDenied` error. For more information, see [ Update a role trust policy](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_update-role-trust-policy.html) in the *IAM User Guide*.

------
#### [ IMDSv2 ]

**Linux**  
Run the following command from your Linux instance to retrieve the security credentials for an IAM role.

```
TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` \
    && curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/role-name
```

**Windows**  
Run the following cmdlet from your Windows instance to retrieve the security credentials for an IAM role.

```
[string]$token = Invoke-RestMethod `
    -Headers @{"X-aws-ec2-metadata-token-ttl-seconds" = "21600"} `
    -Method PUT -Uri http://169.254.169.254/latest/api/token
```

```
Invoke-RestMethod `
    -Headers @{"X-aws-ec2-metadata-token" = $token} `
    -Method GET -Uri http://169.254.169.254/latest/meta-data/iam/security-credentials/role-name
```

------
#### [ IMDSv1 ]

**Linux**  
Run the following command from your Linux instance to retrieve the security credentials for an IAM role.

```
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/role-name
```

**Windows**  
Run the following cmdlet from your Windows instance to retrieve the security credentials for an IAM role.

```
Invoke-RestMethod -uri http://169.254.169.254/latest/meta-data/iam/security-credentials/role-name
```

------

The following is example output. If you are not able to retrieve the security credentials, see [I can't access the temporary security credentials on my EC2 instance](https://docs.aws.amazon.com/IAM/latest/UserGuide/troubleshoot_iam-ec2.html#troubleshoot_iam-ec2_no-keys) in the *IAM User Guide*.

```
{
  "Code" : "Success",
  "LastUpdated" : "2012-04-26T16:39:16Z",
  "Type" : "AWS-HMAC",
  "AccessKeyId" : "ASIAIOSFODNN7EXAMPLE",
  "SecretAccessKey" : "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
  "Token" : "token",
  "Expiration" : "2017-05-17T15:09:54Z"
}
```

For applications, AWS CLI, and Tools for Windows PowerShell commands that run on the instance, you do not have to explicitly get the temporary security credentials—the AWS SDKs, AWS CLI, and Tools for Windows PowerShell automatically get the credentials from the EC2 instance metadata service and use them. To make a call outside of the instance using temporary security credentials (for example, to test IAM policies), you must provide the access key, secret key, and the session token. For more information, see [Using Temporary Security Credentials to Request Access to AWS Resources](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html) in the *IAM User Guide*.

# Grant permissions to attach an IAM role to an instance
<a name="permission-to-pass-iam-roles"></a>

The identities in your AWS account, such as IAM users, must have specific permissions to launch an Amazon EC2 instance with an IAM role, attach an IAM role to an instance, replace the IAM role for an instance, or detach an IAM role from an instance. You must grant permission to use the following API actions as required:
+ `iam:PassRole`
+ `ec2:AssociateIamInstanceProfile`
+ `ec2:DisassociateIamInstanceProfile`
+ `ec2:ReplaceIamInstanceProfileAssociation`

**Note**  
If you specify the resource for `iam:PassRole` as `*`, this would grant access to pass any of your IAM roles to an instance. To follow the best practice of [least privilege](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege), specify the ARNs of specific IAM roles with `iam:PassRole`, as shown in the example policy below.

**Example policy for programmatic access**  
The following IAM policy grants permissions to launch instances with an IAM role, attach an IAM role to an instance, or replace the IAM role for an instance using the AWS CLI or the Amazon EC2 API.

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
         "ec2:RunInstances",
         "ec2:AssociateIamInstanceProfile",
         "ec2:DisassociateIamInstanceProfile",
         "ec2:ReplaceIamInstanceProfileAssociation"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": "iam:PassRole",
      "Resource": "arn:aws:iam::123456789012:role/DevTeam*"
    }
  ]
}
```

------

**Additional requirement for console access**  
To grant permissions to complete the same tasks using the Amazon EC2 console, you must also include the `iam:ListInstanceProfiles` API action.

# Attach an IAM role to an instance
<a name="attach-iam-role"></a>

You can create an IAM role and attach it to an instance during or after launch. You can also replace or detach IAM roles.

**Creating and attaching an IAM role during instance launch (Recommended)**

1. During EC2 instance launch, expand **Advanced details**.

1. In the **IAM instance profile** section, choose **Create new IAM role**.

1. An inline role creation form opens, allowing you to:
   + Specify **Role name** (for example, `EC2-S3-Access-Role`)
   + Define permissions by selecting AWS managed policies or creating custom policies for your instance

     For example, to grant S3 access, select the `AmazonS3ReadOnlyAccess` managed policy
   + Review the trust policy that allows `ec2.amazonaws.com` to assume the role
   + Add optional tags for metadata

1. Choose **Create role**.

   The newly created role is automatically selected and will be attached to your instance via an instance profile when the instance launches.

**Note**  
When you create a role using the console during instance launch, an instance profile with the same name as the role is automatically created. The instance profile is a container that passes IAM role information to the instance at launch.

**Important**  
You can only attach one IAM role to an instance, but you can attach the same role to many instances.
Associate least privilege IAM policies that restrict access to the specific API calls the application requires.

For more information about creating and using IAM roles, see [Roles](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html) in the *IAM User Guide*.

**Attaching an existing IAM role during instance launch**  
To attach an existing IAM role to an instance at launch using the Amazon EC2 console, expand **Advanced details**. For **IAM instance profile**, select the IAM role from the dropdown list.

**Note**  
If you created your IAM role using the IAM console, the instance profile was created for you and given the same name as the role. If you created your IAM role using the AWS CLI, API, or an AWS SDK, you might have given your instance profile a different name than the role.

You can attach an IAM role to an instance that is running or stopped. If the instance already has an IAM role attached, you must replace it with the new IAM role.

------
#### [ Console ]<a name="attach-iam-role-console"></a>

**To attach an IAM role to an instance**

1. Open the Amazon EC2 console at [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/).

1. In the navigation pane, choose **Instances**.

1. Select the instance.

1. Choose **Actions**, **Security**, **Modify IAM role**.

1. For **IAM role**, select the IAM instance profile.

1. Choose **Update IAM role**.

------
#### [ AWS CLI ]
<a name="attach-iam-role-instance-cli"></a>
**To attach an IAM role to an instance**  
Use the [associate-iam-instance-profile](https://docs.aws.amazon.com/cli/latest/reference/ec2/associate-iam-instance-profile.html) command to attach the IAM role to the instance. When you specify the instance profile, you can use either the Amazon Resource Name (ARN) of the instance profile, or you can use its name.

```
aws ec2 associate-iam-instance-profile \
    --instance-id i-1234567890abcdef0 \
    --iam-instance-profile Name="TestRole-1"
```

------
#### [ PowerShell ]

**To attach an IAM role to an instance**  
Use the [Register-EC2IamInstanceProfile](https://docs.aws.amazon.com/powershell/latest/reference/items/Register-EC2IamInstanceProfile.html) cmdlet.

```
Register-EC2IamInstanceProfile `
    -InstanceId i-1234567890abcdef0 `
    -IamInstanceProfile_Name TestRole-1
```

------

To replace the IAM role on an instance that already has an attached IAM role, the instance must be running. You can do this if you want to change the IAM role for an instance without detaching the existing one first. For example, you can do this to ensure that API actions performed by applications running on the instance are not interrupted.

------
#### [ Console ]<a name="replace-iam-role-console"></a>

**To replace an IAM role for an instance**

1. Open the Amazon EC2 console at [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/).

1. In the navigation pane, choose **Instances**.

1. Select the instance.

1. Choose **Actions**, **Security**, **Modify IAM role**.

1. For **IAM role**, select the IAM instance profile.

1. Choose **Update IAM role**.

------
#### [ AWS CLI ]<a name="replace-iam-role-cli"></a>

**To replace an IAM role for an instance**

1. If required, use the [describe-iam-instance-profile-associations](https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-iam-instance-profile-associations.html) command to get the association ID.

   ```
   aws ec2 describe-iam-instance-profile-associations \
       --filters Name=instance-id,Values=i-1234567890abcdef0 \
       --query IamInstanceProfileAssociations.AssociationId
   ```

1. Use the [replace-iam-instance-profile-association](https://docs.aws.amazon.com/cli/latest/reference/ec2/replace-iam-instance-profile-association.html) command. Specify the association ID for the existing instance profile and the ARN or name of the new instance profile.

   ```
   aws ec2 replace-iam-instance-profile-association \
       --association-id iip-assoc-0044d817db6c0a4ba \
       --iam-instance-profile Name="TestRole-2"
   ```

------
#### [ PowerShell ]

**To replace an IAM role for an instance**

1. If required, use the [Get-EC2IamInstanceProfileAssociation](https://docs.aws.amazon.com/powershell/latest/reference/items/Get-EC2IamInstanceProfileAssociation.html) cmdlet to get the association ID.

   ```
   (Get-EC2IamInstanceProfileAssociation -Filter @{Name="instance-id"; Values="i-0636508011d8e966a"}).AssociationId
   ```

1. Use the [Set-EC2IamInstanceProfileAssociation](https://docs.aws.amazon.com/powershell/latest/reference/items/Set-EC2IamInstanceProfileAssociation.html) cmdlet. Specify the association ID for the existing instance profile and the ARN or name of the new instance profile.

   ```
   Set-EC2IamInstanceProfileAssociation `
       -AssociationId iip-assoc-0044d817db6c0a4ba `
       -IamInstanceProfile_Name TestRole-2
   ```

------

You can detach an IAM role from an instance that is running or stopped.

------
#### [ Console ]<a name="detach-iam-role-console"></a>

**To detach an IAM role from an instance**

1. Open the Amazon EC2 console at [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/).

1. In the navigation pane, choose **Instances**.

1. Select the instance.

1. Choose **Actions**, **Security**, **Modify IAM role**.

1. For **IAM role**, choose **No IAM Role**.

1. Choose **Update IAM role**.

1. When promoted for confirmation, enter **Detach**, and then choose **Detach**.

------
#### [ AWS CLI ]<a name="detach-iam-role-cli"></a>

**To detach an IAM role from an instance**

1. If required, use [describe-iam-instance-profile-associations](https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-iam-instance-profile-associations.html) to get the association ID for the IAM instance profile to detach.

   ```
   aws ec2 describe-iam-instance-profile-associations \
       --filters Name=instance-id,Values=i-1234567890abcdef0 \
       --query IamInstanceProfileAssociations.AssociationId
   ```

1. Use the [disassociate-iam-instance-profile](https://docs.aws.amazon.com/cli/latest/reference/ec2/disassociate-iam-instance-profile.html) command.

   ```
   aws ec2 disassociate-iam-instance-profile --association-id iip-assoc-0044d817db6c0a4ba
   ```

------
#### [ PowerShell ]

**To detach an IAM role from an instance**

1. If required, use [Get-EC2IamInstanceProfileAssociation](https://docs.aws.amazon.com/powershell/latest/reference/items/Get-EC2IamInstanceProfileAssociation.html) to get the association ID for the IAM instance profile to detach.

   ```
   (Get-EC2IamInstanceProfileAssociation -Filter @{Name="instance-id"; Values="i-0636508011d8e966a"}).AssociationId
   ```

1. Use the [Unregister-EC2IamInstanceProfile](https://docs.aws.amazon.com/powershell/latest/reference/items/Unregister-EC2IamInstanceProfile.html) cmdlet.

   ```
   Unregister-EC2IamInstanceProfile -AssociationId iip-assoc-0044d817db6c0a4ba
   ```

------

## Instance identity roles for Amazon EC2 instances
<a name="ec2-instance-identity-roles"></a>

Each Amazon EC2 instance that you launch has an *instance identity role* that represents its identity. An instance identity role is a type of IAM role. AWS services and features that are integrated to use the instance identity role can use it to identify the instance to the service.

The instance identity role credentials are accessible from the Instance Metadata Service (IMDS) at `/identity-credentials/ec2/security-credentials/ec2-instance`. The credentials consist of an AWS temporary access key pair and a session token. They are used to sign AWS Sigv4 requests to the AWS services that use the instance identity role. The credentials are present in the instance metadata regardless of whether a service or feature that makes use of instance identity roles is enabled on the instance.

Instance identity roles are automatically created when an instance is launched, have no role-trust policy document, and are not subject to any identity or resource policy.

### Supported services
<a name="iir-supported-services"></a>

The following AWS services use the instance identity role:
+ **Amazon EC2** – [EC2 Instance Connect](connect-linux-inst-eic.md) uses the instance identity role to update the host keys for a Linux instance.
+ **Amazon GuardDuty** – [GuardDuty Runtime Monitoring](https://docs.aws.amazon.com/guardduty/latest/ug/runtime-monitoring.html) uses the instance identity role to allow the runtime agent to send security telemetry to the GuardDuty VPC endpoint.
+ **AWS Lambda** – [Lambda Managed Instances](https://docs.aws.amazon.com/lambda/latest/dg/lambda-managed-instances.html) uses the instance identity role for lifecycle hooks, telemetry, and artifact distribution.
+ **AWS Security Token Service (AWS STS)** – Instance identity role credentials can be used with the AWS STS [https://docs.aws.amazon.com/STS/latest/APIReference/API_GetCallerIdentity.html](https://docs.aws.amazon.com/STS/latest/APIReference/API_GetCallerIdentity.html) action.
+ **AWS Systems Manager** – When using [Default Host Management Configuration](https://docs.aws.amazon.com/systems-manager/latest/userguide/fleet-manager-default-host-management-configuration.html), AWS Systems Manager uses the identity provided by the instance identity role to register EC2 instances. After identifying your instance, Systems Manager can pass your `AWSSystemsManagerDefaultEC2InstanceManagementRole` IAM role to your instance.

Instance identity roles can’t be used with other AWS services or features because they do not have an integration with instance identity roles.

### Instance identity role ARN
<a name="iir-arn"></a>

The instance identity role ARN takes the following format:

```
arn:aws-partition:iam::account-number:assumed-role/aws:ec2-instance/instance-id
```

For example:

```
arn:aws:iam::0123456789012:assumed-role/aws:ec2-instance/i-1234567890abcdef0
```

For more information about ARNs, see [Amazon Resource Names (ARNs)](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference-arns.html) in the *IAM User Guide*.

# Update management for Amazon EC2 instances
<a name="update-management"></a>

We recommend that you regularly patch, update, and secure the operating system and applications on your EC2 instances. You can use [AWS Systems Manager Patch Manager](https://docs.aws.amazon.com/systems-manager/latest/userguide/patch-manager.html) to automate the process of installing security-related updates for both the operating system and applications.

For EC2 instances in an Auto Scaling group, you can use the [https://docs.aws.amazon.com/systems-manager-automation-runbooks/latest/userguide/automation-aws-patchasginstance.html](https://docs.aws.amazon.com/systems-manager-automation-runbooks/latest/userguide/automation-aws-patchasginstance.html) runbook to help avoid instances that are undergoing patching from being replaced. Alternatively, you can use any automatic update services or recommended processes for installing updates that are provided by the application vendor.

**Resources**
+ **AL2023** – [Updating AL2023](https://docs.aws.amazon.com/linux/al2023/ug/updating.html) in the *Amazon Linux 2023 User Guide*
+ **AL2** – [Manage software on your Amazon Linux 2 instance](https://docs.aws.amazon.com/linux/al2/ug/managing-software.html) in the *Amazon Linux 2 User Guide*
+ **Windows instances** – [Update management](ec2-windows-security-best-practices.md#ec2-windows-update-management)

# Security best practices for Windows instances
<a name="ec2-windows-security-best-practices"></a>

We recommend that you follow these security best practices for your Windows instances.

**Topics**
+ [High-level security best practices](#high-level-security)
+ [Update management](#ec2-windows-update-management)
+ [Configuration management](#configuration-management)
+ [Change management](#change-management)
+ [Audit and accountability for Amazon EC2 Windows instances](#audit-accountability)

## High-level security best practices
<a name="high-level-security"></a>

You should adhere to the following high-level security best practices for your Windows instances:
+ **Least access** – Grant access only to systems and locations that are trusted and expected. This applies to all Microsoft products such as Active Directory, Microsoft business productivity servers, and infrastructure services such as Remote Desktop Services, reverse proxy servers, IIS web servers,and more. Use AWS capabilities such as Amazon EC2 instance security groups, network access control lists (ACLs), and Amazon VPC public/private subnets to layer security across multiple locations in an architecture. Within a Windows instance, customers can use Windows Firewall to further layer a defense-in-depth strategy within their deployment. Install only the OS components and applications that are necessary for the system to function as designed. Configure infrastructure services such as IIS to run under service accounts, or to use features such as application pool identities to access resources locally and remotely across your infrastructure.
+ **Least privilege** – Determine the minimum set of privileges that instances and accounts need in order to perform their functions. Restrict these servers and users to only allow these defined permissions. Use techniques such as Role Based Access Controls to reduce the surface area of administrative accounts, and create the most limited roles to accomplish a task. Use OS features such as Encrypting File System (EFS) within NTFS to encrypt sensitive data at rest, and control application and user access to it.
+ **Configuration management** – Create a baseline server configuration that incorporates up-to-date security patches and host-based protection suites that include anti-virus, anti-malware, intrusion detection/prevention, and file integrity monitoring. Assess each server against the current recorded baseline to identify and flag any deviations. Ensure each server is configured to generate and securely store appropriate log and audit data.
+ **Change management** – Create processes to control changes to server configuration baselines and work toward fully automated change processes. Also, leverage Just Enough Administration (JEA) with Windows PowerShell DSC to limit administrative access to the minimum required functions.
+ **Patch management** – Implement processes that regularly patch, update, and secure the operating system and applications on your EC2 instances.
+ **Audit logs** – Audit access and all changes to Amazon EC2 instances to verify server integrity and ensure only authorized changes are made. Leverage features such as [Enhanced Logging for IIS](https://learn.microsoft.com/en-us/iis/get-started/whats-new-in-iis-85/enhanced-logging-for-iis85) to enhance default logging capabilities. AWS capabilities such as VPC Flow Logs and AWS CloudTrail are also available to audit network access, including allowed/denied requests and API calls, respectively.

## Update management
<a name="ec2-windows-update-management"></a>

To ensure the best results when you run Windows Server on Amazon EC2, we recommend that you implement the following best practices:
+ [Configure Windows Update](#windows-update)
+ [Update drivers](#drivers)
+ [Use the latest Windows AMIs](#AMI)
+ [Test performance before migration](#test)
+ [Update launch agents](#agents)
+ Reboot your Windows instance after you install updates. For more information, see [Reboot your Amazon EC2 instance](ec2-instance-reboot.md).

For information about how to upgrade or migrate a Windows instance to a newer version of Windows Server, see [Upgrade an EC2 Windows instance to a newer version of Windows Server](serverupgrade.md).

**Configure Windows Update**  
By default, instances that are launched from AWS Windows Server AMIs don't receive updates through Windows Update.

**Update Windows drivers**

Maintain the latest drivers on all Windows EC2 instances to ensure that the latest issue fixes and performance enhancements are applied across your fleet. Depending on your instance type, you should update the AWS PV, Amazon ENA, and AWS NVMe drivers.
+ Use [SNS topics](xen-drivers-overview.md#drivers-subscribe-notifications) to receive updates for new driver releases.
+ Use the AWS Systems Manager Automation runbook [AWSSupport-UpgradeWindowsAWSDrivers](https://docs.aws.amazon.com/systems-manager-automation-runbooks/latest/userguide/automation-awssupport-upgradewindowsawsdrivers.html) to easily apply the updates across your instances.

**Launch instances using the latest Windows AMIs**

AWS releases new Windows AMIs each month, which contain the latest OS patches, drivers, and launch agents. You should leverage the latest AMI when you launch new instances or when you build your own custom images.
+ To view updates to each release of the AWS Windows AMIs, see [AWS Windows AMI version history](https://docs.aws.amazon.com/ec2/latest/windows-ami-reference/ec2-windows-ami-version-history.html).
+ To build with the latest available AMIs, see [Query for the Latest Windows AMI Using Systems Manager Parameter Store](https://aws.amazon.com/blogs/mt/query-for-the-latest-windows-ami-using-systems-manager-parameter-store/).
+ For more information about specialized Windows AMIs that you can use to launch instances for your database and compliance hardening use cases, see [Specialized Windows AMIs](https://docs.aws.amazon.com/ec2/latest/windows-ami-reference/specialized-windows-amis.html) in the *AWS Windows AMI Reference*.

**Test system/application performance before migration**

Migrating enterprise applications to AWS can involve many variables and configurations. Always performance test the EC2 solution to ensure that:
+ Instance types are properly configured, including instance size, enhanced networking, and tenancy (shared or dedicated).
+ Instance topology is appropriate for the workload and leverages high-performance features when necessary, such as dedicated tenancy, placement groups, instance store volumes, and bare metal.

**Install the latest version of EC2Launch v2**  
Install the latest EC2Launch v2 agent to ensure that the latest enhancements are applied across your fleet. For more information, see [Install EC2Launch v2](ec2launch-v2-install.md).

If you have a mixed fleet, or if you want to continue to use the EC2Launch (Windows Server 2016 and 2019) or EC2 Config (legacy OS only) agents, update to the latest versions of the respective agents.

Automatic updates are supported on the following combinations of Windows Server version and launch agents. You can opt in to automatic updates in the [SSM Quick Setup Host Management](https://docs.aws.amazon.com/systems-manager/latest/userguide/quick-setup-host-management.html) console under **Amazon EC2 Launch Agents**.


| Windows Version | EC2Launch v1 | EC2Launch v2 | 
| --- | --- | --- | 
| 2016 | ✓ | ✓ | 
| 2019 | ✓ | ✓ | 
| 2022 |  | ✓ | 
+ For more information about updating to EC2Launch v2, see [Install the latest version of EC2Launch v2](ec2launch-v2-install.md).
+ For information to manually update EC2Config, see [Install the latest version of EC2Config](UsingConfig_Install.md). 
+ For information to manually update EC2Launch, see [Install the latest version of EC2Launch](ec2launch-download.md).

## Configuration management
<a name="configuration-management"></a>

Amazon Machine Images (AMIs) provide an initial configuration for an Amazon EC2 instance, which includes the Windows OS and optional customer-specific customizations, such as applications and security controls. Create an AMI catalog containing customized security configuration baselines to ensure that all Windows instances are launched with standard security controls. Security baselines can be baked into an AMI, bootstrapped dynamically when an EC2 instance is launched, or packaged as a product for uniform distribution through AWS Service Catalog portfolios. For more information on securing an AMI, see [Best Practices for Building an AMI](https://docs.aws.amazon.com/marketplace/latest/userguide/best-practices-for-building-your-amis.html).

Each Amazon EC2 instance should adhere to organizational security standards. Do not install any Windows roles and features that are not required, and do install software to protect against malicious code (antivirus, antimalware, exploit mitigation), monitor host-integrity, and perform intrusion detection. Configure security software to monitor and maintain OS security settings, protect the integrity of critical OS files, and alert on deviations from the security baseline. Consider implementing recommended security configuration benchmarks published by Microsoft, the Center for Internet Security (CIS), or the National Institute of Standards and Technology (NIST). Consider using other Microsoft tools for particular application servers, such as the [Best Practice Analyzer for SQL Server](https://www.microsoft.com/en-us/download/details.aspx?id=29302).

AWS customers can also run Amazon Inspector assessments to improve the security and compliance of applications deployed on Amazon EC2 instances. Amazon Inspector automatically assesses applications for vulnerabilities or deviations from best practices and includes a knowledge base of hundreds of rules mapped to common security compliance standards (for example, PCI DSS) and vulnerability definitions. Examples of built-in rules include checking if remote root login is enabled, or if vulnerable software versions are installed. These rules are regularly updated by AWS security researchers.

When securing Windows instances, we recommend that you implement Active Directory Domain Services to enable a scalable, secure, and manageable infrastructure for distributed locations. Additionally, after launching instances from the Amazon EC2 console or by using an Amazon EC2 provisioning tool, such as AWS CloudFormation, it is good practice to utilize native OS features, such as Microsoft Windows PowerShell DSC to maintain configuration state in the event that configuration drift occurs.

## Change management
<a name="change-management"></a>

After initial security baselines are applied to Amazon EC2 instances at launch, control ongoing Amazon EC2 changes to maintain the security of your virtual machines. Establish a change management process to authorize and incorporate changes to AWS resources (such as security groups, route tables, and network ACLs) as well as to OS and application configurations (such as Windows or application patching, software upgrades, or configuration file updates).

AWS provides several tools to help manage changes to AWS resources, including AWS CloudTrail, AWS Config, CloudFormation, and AWS Elastic Beanstalk, and management packs for Systems Center Operations Manager and System Center Virtual Machine Manager. Note that Microsoft releases Windows patches the second Tuesday of each month (or as needed) and AWS updates all Windows AMIs managed by AWS within five days after Microsoft releases a patch. Therefore it is important to continually patch all baseline AMIs, update CloudFormation templates and Auto Scaling group configurations with the latest AMI IDs, and implement tools to automate running instance patch management.

Microsoft provides several options for managing Windows OS and application changes. SCCM, for example, provides full lifecycle coverage of environment modifications. Select tools that address business requirements and control how changes will affect application SLAs, capacity, security, and disaster recovery procedures. Avoid manual changes and instead leverage automated configuration management software or command line tools such as the EC2 Run Command or Windows PowerShell to implement scripted, repeatable change processes. To assist with this requirement, use bastion hosts with enhanced logging for all interactions with your Windows instances to ensure that all events and tasks are automatically recorded.

## Audit and accountability for Amazon EC2 Windows instances
<a name="audit-accountability"></a>

AWS CloudTrail, AWS Config, and AWS Config Rules provide audit and change tracking features for auditing AWS resource changes. Configure Windows event logs to send local log files to a centralized log management system to preserve log data for security and operational behavior analysis. Microsoft System Center Operations Manager (SCOM) aggregates information about Microsoft applications deployed to Windows instances and applies preconfigured and custom rulesets based on application roles and services. System Center Management Packs build on SCOM to provide application-specific monitoring and configuration guidance. These [Management Packs](https://learn.microsoft.com/en-us/archive/technet-wiki/16174.microsoft-management-packs) support Windows Server Active Directory, SharePoint Server 2013, Exchange Server 2013, Lync Server 2013, SQL Server 2014, and many more servers and technologies.

In addition to Microsoft systems management tools, customers can use Amazon CloudWatch to monitor instance CPU utilization, disk performance, network I/O, and perform host and instance status checks. The EC2Config, EC2Launch, and EC2Launch v2 launch agents provide access to additional, advanced features for Windows instances. For example, they can export Windows system, security, application, and Internet Information Services (IIS) logs to CloudWatch Logs which can then be integrated with Amazon CloudWatch metrics and alarms. Customers can also create scripts that export Windows performance counters to Amazon CloudWatch custom metrics.

# Amazon EC2 key pairs and Amazon EC2 instances
<a name="ec2-key-pairs"></a>

A key pair, consisting of a public key and a private key, is a set of security credentials that you use to prove your identity when connecting to an Amazon EC2 instance. For Linux instances, the private key allows you to securely SSH into your instance. For Windows instances, the private key is required to decrypt the administrator password, which you then use to connect to your instance.

Amazon EC2 stores the public key on your instance, and you store the private key, as shown in the following diagram. It's important that you store your private key in a secure place because anyone who possesses your private key can connect to your instances that use the key pair.

![\[A key pair consists of a private key for your computer and a public key for your instance.\]](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/images/ec2-key-pair.png)


When you launch an instance, you can [specify a key pair](ec2-instance-launch-parameters.md#liw-key-pair), so that you can connect to your instance using a method that requires a key pair. Depending on how you manage your security, you can specify the same key pair for all your instances or you can specify different key pairs.

For Linux instances, when your instance boots for the first time, the public key that you specified at launch is placed on your Linux instance in an entry within `~/.ssh/authorized_keys`. When you connect to your Linux instance using SSH, to log in you must specify the private key that corresponds to the public key.

For more information about connecting to your EC2 instance, see [Connect to your EC2 instance](connect.md).

**Important**  
Because Amazon EC2 doesn't keep a copy of your private key, there is no way to recover a private key if you lose it. However, there can still be a way to connect to instances for which you've lost the private key. For more information, see [I've lost my private key. How can I connect to my instance?](TroubleshootingInstancesConnecting.md#replacing-lost-key-pair)

As an alternative to key pairs, you can use [AWS Systems Manager Session Manager](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager.html) to connect to your instance with an interactive one-click browser-based shell or the AWS Command Line Interface (AWS CLI).

**Topics**
+ [Create a key pair for your Amazon EC2 instance](create-key-pairs.md)
+ [Describe your key pairs](describe-keys.md)
+ [Delete your key pair](delete-key-pair.md)
+ [Add or replace a public key on your Linux instance](replacing-key-pair.md)
+ [Verify the fingerprint of your key pair](verify-keys.md)

# Create a key pair for your Amazon EC2 instance
<a name="create-key-pairs"></a>

You can use Amazon EC2 to create your key pairs, or you can use a third-party tool to create your key pairs, and then import them to Amazon EC2.

Amazon EC2 supports 2048-bit SSH-2 RSA keys for Linux and Windows instances. Amazon EC2 also supports ED25519 keys for Linux instances.

For instructions on how to connect to your instance after you have created a key pair, see [Connect to your Linux instance using SSH](connect-to-linux-instance.md) and [Connect to your Windows instance using RDP](connecting_to_windows_instance.md).

**Topics**
+ [Create a key pair using Amazon EC2](#having-ec2-create-your-key-pair)
+ [Create a key pair using AWS CloudFormation](#create-key-pair-cloudformation)
+ [Create a key pair using a third-party tool and import the public key to Amazon EC2](#how-to-generate-your-own-key-and-import-it-to-aws)

## Create a key pair using Amazon EC2
<a name="having-ec2-create-your-key-pair"></a>

When you create a key pair using Amazon EC2, the public key is stored in Amazon EC2, and you store the private key.

You can create up to 5,000 key pairs per Region. To request an increase, create a support case. For more information, see [Creating a support case](https://docs.aws.amazon.com/awssupport/latest/user/case-management.html#creating-a-support-case) in the *Support User Guide*.

------
#### [ Console ]

**To create a key pair using Amazon EC2**

1. Open the Amazon EC2 console at [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/).

1. In the navigation pane, under **Network & Security**, choose **Key Pairs**.

1. Choose **Create key pair**.

1. For **Name**, enter a descriptive name for the key pair. Amazon EC2 associates the public key with the name that you specify as the key name. A key name can include up to 255 ASCII characters. It can’t include leading or trailing spaces.

1. Select a key pair type appropriate for your operating system:

   (Linux instances) For **Key pair type**, choose either **RSA** or **ED25519**.

   (Windows instances) For **Key pair type**, choose **RSA**. **ED25519** keys are not supported for Windows instances.

1. For **Private key file format**, choose the format in which to save the private key. To save the private key in a format that can be used with OpenSSH, choose **pem**. To save the private key in a format that can be used with PuTTY, choose **ppk**.

1. To add a tag to the public key, choose **Add tag**, and enter the key and value for the tag. Repeat for each tag. 

1. Choose **Create key pair**.

1. The private key file is automatically downloaded by your browser. The base file name is the name that you specified as the name of your key pair, and the file name extension is determined by the file format that you chose. Save the private key file in a safe place.
**Important**  
This is the only chance for you to save the private key file.

1. If you plan to use an SSH client on a macOS or Linux computer to connect to your Linux instance, use the following command to set the permissions of your private key file so that only you can read it.

   ```
   chmod 400 key-pair-name.pem
   ```

   If you do not set these permissions, then you cannot connect to your instance using this key pair. For more information, see [Error: Unprotected private key file](TroubleshootingInstancesConnecting.md#troubleshoot-unprotected-key).

------
#### [ AWS CLI ]

**To create a key pair using Amazon EC2**

1. Use the [https://docs.aws.amazon.com/cli/latest/reference/ec2/create-key-pair.html](https://docs.aws.amazon.com/cli/latest/reference/ec2/create-key-pair.html) command as follows to generate the key pair and to save the private key to a `.pem` file. The `--query` option prints the private key material to the output. The `--output` option saves the private key material in the specified file. The extension should be either `.pem` or `.ppk`, depending on the key format. The private key name can be different from the public key name, but for ease of use, use the same name.

   ```
   aws ec2 create-key-pair \
       --key-name my-key-pair \
       --key-type rsa \
       --key-format pem \
       --query "KeyMaterial" \
       --output text > my-key-pair.pem
   ```

1. If you plan to use an SSH client on a macOS or Linux computer to connect to your Linux instance, use the following command to set the permissions of your private key file so that only you can read it.

   ```
   chmod 400 key-pair-name.pem
   ```

   If you do not set these permissions, then you cannot connect to your instance using this key pair. For more information, see [Error: Unprotected private key file](TroubleshootingInstancesConnecting.md#troubleshoot-unprotected-key).

------
#### [ PowerShell ]

**To create a key pair using Amazon EC2**  
Use the [https://docs.aws.amazon.com/powershell/latest/reference/items/New-EC2KeyPair.html](https://docs.aws.amazon.com/powershell/latest/reference/items/New-EC2KeyPair.html) cmdlet as follows to generate the key and save it to a `.pem` or `.ppk` file. The **Out-File** cmdlet saves the private key material in a file with the specified extension. The extension should be either `.pem` or `.ppk`, depending on the key format. The private key name can be different from the public key name, but for ease of use, use the same name.

```
(New-EC2KeyPair `
    -KeyName "my-key-pair" `
    -KeyType "rsa" `
    -KeyFormat "pem").KeyMaterial | Out-File -Encoding ascii -FilePath C:\path\my-key-pair.pem
```

------

## Create a key pair using AWS CloudFormation
<a name="create-key-pair-cloudformation"></a>

When you create a new key pair using CloudFormation, the private key is saved to AWS Systems Manager Parameter Store. The parameter name has the following format:

```
/ec2/keypair/key_pair_id
```

For more information, see [AWS Systems Manager Parameter Store](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html) in the *AWS Systems Manager User Guide*.

**To create a key pair using CloudFormation**

1. Specify the [AWS::EC2::KeyPair](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-keypair.html) resource in your template.

   ```
   Resources:
     NewKeyPair:
       Type: 'AWS::EC2::KeyPair'
       Properties: 
         KeyName: new-key-pair
   ```

1. Use the [https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-key-pairs.html](https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-key-pairs.html) command as follows to get the ID of the key pair.

   ```
   aws ec2 describe-key-pairs --filters Name=key-name,Values=new-key-pair --query KeyPairs[*].KeyPairId --output text
   ```

   The following is example output.

   ```
   key-05abb699beEXAMPLE
   ```

1. Use the [https://docs.aws.amazon.com/cli/latest/reference/ssm/get-parameter.html](https://docs.aws.amazon.com/cli/latest/reference/ssm/get-parameter.html) command as follows to get the parameter for your key and save the key material in a `.pem` file.

   ```
   aws ssm get-parameter --name /ec2/keypair/key-05abb699beEXAMPLE --with-decryption --query Parameter.Value --output text > new-key-pair.pem
   ```

**Required IAM permissions**

To enable CloudFormation to manage Parameter Store parameters on your behalf, the IAM role assumed by CloudFormation or your user must have the following permissions:
+ `ssm:PutParameter` – Grants permission to create a parameter for the private key material.
+ `ssm:DeleteParameter` – Grants permission to delete the parameter that stored the private key material. This permission is required whether the key pair was imported or created by CloudFormation.

When CloudFormation deletes a key pair that was created or imported by a stack, it performs a permissions check to determine whether you have permission to delete parameters, even though CloudFormation creates a parameter only when it creates a key pair, not when it imports a key pair. CloudFormation tests for the required permission using a fabricated parameter name that does not match any parameter in your account. Therefore, you might see a fabricated parameter name in the `AccessDeniedException` error message.

## Create a key pair using a third-party tool and import the public key to Amazon EC2
<a name="how-to-generate-your-own-key-and-import-it-to-aws"></a>

Instead of using Amazon EC2 to create a key pair, you can create an RSA or ED25519 key pair by using a third-party tool and then import the public key to Amazon EC2.

**Requirements for key pairs**
+ Supported types:
  + (Linux and Windows) RSA
  + (Linux only) ED25519
**Note**  
ED25519 keys are not supported for Windows instances.
  + Amazon EC2 does not accept DSA keys.
+ Supported formats:
  + OpenSSH public key format (for Linux, the format in `~/.ssh/authorized_keys`)
  + (Linux only) If you connect using SSH while using the EC2 Instance Connect API, the SSH2 format is also supported.
  + SSH private key file format must be PEM or PPK
  + (RSA only) Base64 encoded DER format
  + (RSA only) SSH public key file format as specified in [RFC 4716](https://www.ietf.org/rfc/rfc4716.txt)
+ Supported lengths:
  + 1024, 2048, and 4096.
  + (Linux only) If you connect using SSH while using the EC2 Instance Connect API, the supported lengths are 2048 and 4096.

**To create a key pair using a third-party tool**

1. Generate a key pair with a third-party tool of your choice. For example, you can use **ssh-keygen** (a tool provided with the standard OpenSSH installation). Alternatively, Java, Ruby, Python, and many other programming languages provide standard libraries that you can use to create a key pair.
**Important**  
The private key must be in the PEM or PPK format. For example, use `ssh-keygen -m PEM` to generate the OpenSSH key in the PEM format.

1. Save the public key to a local file. For example, `~/.ssh/my-key-pair.pub` (Linux, macOS) or `C:\keys\my-key-pair.pub` (Windows). The file name extension for this file is not important.

1. Save the private key to a local file that has the `.pem` or `.ppk` extension. For example, `~/.ssh/my-key-pair.pem` or `~/.ssh/my-key-pair.ppk` (Linux, macOS) or `C:\keys\my-key-pair.pem` or `C:\keys\my-key-pair.ppk` (Windows). The file extension is important because, depending on the tool you use to connect to your instance, you'll need a specific file format. OpenSSH requires a `.pem` file, while PuTTY requires a `.ppk` file.
**Important**  
Save the private key file in a safe place. You'll need to provide the name of your public key when you launch an instance, and the corresponding private key each time you connect to the instance.

After you have created the key pair, use one of the following methods to import your public key to Amazon EC2.

------
#### [ Console ]

**To import the public key to Amazon EC2**

1. Open the Amazon EC2 console at [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/).

1. In the navigation pane, choose **Key Pairs**.

1. Choose **Import key pair**.

1. For **Name**, enter a descriptive name for the public key. The name can include up to 255 ASCII characters. It can’t include leading or trailing spaces.
**Note**  
When you connect to your instance from the EC2 console, the console suggests this name for the name of your private key file.

1. Either choose **Browse** to navigate to and select your public key, or paste the contents of your public key into the **Public key contents** field.

1. Choose **Import key pair**.

1. Verify that the public key that you imported appears in the list of key pairs.

------
#### [ AWS CLI ]

**To import the public key to Amazon EC2**  
Use the [https://docs.aws.amazon.com/cli/latest/reference/ec2/import-key-pair.html](https://docs.aws.amazon.com/cli/latest/reference/ec2/import-key-pair.html) command.

```
aws ec2 import-key-pair \
    --key-name my-key-pair \
    --public-key-material fileb://path/my-key-pair.pub
```

**To verify that the key pair was imported successfully**  
Use the [https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-key-pairs.html](https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-key-pairs.html) command.

```
aws ec2 describe-key-pairs --key-names my-key-pair
```

------
#### [ PowerShell ]

**To import the public key to Amazon EC2**  
Use the [https://docs.aws.amazon.com/powershell/latest/reference/items/Import-EC2KeyPair.html](https://docs.aws.amazon.com/powershell/latest/reference/items/Import-EC2KeyPair.html) cmdlet.

```
$publickey=[Io.File]::ReadAllText("C:\Users\TestUser\.ssh\id_rsa.pub")
Import-EC2KeyPair `
    -KeyName my-key-pair `
    -PublicKey $publickey
```

**To verify that the key pair was imported successfully**  
Use the [https://docs.aws.amazon.com/powershell/latest/reference/items/Get-EC2KeyPair.html](https://docs.aws.amazon.com/powershell/latest/reference/items/Get-EC2KeyPair.html) cmdlet.

```
Get-EC2KeyPair -KeyName my-key-pair
```

------

# Describe your key pairs
<a name="describe-keys"></a>

You can describe the key pairs that you stored in Amazon EC2. You can also retrieve the public key material and identify the public key that was specified at launch.

**Topics**
+ [Describe your key pairs](#describe-public-key)
+ [Retrieve the public key material](#retrieving-the-public-key)
+ [Identify the public key specified at launch](#identify-key-pair-specified-at-launch)

## Describe your key pairs
<a name="describe-public-key"></a>

You can view the following information about your public keys that are stored in Amazon EC2: public key name, ID, key type, fingerprint, public key material, the date and time (in the UTC time zone) the key was created by Amazon EC2 (if the key was created by a third-party tool, then it's the date and time the key was imported to Amazon EC2), and any tags that are associated with the public key.

------
#### [ Console ]

**To view information about your key pairs**

1. Open the Amazon EC2 console at [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/).

1. In the left navigator, choose **Key Pairs**.

1. You can view the information about each public key in the **Key pairs** table.  
![\[Key pairs table.\]](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/images/key-pairs-describe-console.png)

1. To view a public key's tags, select the checkbox next to the key, and then choose **Actions**, **Manage tags**.

------
#### [ AWS CLI ]

**To view information about a key pair**  
Use the [https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-key-pairs.html](https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-key-pairs.html) command.

```
aws ec2 describe-key-pairs --key-names key-pair-name
```

------
#### [ PowerShell ]

**To view information about a key pair**  
Use the [https://docs.aws.amazon.com/powershell/latest/reference/items/Get-EC2KeyPair.html](https://docs.aws.amazon.com/powershell/latest/reference/items/Get-EC2KeyPair.html) cmdlet.

```
Get-EC2KeyPair -KeyName key-pair-name
```

------

## Retrieve the public key material
<a name="retrieving-the-public-key"></a>

You can get the public key material for your key pairs. The following is an example public key. Note that there are line breaks added for readability.

```
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQClKsfkNkuSevGj3eYhCe53pcjqP3maAhDFcvBS7O6V
hz2ItxCih+PnDSUaw+WNQn/mZphTk/a/gU8jEzoOWbkM4yxyb/wB96xbiFveSFJuOp/d6RJhJOI0iBXr
lsLnBItntckiJ7FbtxJMXLvvwJryDUilBMTjYtwB+QhYXUMOzce5Pjz5/i8SeJtjnV3iAoG/cQk+0FzZ
qaeJAAHco+CY/5WrUBkrHmFJr6HcXkvJdWPkYQS3xqC0+FmUZofz221CBt5IMucxXPkX4rWi+z7wB3Rb
BQoQzd8v7yeb7OzlPnWOyN0qFU0XA246RA8QFYiCNYwI3f05p6KLxEXAMPLE
```

------
#### [ Private key ]

**To retrieve the public key material using ssh-keygen (Linux)**  
On your local Linux or macOS computer, use the **ssh-keygen** command. Specify the path where you downloaded your private key (the `.pem` file).

```
ssh-keygen -y -f /path_to_key_pair/my-key-pair.pem
```

If this **ssh-keygen** command fails, run the following **chmod** command to ensure that the private key file has the required permissions.

```
chmod 400 key-pair-name.pem
```

**To retrieve the public key material using PuTTYgen (Windows)**  
On your local Windows computer, start PuTTYgen. Choose **Load**. Select the `.ppk` or `.pem` private key file. PuTTYgen displays the public key under **Public key for pasting into OpenSSH authorized\$1keys file**. You can also view the public key by choosing **Save public key**, specifying a name for the file, saving the file, and then opening the file.

------
#### [ AWS CLI ]

**To retrieve the public key material**  
Use the following [describe-key-pairs](https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-key-pairs.html) command and specify the `--include-public-key` option.

```
aws ec2 describe-key-pairs \
    --key-names key-pair-name \
    --include-public-key \
    --query "KeyPairs[].PublicKey"
```

------
#### [ PowerShell ]

**To retrieve the public key material**  
Use the [Get-EC2KeyPair](https://docs.aws.amazon.com/powershell/latest/reference/items/Get-EC2KeyPair.html) cmdlet.

```
(Get-EC2KeyPair -KeyName key-pair-name -IncludePublicKey $true).PublicKey
```

------
#### [ IMDSv2 ]

**Linux**  
Run the following commands from your Linux instance.

```
TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` \
&& curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/public-keys/0/openssh-key
```

**Windows**  
Run the following cmdlets from your Windows instance.

```
[string]$token = Invoke-RestMethod -Headers @{"X-aws-ec2-metadata-token-ttl-seconds" = "21600"} -Method PUT -Uri http://169.254.169.254/latest/api/token
```

```
Invoke-RestMethod -Headers @{"X-aws-ec2-metadata-token" = $token} -Method GET -Uri http://169.254.169.254/latest/meta-data/public-keys/0/openssh-key
```

------
#### [ IMDSv1 ]

**Linux**  
Run the following command from your Linux instance.

```
curl http://169.254.169.254/latest/meta-data/public-keys/0/openssh-key
```

**Windows**  
Run the following cmdlet from your Windows instance.

```
Invoke-RestMethod -uri  http://169.254.169.254/latest/meta-data/public-keys/0/openssh-key
```

------

## Identify the public key specified at launch
<a name="identify-key-pair-specified-at-launch"></a>

If you specify a public key when you launch an instance, the public key name is recorded by the instance. The public key name reported for an instance does not change, even if you change the public key on the instance or add public keys.

------
#### [ Console ]

**To identify the public key specified at instance launch**

1. Open the Amazon EC2 console at [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/).

1. In the navigation pane, choose **Instances**.

1. Select the instance.

1. On the **Details** tab, under **Instance details**, find **Key pair assigned at launch**.

------
#### [ AWS CLI ]

**To identify the public key specified at instance launch**  
Use the following [describe-instances](https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-instances.html) command.

```
aws ec2 describe-instances \
    --instance-id i-1234567890abcdef0 \
    --query "Reservations[].Instances[].KeyName" \
    --output text
```

The following is example output.

```
key-pair-name
```

------
#### [ PowerShell ]

**To identify the public key specified at instance launch**  
Use the [Get-EC2Instance](https://docs.aws.amazon.com/powershell/latest/reference/items/Get-EC2Instance.html) cmdlet.

```
(Get-EC2Instance -InstanceId i-1234567890abcdef0).Instances | Select KeyName
```

The following is example output.

```
KeyName
-------
key-pair-name
```

------

# Delete your key pair
<a name="delete-key-pair"></a>

You can delete a key pair, which removes the public key that is stored in Amazon EC2. Deleting a key pair does not delete the matching private key.

When you delete a public key using the following methods, you're only deleting the public key that you stored in Amazon EC2 when you [created](create-key-pairs.md#having-ec2-create-your-key-pair) or [imported](create-key-pairs.md#how-to-generate-your-own-key-and-import-it-to-aws) the key pair. Deleting a public key doesn't remove the public key from any instances to which you've added it, either when you launched the instance or later. It also doesn't delete the private key on your local computer. You can continue to connect to instances that you launched using a public key that you've deleted from Amazon EC2 as long as you still have the private key (`.pem`) file.

**Important**  
If you're using an Auto Scaling group (for example, in an Elastic Beanstalk environment), ensure that the public key you're deleting is not specified in an associated launch template or launch configuration. If Amazon EC2 Auto Scaling detects an unhealthy instance, it launches a replacement instance. However, the instance launch fails if the public key cannot be found. For more information, see [Launch templates](https://docs.aws.amazon.com/autoscaling/ec2/userguide/launch-templates.html) in the *Amazon EC2 Auto Scaling User Guide*.

------
#### [ Console ]

**To delete your public key on Amazon EC2**

1. Open the Amazon EC2 console at [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/).

1. In the navigation pane, choose **Key Pairs**.

1. Select the key pair to delete and choose **Actions**, **Delete**.

1. In the confirmation field, enter `Delete` and then choose **Delete**.

------
#### [ AWS CLI ]

**To delete your public key on Amazon EC2**  
Use the [https://docs.aws.amazon.com/cli/latest/reference/ec2/delete-key-pair.html](https://docs.aws.amazon.com/cli/latest/reference/ec2/delete-key-pair.html) command.

```
aws ec2 delete-key-pair --key-name my-key-pair
```

------
#### [ PowerShell ]

**To delete your public key on Amazon EC2**  
Use the [https://docs.aws.amazon.com/powershell/latest/reference/items/Remove-EC2KeyPair.html](https://docs.aws.amazon.com/powershell/latest/reference/items/Remove-EC2KeyPair.html) cmdlet.

```
Remove-EC2KeyPair -KeyName my-key-pair
```

------

# Add or replace a public key on your Linux instance
<a name="replacing-key-pair"></a>


|  | 
| --- |
| If you lose a private key, you lose access to any instances that use the key pair. For more information about connecting to an instance using a different key pair than the one that you specified at launch, see [I've lost my private key](TroubleshootingInstancesConnecting.md#replacing-lost-key-pair). | 

When you launch an instance, you can [specify a key pair](ec2-instance-launch-parameters.md#liw-key-pair). If you specify a key pair at launch, when your instance boots for the first time, the public key material is placed on your Linux instance in an entry within `~/.ssh/authorized_keys`. When you first connect to your Linux instance using SSH, you specify the default user and the private key that corresponds to the public key that is stored on your Linux instance.

After you connect to your instance, you can change the key pair that is used to access the default system account of your instance by adding a new public key on the instance, or by replacing the public key (deleting the existing public key and adding a new one) on the instance. You can also remove all public keys from an instance.

You might add or replace a key pair for the following reasons:
+ If a user in your organization requires access to the system user using a separate key pair, you can add the public key to your instance.
+ If someone has a copy of the private key (`.pem` file) and you want to prevent them from connecting to your instance (for example, if they've left your organization), you can delete the public key on the instance and replace it with a new one.
+ If you create a Linux AMI from an instance, the public key material is copied from the instance to the AMI. If you launch an instance from the AMI, the new instance includes the public key from the original instance. To prevent someone who has the private key from connecting to the new instance, you can remove the public key from the original instance *before* creating the AMI.

Use the following procedures to modify the key pair for the default user, such as `ec2-user`. For information about adding users to your instance, see the documentation for the operating system on your instance.

**To add or replace a key pair**

1. Create a new key pair using the [Amazon EC2 console](create-key-pairs.md#having-ec2-create-your-key-pair) or a [third-party tool](create-key-pairs.md#how-to-generate-your-own-key-and-import-it-to-aws).

1. Retrieve the public key from your new key pair. For more information, see [Retrieve the public key material](describe-keys.md#retrieving-the-public-key).

1. [Connect to your instance](connect-to-linux-instance.md).

1. On the instance, using the text editor of your choice, open the `.ssh/authorized_keys` file. Paste the public key information from your new key pair underneath the existing public key information and then save the file.

1. Disconnect from your instance. Test that you can connect to your instance using the private key file from the new key pair.

1. If you're using Auto Scaling, EC2 fleet, or a launch template to launch your instances, check whether the key pair that you're replacing is specified in your launch template or launch configuration. Otherwise, instance launches will fail.

1. (Optional) If you're replacing an existing key pair, connect to your instance and delete the public key information for the original key pair from the `.ssh/authorized_keys` file.

**To remove a public key from an instance**

1. [Connect to your instance](connect-to-linux-instance.md).

1. Using a text editor of your choice, open the `.ssh/authorized_keys` file on the instance. Delete the public key information, and then save the file.

**Warning**  
If you remove all the public keys from an instance and disconnect from the instance, you can't connect to the instance again unless you've configured an alternate way to log in.

# Verify the fingerprint of your key pair
<a name="verify-keys"></a>

To verify the fingerprint of your key pair, compare the fingerprint displayed on the **Key pairs** page in the Amazon EC2 console, or returned by the [describe-key-pairs](https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-key-pairs.html) command, with the fingerprint that you generate using the private key on your local computer. These fingerprints should match.

When Amazon EC2 calculates a fingerprint, Amazon EC2 might append padding to the fingerprint with `=` characters. Other tools, such as **ssh-keygen**, might omit this padding.

If you're trying to verify the fingerprint of your Linux EC2 instance, not the fingerprint of your key pair, see [Get the instance fingerprint](connection-prereqs-general.md#connection-prereqs-fingerprint).

## How the fingerprints are calculated
<a name="how-ec2-key-fingerprints-are-calculated"></a>

Amazon EC2 uses different hash functions to calculate the fingerprints for RSA and ED25519 key pairs. Furthermore, for RSA key pairs, Amazon EC2 calculates the fingerprints differently using different hash functions depending on whether the key pair was created by Amazon EC2 or imported to Amazon EC2.

The following table lists the hash functions that are used to calculate the fingerprints for RSA and ED25519 key pairs that are created by Amazon EC2 and imported to Amazon EC2.


**(Linux instances) Hash functions used to calculate fingerprints**  

| Key pair source | RSA key pairs (Windows and Linux) | ED25519 key pairs (Linux) | 
| --- | --- | --- | 
| Created by Amazon EC2 | SHA-1 | SHA-256 | 
| Imported to Amazon EC2 | MD5¹ | SHA-256 | 

¹ If you import a public RSA key to Amazon EC2, the fingerprint is calculated using an MD5 hash function. This is true regardless of how you created the key pair, for example, by using a third-party tool or by generating a new public key from an existing private key created using Amazon EC2.

## When using the same key pair in different Regions
<a name="when-using-same-key-pair-in-different-regions"></a>

If you plan to use the same key pair to connect to instances in different AWS Regions, you must import the public key to all of the Regions in which you'll use it. If you use Amazon EC2 to create the key pair, you can [Retrieve the public key material](describe-keys.md#retrieving-the-public-key) so that you can import the public key to the other Regions.

**Note**  
If you create an RSA key pair using Amazon EC2, and then you generate a public key from the Amazon EC2 private key, the imported public keys will have a different fingerprint than the original public key. This is because the fingerprint of the original RSA key created using Amazon EC2 is calculated using a SHA-1 hash function, while the fingerprint of the imported RSA keys is calculated using an MD5 hash function.
For ED25519 key pairs, the fingerprints will be same regardless of whether they’re created by Amazon EC2 or imported to Amazon EC2, because the same SHA-256 hash function is used to calculate the fingerprint.

## Generate a fingerprint from the private key
<a name="generate-fingerprint-from-private-key"></a>

Use one of the following commands to generate a fingerprint from the private key on your local machine.

If you're using a Windows local machine, you can run the following commands using the Windows Subsystem for Linux (WSL). Install the WSL and a Linux distribution using the instructions in the [How to install Linux on Windows with WSL](https://learn.microsoft.com/en-us/windows/wsl/install). The example in the instructions installs the Ubuntu distribution of Linux, but you can install any distribution. You are prompted to restart your computer for the changes to take effect.
+ **If you created the key pair using Amazon EC2**

  Use the OpenSSL tools to generate a fingerprint as shown in the following examples.

  For RSA key pairs:

  ```
  openssl pkcs8 -in path_to_private_key -inform PEM -outform DER -topk8 -nocrypt | openssl sha1 -c
  ```

  (Linux instances) For ED25519 key pairs:

  ```
  ssh-keygen -l -f path_to_private_key
  ```
+ **(RSA key pairs only) If you imported the public key to Amazon EC2**

  You can follow this procedure regardless of how you created the key pair, for example, by using a third-party tool or by generating a new public key from an existing private key created using Amazon EC2

  Use the OpenSSL tools to generate the fingerprint as shown in the following example.

  ```
  openssl rsa -in path_to_private_key -pubout -outform DER | openssl md5 -c
  ```
+ **If you created an OpenSSH key pair using OpenSSH 7.8 or later and imported the public key to Amazon EC2**

  Use **ssh-keygen** to generate the fingerprint as shown in the following examples.

  For RSA key pairs:

  ```
  ssh-keygen -ef path_to_private_key -m PEM | openssl rsa -RSAPublicKey_in -outform DER | openssl md5 -c
  ```

  (Linux instances) For ED25519 key pairs:

  ```
  ssh-keygen -l -f path_to_private_key
  ```

# Amazon EC2 security groups for your EC2 instances
<a name="ec2-security-groups"></a>

A *security group* acts as a virtual firewall for your EC2 instances to control incoming and outgoing traffic. Inbound rules control the incoming traffic to your instance, and outbound rules control the outgoing traffic from your instance. When you launch an instance, you can specify one or more security groups. If you don't specify a security group, Amazon EC2 uses the default security group for the VPC. After you launch an instance, you can change its security groups.

Security is a shared responsibility between AWS and you. For more information, see [Security in Amazon EC2](ec2-security.md). AWS provides security groups as one of the tools for securing your instances, and you need to configure them to meet your security needs. If you have requirements that aren't fully met by security groups, you can maintain your own firewall on any of your instances in addition to using security groups.

**Pricing**  
There is no additional charge for using security groups.

**Topics**
+ [Overview](#security-group-basics)
+ [Create a security group for your Amazon EC2 instance](creating-security-group.md)
+ [Change the security groups for your Amazon EC2 instance](changing-security-group.md)
+ [Delete an Amazon EC2 security group](deleting-security-group.md)
+ [Amazon EC2 security group connection tracking](security-group-connection-tracking.md)
+ [Security group rules for different use cases](security-group-rules-reference.md)

## Overview
<a name="security-group-basics"></a>

You can associate each instance with multiple security groups, and you can associate each security group with multiple instances. You add rules to each security group that allow traffic to or from its associated instances. You can modify the rules for a security group at any time. New and modified rules are automatically applied to all instances that are associated with the security group. When Amazon EC2 decides whether to allow traffic to reach an instance, it evaluates all rules from all security groups that are associated with the instance. For more information, see [Security group rules](https://docs.aws.amazon.com/vpc/latest/userguide/security-group-rules.html) in the *Amazon VPC User Guide*.

The following diagram shows a VPC with a subnet, an internet gateway, and a security group. The subnet contains EC2 instances. The security group is associated with the instances. The only traffic that reaches the instance is the traffic allowed by the security group rules. For example, if the security group contains a rule that allows SSH traffic from your network, then you can connect to your instance from your computer using SSH. If the security group contains a rule that allows all traffic from the resources associated with it, then each instance can receive any traffic sent from the other instances.

![\[A VPC with a security group. The EC2 instances in the subnet are associated with the security group.\]](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/images/ec2-security-groups.png)


Security groups are stateful—if you send a request from your instance, the response traffic for that request is allowed to flow in regardless of inbound security group rules. Also, responses to allowed inbound traffic are allowed to flow out, regardless of outbound rules. For more information, see [Connection tracking](security-group-connection-tracking.md).

# Create a security group for your Amazon EC2 instance
<a name="creating-security-group"></a>

Security groups act as a firewall for associated instances, controlling both inbound and outbound traffic at the instance level. You can add rules to a security group that enable you to connect to your instance using SSH (Linux instances) or RDP (Windows instances). You can also add rules that allow client traffic, for example, HTTP and HTTPS traffic destined to a web server.

You can associate a security group with an instance when you launch the instance. When you add or remove rules from associated security groups, those changes are automatically applied to all instances to which you've associated the security group.

After you launch an instance, you can associate additional security groups. For more information, see [Change the security groups for your Amazon EC2 instance](changing-security-group.md).

You can add inbound and outbound security group rules when you create a security group or you can add them later on. For more information, see [Configure security group rules](changing-security-group.md#add-remove-security-group-rules). For examples of rules that you can add to a security group, see [Security group rules for different use cases](security-group-rules-reference.md).

**Considerations**
+ New security groups start with only an outbound rule that allows all traffic to leave the resource. You must add rules to enable any inbound traffic or to restrict the outbound traffic.
+ When configuring a source for a rule that allows SSH or RDP access to your instances, do not allow access from anywhere, because it would allow this access to your instance from all IP addresses on the internet. This is acceptable for a short time in a test environment, but it is unsafe for production environments.
+ If there is more than one rule for a specific port, Amazon EC2 applies the most permissive rule. For example, if you have a rule that allows access to TCP port 22 (SSH) from IP address 203.0.113.1, and another rule that allows access to TCP port 22 from anywhere, then everyone has access to TCP port 22.
+ You can associate multiple security groups with an instance. Therefore, an instance can have hundreds of rules that apply. This might cause problems when you access the instance. We recommend that you condense your rules as much as possible.
+ When you specify a security group as the source or destination for a rule, the rule affects all instances that are associated with the security group. Incoming traffic is allowed based on the private IP addresses of the instances that are associated with the source security group (and not the public IP or Elastic IP addresses). For more information about IP addresses, see [Amazon EC2 instance IP addressing](using-instance-addressing.md).
+ Amazon EC2 blocks traffic on port 25 by default. For more information, see [Restriction on email sent using port 25](ec2-resource-limits.md#port-25-throttle).

------
#### [ Console ]

**To create a security group**

1. Open the Amazon EC2 console at [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/).

1. In the navigation pane, choose **Security Groups**.

1. Choose **Create security group**.

1. Enter a descriptive name and brief description for the security group. You can't change the name and description of a security group after it is created.

1. For **VPC**, choose the VPC in which you'll run your Amazon EC2 instances.

1. (Optional) To add inbound rules, choose **Inbound rules**. For each rule, choose **Add rule** and specify the protocol, port, and source. For example, to allow SSH traffic, choose **SSH** for **Type** and specify the public IPv4 address of your computer or network for **Source**.

1. (Optional) To add outbound rules, choose **Outbound rules**. For each rule, choose **Add rule** and specify the protocol, port, and destination. Otherwise, you can keep the default rule, which allows all outbound traffic.

1. (Optional) To add a tag, choose **Add new tag** and enter the tag key and value.

1. Choose **Create security group**.

------
#### [ AWS CLI ]

**To create a security group**  
Use the following [create-security-group](https://docs.aws.amazon.com/cli/latest/reference/ec2/create-security-group.html) command.

```
aws ec2 create-security-group \
    --group-name my-security-group \
    --description "my security group" \
    --vpc-id vpc-1234567890abcdef0
```

For examples that add rules, see [Configure security group rules](changing-security-group.md#add-remove-security-group-rules).

------
#### [ PowerShell ]

**To create a security group**  
Use the [New-EC2SecurityGroup](https://docs.aws.amazon.com/powershell/latest/reference/items/New-EC2SecurityGroup.html) cmdlet.

```
New-EC2SecurityGroup `
    -GroupName my-security-group `
    -Description "my security group" `
    -VpcId vpc-1234567890abcdef0
```

For examples that add rules, see [Configure security group rules](changing-security-group.md#add-remove-security-group-rules).

------

# Change the security groups for your Amazon EC2 instance
<a name="changing-security-group"></a>

You can specify security groups for your Amazon EC2 instances when you launch them. After you launch an instance, you can add or remove security groups. You can also add, remove, or edit security group rules for associated security groups at any time.

Security groups are associated with network interfaces. Adding or removing security groups changes the security groups associated with the primary network interface. You can also change the security groups associated with any secondary network interfaces. For more information, see [Modify network interface attributes](modify-network-interface-attributes.md).

**Topics**
+ [Add or remove security groups](#add-remove-instance-security-groups)
+ [Configure security group rules](#add-remove-security-group-rules)

## Add or remove security groups
<a name="add-remove-instance-security-groups"></a>

After you launch an instance, you can add or remove security groups from the list of associated security groups. When you associate multiple security groups with an instance, the rules from each security group are effectively aggregated to create one set of rules. Amazon EC2 uses this set of rules to determine whether to allow traffic.

**Requirements**
+ The instance must be in the `running` or `stopped` state.

------
#### [ Console ]

**To change the security groups for an instance**

1. Open the Amazon EC2 console at [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/).

1. In the navigation pane, choose **Instances**.

1. Select your instance, and then choose **Actions**, **Security**, **Change security groups**.

1. For **Associated security groups**, select a security group from the list and choose **Add security group**.

   To remove an already associated security group, choose **Remove** for that security group.

1. Choose **Save**.

------
#### [ AWS CLI ]

**To change the security groups for an instance**  
Use the following [modify-instance-attribute](https://docs.aws.amazon.com/cli/latest/reference/ec2/modify-instance-attribute.html) command.

```
aws ec2 modify-instance-attribute \
    --instance-id i-1234567890abcdef0 \
    --groups sg-1234567890abcdef0
```

------
#### [ PowerShell ]

**To change the security groups for an instance**  
Use the [Edit-EC2InstanceAttribute](https://docs.aws.amazon.com/powershell/latest/reference/items/Edit-EC2InstanceAttribute.html) cmdlet.

```
Edit-EC2InstanceAttribute `
    -InstanceId i-1234567890abcdef0 `
    -Group sg-1234567890abcdef0
```

------

## Configure security group rules
<a name="add-remove-security-group-rules"></a>

After you create a security group, you can add, update, and delete its security group rules. When you add, update, or delete a rule, the change is automatically applied to the resources that are associated with the security group.

For examples of rules that you can add to a security group, see [Security group rules for different use cases](security-group-rules-reference.md).

**Required permissions**  
Before you begin, ensure that you have the required permissions. For more information, see [Example: Work with security groups](iam-policies-ec2-console.md#ex-security-groups).

**Protocols and ports**
+ With the console, when you select a predefined type, **Protocol** and **Port range** are specified for you. To enter a port range, you must select one of the following custom types: **Custom TCP** or **Custom UDP**.
+ With the AWS CLI, you can add a single rule with a single port using the `--protocol` and `--port` options. To add multiple rules, or a rule with a port range, use the `--ip-permissions` option instead.

**Sources and destinations**
+ With the console, you can specify the following as sources for inbound rules or destinations for outbound rules:
  + **Custom** – An IPv4 CIDR block, an IPv6 CIDR block, a security group, or a prefix list.
  + **Anywhere-IPv4** – The 0.0.0.0/0 IPv4 CIDR block.
  + **Anywhere-IPv6** – The ::/0 IPv6 CIDR block.
  + **My IP** – The public IPv4 address of your local computer.
+ With the AWS CLI, you can specify an IPv4 CIDR block using the `--cidr` option or a security group using the `--source-group` option. To specify a prefix list or an IPv6 CIDR block, use the `--ip-permissions` option.

**Warning**  
If you add inbound rules for ports 22 (SSH) or 3389 (RDP), we strongly recommend that you authorize only the specific IP address or range of addresses that need access to your instances. If you choose **Anywhere-IPv4**, you allow traffic from all IPv4 addresses to access your instances using the specified protocol. If you choose **Anywhere-IPv6**, you allow traffic from all IPv6 addresses to access your instances using the specified protocol.

------
#### [ Console ]

**To configure security group rules**

1. Open the Amazon EC2 console at [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/).

1. In the navigation pane, choose **Security Groups**.

1. Select the security group.

1. To edit the inbound rules, choose **Edit inbound rules** from **Actions** or the **Inbound rules** tab.

   1. To add a rule, choose **Add rule** and enter the type, protocol, port, and source for the rule.

      If the type is TCP or UDP, you must enter the port range to allow. For custom ICMP, you must choose the ICMP type name from **Protocol**, and, if applicable, the code name from **Port range**. For any other type, the protocol and port range are configured for you.

   1. To update a rule, change its protocol, description, and source as needed. However, you can't change the source type. For example, if the source is an IPv4 CIDR block, you can't specify an IPv6 CIDR block, a prefix list, or a security group.

   1. To delete a rule, choose its **Delete** button.

1. To edit the outbound rules, choose **Edit outbound rules** from **Actions** or the **Outbound rules** tab.

   1. To add a rule, choose **Add rule** and enter the type, protocol, port, and destination for the rule. You can also enter an optional description.

      If the type is TCP or UDP, you must enter the port range to allow. For custom ICMP, you must choose the ICMP type name from **Protocol**, and, if applicable, the code name from **Port range**. For any other type, the protocol and port range are configured for you.

   1. To update a rule, change its protocol, description, and source as needed. However, you can't change the source type. For example, if the source is an IPv4 CIDR block, you can't specify an IPv6 CIDR block, a prefix list, or a security group.

   1. To delete a rule, choose its **Delete** button.

1. Choose **Save rules**.

------
#### [ AWS CLI ]

**To add security group rules**  
Use the [authorize-security-group-ingress](https://docs.aws.amazon.com/cli/latest/reference/ec2/authorize-security-group-ingress.html) command to add inbound rules. The following example allows inbound SSH traffic from the CIDR blocks in the specified prefix list.

```
aws ec2 authorize-security-group-ingress \
    --group-id sg-1234567890abcdef0 \
    --ip-permissions 'IpProtocol=tcp,FromPort=22,ToPort=22,PrefixListIds=[{PrefixListId=pl-f8a6439156EXAMPLE}]'
```

Use the [authorize-security-group-egress](https://docs.aws.amazon.com/cli/latest/reference/ec2/authorize-security-group-egress.html) command to add outbound rules. The following example allows outbound TCP traffic on port 80 to instances with the specified security group.

```
aws ec2 authorize-security-group-egress \
    --group-id sg-1234567890abcdef0 \
    --ip-permissions 'IpProtocol=tcp,FromPort=80,ToPort=80,UserIdGroupPairs=[{GroupId=sg-0aad1c26bb6EXAMPLE}]'
```

**To remove security group rules**  
Use the following [revoke-security-group-ingress](https://docs.aws.amazon.com/cli/latest/reference/ec2/revoke-security-group-ingress.html) command to remove an inbound rule.

```
aws ec2 revoke-security-group-egress \
    --group id sg-1234567890abcdef0 \
    --security-group-rule-ids sgr-09ed298024EXAMPLE
```

Use the following [revoke-security-group-egress](https://docs.aws.amazon.com/cli/latest/reference/ec2/revoke-security-group-egress.html) command to remove an outbound rule.

```
aws ec2 revoke-security-group-ingress \
    --group id sg-1234567890abcdef0 \
    --security-group-rule-ids sgr-0352250c1aEXAMPLE
```

**To modify security group rules**  
Use the [modify-security-group-rules](https://docs.aws.amazon.com/cli/latest/reference/ec2/modify-security-group-rules.html) command. The following example changes the IPv4 CIDR block of the specified security group rule.

```
aws ec2 modify-security-group-rules \
    --group id sg-1234567890abcdef0 \
    --security-group-rules 'SecurityGroupRuleId=sgr-09ed298024EXAMPLE,SecurityGroupRule={IpProtocol=tcp,FromPort=80,ToPort=80,CidrIpv4=0.0.0.0/0}'
```

------
#### [ PowerShell ]

**To add security group rules**  
Use the [Grant-EC2SecurityGroupIngress](https://docs.aws.amazon.com/powershell/latest/reference/items/Grant-EC2SecurityGroupIngress.html) cmdlet to add inbound rules. The following example allows inbound SSH traffic from the CIDR blocks in the specified prefix list.

```
$plid = New-Object -TypeName Amazon.EC2.Model.PrefixListId
$plid.Id = "pl-f8a6439156EXAMPLE"
Grant-EC2SecurityGroupIngress `
    -GroupId sg-1234567890abcdef0 `
    -IpPermission @{IpProtocol="tcp"; FromPort=22; ToPort=22; PrefixListIds=$plid}
```

Use the [Grant-EC2SecurityGroupEgress](https://docs.aws.amazon.com/powershell/latest/reference/items/Grant-EC2SecurityGroupEgress.html) cmdlet to add outbound rules. The following example allows outbound TCP traffic on port 80 to instances with the specified security group.

```
$uigp = New-Object -TypeName Amazon.EC2.Model.UserIdGroupPair
$uigp.GroupId = "sg-0aad1c26bb6EXAMPLE"
Grant-EC2SecurityGroupEgress `
    -GroupId sg-1234567890abcdef0 `
    -IpPermission @{IpProtocol="tcp"; FromPort=80; ToPort=80; UserIdGroupPairs=$uigp}
```

**To remove security group rules**  
Use the [Revoke-EC2SecurityGroupIngress](https://docs.aws.amazon.com/powershell/latest/reference/items/Revoke-EC2SecurityGroupIngress.html) cmdlet to remove inbound rules.

```
Revoke-EC2SecurityGroupIngress `
    -GroupId sg-1234567890abcdef0 `
    -SecurityGroupRuleId sgr-09ed298024EXAMPLE
```

Use the [Revoke-EC2SecurityGroupEgress](https://docs.aws.amazon.com/powershell/latest/reference/items/Revoke-EC2SecurityGroupEgress.html) cmdlet to remove outbound rules.

```
Revoke-EC2SecurityGroupEgress `
    -GroupId sg-1234567890abcdef0 `
    -SecurityGroupRuleId sgr-0352250c1aEXAMPLE
```

**To modify security group rules**  
Use the [Edit-EC2SecurityGroupRule](https://docs.aws.amazon.com/powershell/latest/reference/items/Edit-EC2SecurityGroupRule.html) cmdlet. The following example changes the IPv4 CIDR block of the specified security group rule.

```
$sgrr = New-Object -TypeName Amazon.EC2.Model.SecurityGroupRuleRequest
$sgrr.IpProtocol = "tcp"
$sgrr.FromPort = 80
$sgrr.ToPort = 80
$sgrr.CidrIpv4 = "0.0.0.0/0"
$sgr = New-Object -TypeName Amazon.EC2.Model.SecurityGroupRuleUpdate
$sgr.SecurityGroupRuleId = "sgr-09ed298024EXAMPLE"
$sgr.SecurityGroupRule = $sgrr
Edit-EC2SecurityGroupRule  `
    -GroupId sg-1234567890abcdef0 `
    -SecurityGroupRule $sgr
```

------

# Delete an Amazon EC2 security group
<a name="deleting-security-group"></a>

When you are finished with a security group that you created for use with your Amazon EC2 instances, you can delete it.

**Requirements**
+ The security group can't be associated with an instance or network interface.
+ The security group can't be referenced by a rule in another security group.

------
#### [ Console ]

**To delete a security group**

1. Open the Amazon EC2 console at [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/).

1. (Optional) To verify that your security group is not associated with an instance, do the following:

   1. In the navigation pane, choose **Security Groups**.

   1. Copy the ID of the security group to delete.

   1. In the navigation pane, choose **Instances**.

   1. In the search bar, add **Security group IDs equals** filter and paste the ID of the security group. If there are no results, then the security group is not associated with an instance. Otherwise, you must disassociate the security group before you can delete it.

1. In the navigation pane, choose **Security Groups**.

1. Select the security group and choose **Actions**, **Delete security groups**.

1. If you selected more than one security group, you are prompted for confirmation. If some of the security groups can't be deleted, we display the status of each security group, which indicates whether it will be deleted. To confirm deletion, enter **Delete**.

1. Choose **Delete**.

------
#### [ AWS CLI ]

**To delete a security group**  
Use the following [delete-security-group](https://docs.aws.amazon.com/cli/latest/reference/ec2/delete-security-group.html) command.

```
aws ec2 delete-security-group --group-id sg-1234567890abcdef0
```

------
#### [ PowerShell ]

**To delete a security group**  
Use the [Remove-EC2SecurityGroup](https://docs.aws.amazon.com/powershell/latest/reference/items/Remove-EC2SecurityGroup.html) cmdlet.

```
Remove-EC2SecurityGroup -GroupId sg-1234567890abcdef0
```

------

# Amazon EC2 security group connection tracking
<a name="security-group-connection-tracking"></a>

Your security groups use connection tracking to track information about traffic to and from the instance. Rules are applied based on the connection state of the traffic to determine if the traffic is allowed or denied. With this approach, security groups are stateful. This means that responses to inbound traffic are allowed to flow out of the instance regardless of outbound security group rules, and vice versa.

As an example, suppose that you initiate a command such as netcat or similar to your instances from your home computer, and your inbound security group rules allow ICMP traffic. Information about the connection (including the port information) is tracked. Response traffic from the instance for the command is not tracked as a new request, but rather as an established connection, and is allowed to flow out of the instance, even if your outbound security group rules restrict outbound ICMP traffic.

For protocols other than TCP, UDP, or ICMP, only the IP address and protocol number is tracked. If your instance sends traffic to another host, and the host sends the same type of traffic to your instance within 600 seconds, the security group for your instance accepts it regardless of inbound security group rules. The security group accepts it because it’s regarded as response traffic for the original traffic.

When you change a security group rule, its tracked connections are not immediately interrupted. The security group continues to allow packets until existing connections time out. To ensure that traffic is immediately interrupted, or that all traffic is subject to firewall rules regardless of the tracking state, you can use a network ACL for your subnet. Network ACLs are stateless and therefore do not automatically allow response traffic. Adding a network ACL that blocks traffic in either direction breaks existing connections. For more information, see [Network ACLs](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-network-acls.html) in the *Amazon VPC User Guide*.

**Note**  
Security groups have no effect on DNS traffic to or from the Route 53 Resolver, sometimes referred to as the 'VPC\$12 IP address' (see [What is Amazon Route 53 Resolver?](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resolver.html) in the *Amazon Route 53 Developer Guide*), or the ‘AmazonProvidedDNS’ (see [Work with DHCP option sets](https://docs.aws.amazon.com/vpc/latest/userguide/DHCPOptionSet.html) in the *Amazon Virtual Private Cloud User Guide*). If you wish to filter DNS requests through the Route 53 Resolver, you can enable Route 53 Resolver DNS Firewall (see [Route 53 Resolver DNS Firewall](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resolver-dns-firewall.html) in the *Amazon Route 53 Developer Guide*).

## Untracked connections
<a name="untracked-connections"></a>

Not all flows of traffic are tracked. If a security group rule permits TCP or UDP flows for all traffic (0.0.0.0/0 or ::/0) and there is a corresponding rule in the other direction that permits all response traffic (0.0.0.0/0 or ::/0) for any port (0-65535), then that flow of traffic is not tracked, unless it is part of an [automatically tracked connection](#automatic-tracking). The response traffic for an untracked flow is allowed based on the inbound or outbound rule that permits the response traffic, not based on tracking information.

An untracked flow of traffic is immediately interrupted if the rule that enables the flow is removed or modified. For example, if you have an open (0.0.0.0/0) outbound rule, and you remove a rule that allows all (0.0.0.0/0) inbound SSH (TCP port 22) traffic to the instance (or modify it such that the connection would no longer be permitted), your existing SSH connections to the instance are immediately dropped. The connection was not previously being tracked, so the change will break the connection. On the other hand, if you have a narrower inbound rule that initially allows an SSH connection (meaning that the connection was tracked), but change that rule to no longer allow new connections from the address of the current SSH client, the existing SSH connection is not interrupted because it is tracked.

## Automatically tracked connections
<a name="automatic-tracking"></a>

Connections made through the following are automatically tracked, even if the security group configuration does not otherwise require tracking:
+ Egress-only internet gateways
+ Global Accelerator accelerators
+ NAT gateways
+ Network Firewall firewall endpoints
+ Network Load Balancers
+ AWS PrivateLink (interface VPC endpoints)
+ AWS Lambda (Hyperplane elastic network interfaces)
+ DynamoDB gateway endpoints – Each connection to DynamoDB consumes 2 conntrack entries.

## Connection tracking allowances
<a name="connection-tracking-throttling"></a>

Amazon EC2 defines the maximum number of connections that can be tracked per instance. After the maximum is reached, any packets that are sent or received are dropped because a new connection cannot be established. When this happens, applications that send and receive packets cannot communicate properly. Use the `conntrack_allowance_available` network performance metric to determine the number of tracked connections still available for that instance type.

To determine whether packets were dropped because the network traffic for your instance exceeded the maximum number of connections that can be tracked, use the `conntrack_allowance_exceeded` network performance metric. For more information, see [Monitor network performance for ENA settings on your EC2 instance](monitoring-network-performance-ena.md).

With Elastic Load Balancing, if you exceed the maximum number of connections that can be tracked per instance, we recommend that you scale either the number of instances registered with the load balancer or the size of the instances registered with the load balancer.

## Connection tracking best practices
<a name="connection-tracking-performance"></a>

Asymmetric routing, where traffic comes into an instance through one network interface and leaves through a different network interface, can reduce the peak performance that an instance can achieve if flows are tracked.

To maintain peak performance and optimize connection management when connection tracking is enabled for your security groups, we recommend the following configuration:
+ Avoid asymmetric routing topologies, if possible.
+ Instead of using security groups for filtering, use network ACLs.
+ If you must use security groups with connection tracking, configure the shortest idle connection tracking timeout possible. For more details on idle connection tracking timeout, see the following section.
+ With the shorter default timeouts on Nitrov6 instances, applications with long-lived connections (such as database connection pools, persistent HTTP connections, or streaming workloads) should configure an appropriate `TcpEstablishedTimeout` value at instance launch.
+ For long-lived connections, configure TCP keep alives to be sent at intervals of less than 5 minutes to ensure connections stay open and maintain their tracked state. This helps prevent connections from being dropped due to idle timeout and reduces the overhead of connection re-establishment.

For more information about performance tuning on the Nitro system, see [Nitro system considerations for performance tuning](ena-nitro-perf.md).

## Idle connection tracking timeout
<a name="connection-tracking-timeouts"></a>

The security group tracks each connection established to ensure that return packets are delivered as expected. There is a maximum number of connections that can be tracked per instance. Connections that remain idle can lead to connection tracking exhaustion and cause connections not to be tracked and packets to be dropped. You can set the timeout for idle connection tracking on an Elastic network interface.

**Note**  
This feature is available only with [Nitro-based instances](instance-types.md#instance-hypervisor-type). You should test your applications on Nitrov6 generation instances with the reduced `350` second default connection tracking timeout before deploying to production.

There are three configurable timeouts:
+ **TCP established timeout**: Timeout (in seconds) for idle TCP connections in an established state.
  + Min: `60` seconds
  + Max: `432000` seconds
  + Default: `350` seconds for [Nitrov6](https://docs.aws.amazon.com/ec2/latest/instancetypes/ec2-nitro-instances.html) instance types, excluding P6e-GB200. And `432000` seconds for other instance types, including P6e-GB200.
  + Recommended: Less than `432000` seconds
+ **UDP timeout**: Timeout (in seconds) for idle UDP flows that have seen traffic only in a single direction or a single request-response transaction.
  + Min: `30` seconds
  + Max: `60` seconds
  + Default: `30` seconds
+ **UDP stream timeout**: Timeout (in seconds) for idle UDP flows classified as streams which have seen more than one request-response transaction.
  + Min: `60` seconds
  + Max: `180` seconds
  + Default: `180` seconds

You may want to modify the default timeouts for any of the following cases:
+  If you are [monitoring tracked connections using Amazon EC2 network performance metrics](monitoring-network-performance-ena.md), the *conntrack\$1allowance\$1exceeded* and *conntrack\$1allowance\$1available* metrics enable you to monitor dropped packets and tracked connection utilization to proactively manage EC2 instance capacity with scale up or out actions to help meet network connections demand before dropping packets. If you are observing *conntrack\$1allowance\$1exceeded* drops on your EC2 instances, you may benefit from setting a lower TCP established timeout to account for stale TCP/UDP sessions resulting from improper clients or network middle boxes.
+ Typically, load balancers or firewalls have TCP Established idle timeout in the range of 60 to 90 minutes. If you are running workloads that are expected to handle a very high number of connections (greater than 100k) from appliances like network firewalls, configuring a similar timeout on an EC2 network interface is advised.
+ If you are running a workload that utilizes an asymmetric routing topology, we recommend that you configure a TCP Established idle timeout of 60 seconds.
+ If you are running workloads with high numbers of connections like DNS, SIP, SNMP, Syslog, Radius and other services that primarily use UDP to serve requests, setting the ‘UDP-stream’ timeout to 60s provides higher scale/performance for existing capacity and to prevent gray failures.
+ For TCP/UDP connections through Network Load Balancers, all connections are tracked. Idle timeout value for TCP flows is 350secs and UDP flows is 120 secs, and varies from interface level timeout values. You may want to configure timeouts at the network interface level to allow for more flexibility for timeout than the defaults for the load balancer.

You have the option to configure the connection tracking timeouts when you do the following:
+ [Create a network interface](create-network-interface.md)
+ [Modify network interface attributes](modify-network-interface-attributes.md)
+ [Launch an EC2 instance](ec2-instance-launch-parameters.md#liw-network-settings)
+ [Create an EC2 instance launch template](ec2-instance-launch-parameters.md#liw-network-settings)

## Example
<a name="connection-tracking-example"></a>

In the following example, the security group has inbound rules that allow TCP and ICMP traffic, and outbound rules that allow all outbound traffic.


**Inbound**  

| Protocol type | Port number | Source | 
| --- | --- | --- | 
| TCP  | 22 (SSH) | 203.0.113.1/32 | 
| TCP  | 80 (HTTP) | 0.0.0.0/0 | 
| TCP  | 80 (HTTP) | ::/0 | 
| ICMP | All | 0.0.0.0/0 | 


**Outbound**  

| Protocol type | Port number | Destination | 
| --- | --- | --- | 
| All | All | 0.0.0.0/0 | 
| All | All | ::/0 | 

With a direct network connection to the instance or network interface, the tracking behavior is as follows:
+ Inbound and outbound TCP traffic on port 22 (SSH) is tracked, because the inbound rule allows traffic from 203.0.113.1/32 only, and not all IP addresses (0.0.0.0/0).
+ Inbound and outbound TCP traffic on port 80 (HTTP) is not tracked, because the inbound and outbound rules allow traffic from all IP addresses.
+ ICMP traffic is always tracked.

If you remove the outbound rule for IPv4 traffic, all inbound and outbound IPv4 traffic is tracked, including traffic on port 80 (HTTP). The same applies for IPv6 traffic if you remove the outbound rule for IPv6 traffic.

# Security group rules for different use cases
<a name="security-group-rules-reference"></a>

You can create a security group and add rules that reflect the role of the instance that's associated with the security group. For example, an instance that's configured as a web server needs security group rules that allow inbound HTTP and HTTPS access. Likewise, a database instance needs rules that allow access for the type of database, such as access over port 3306 for MySQL.

The following are examples of the kinds of rules that you can add to security groups for specific kinds of access.

**Topics**
+ [Web server rules](#sg-rules-web-server)
+ [Database server rules](#sg-rules-db-server)
+ [Rules to connect to instances from your computer](#sg-rules-local-access)
+ [Rules to connect to instances from an instance with the same security group](#sg-rules-other-instances)
+ [Rules for ping/ICMP](#sg-rules-ping)
+ [DNS server rules](#sg-rules-dns)
+ [Amazon EFS rules](#sg-rules-efs)
+ [Elastic Load Balancing rules](#sg-rules-elb)

For instructions, see [Create a security group](creating-security-group.md) and [Configure security group rules](changing-security-group.md#add-remove-security-group-rules).

## Web server rules
<a name="sg-rules-web-server"></a>

The following inbound rules allow HTTP and HTTPS access from any IP address. If your VPC is enabled for IPv6, you can add rules to control inbound HTTP and HTTPS traffic from IPv6 addresses.


| Protocol type | Protocol number | Port | Source IP | Notes | 
| --- | --- | --- | --- | --- | 
| TCP | 6 | 80 (HTTP) | 0.0.0.0/0 | Allows inbound HTTP access from any IPv4 address | 
| TCP | 6 | 443 (HTTPS) | 0.0.0.0/0 | Allows inbound HTTPS access from any IPv4 address | 
| TCP | 6 | 80 (HTTP) | ::/0 | Allows inbound HTTP access from any IPv6 address | 
| TCP | 6 | 443 (HTTPS) | ::/0 | Allows inbound HTTPS access from any IPv6 address | 

## Database server rules
<a name="sg-rules-db-server"></a>

The following inbound rules are examples of rules you might add for database access, depending on what type of database you're running on your instance. For more information about Amazon RDS instances, see the [Amazon RDS User Guide](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/).

For the source IP, specify one of the following:
+ A specific IP address or range of IP addresses (in CIDR block notation) in your local network
+ A security group ID for a group of instances that access the database


| Protocol type | Protocol number | Port | Notes | 
| --- | --- | --- | --- | 
| TCP | 6 | 1433 (MS SQL) | The default port to access a Microsoft SQL Server database, for example, on an Amazon RDS instance | 
| TCP | 6 | 3306 (MYSQL/Aurora) | The default port to access a MySQL or Aurora database, for example, on an Amazon RDS instance | 
| TCP | 6 | 5439 (Redshift) | The default port to access an Amazon Redshift cluster database. | 
| TCP | 6 | 5432 (PostgreSQL) | The default port to access a PostgreSQL database, for example, on an Amazon RDS instance | 
| TCP | 6 | 1521 (Oracle) | The default port to access an Oracle database, for example, on an Amazon RDS instance | 

You can optionally restrict outbound traffic from your database servers. For example, you might want to allow access to the internet for software updates, but restrict all other kinds of traffic. You must first remove the default outbound rule that allows all outbound traffic.


| Protocol type | Protocol number | Port | Destination IP | Notes | 
| --- | --- | --- | --- | --- | 
| TCP | 6 | 80 (HTTP) | 0.0.0.0/0 | Allows outbound HTTP access to any IPv4 address | 
| TCP | 6 | 443 (HTTPS) | 0.0.0.0/0 | Allows outbound HTTPS access to any IPv4 address | 
| TCP | 6 | 80 (HTTP) | ::/0 | (IPv6-enabled VPC only) Allows outbound HTTP access to any IPv6 address | 
| TCP | 6 | 443 (HTTPS) | ::/0 | (IPv6-enabled VPC only) Allows outbound HTTPS access to any IPv6 address | 

## Rules to connect to instances from your computer
<a name="sg-rules-local-access"></a>

To connect to your instance, your security group must have inbound rules that allow SSH access (for Linux instances) or RDP access (for Windows instances).


| Protocol type | Protocol number | Port | Source IP | 
| --- | --- | --- | --- | 
| TCP | 6 | 22 (SSH) | The public IPv4 address of your computer, or a range of IP addresses in your local network. If your VPC is enabled for IPv6 and your instance has an IPv6 address, you can enter an IPv6 address or range. | 
| TCP | 6 | 3389 (RDP) | The public IPv4 address of your computer, or a range of IP addresses in your local network. If your VPC is enabled for IPv6 and your instance has an IPv6 address, you can enter an IPv6 address or range. | 

## Rules to connect to instances from an instance with the same security group
<a name="sg-rules-other-instances"></a>

To allow instances that are associated with the same security group to communicate with each other, you must explicitly add rules for this. 

**Note**  
If you configure routes to forward the traffic between two instances in different subnets through a middlebox appliance, you must ensure that the security groups for both instances allow traffic to flow between the instances. The security group for each instance must reference the private IP address of the other instance, or the CIDR range of the subnet that contains the other instance, as the source. If you reference the security group of the other instance as the source, this does not allow traffic to flow between the instances.

The following table describes the inbound rule for a security group that enables associated instances to communicate with each other. The rule allows all types of traffic.


| Protocol type | Protocol number | Ports | Source IP | 
| --- | --- | --- | --- | 
| -1 (All) | -1 (All) | -1 (All) | The ID of the security group, or the CIDR range of the subnet that contains the other instance (see note). | 

## Rules for ping/ICMP
<a name="sg-rules-ping"></a>

The **ping** command is a type of ICMP traffic. To ping your instance, you must add one of the following inbound ICMP rules.


| Type | Protocol | Source | 
| --- | --- | --- | 
| Custom ICMP - IPv4 | Echo request | The public IPv4 address of your computer, a specific IPv4 address, or an IPv4 or IPv6 address from anywhere. | 
| All ICMP - IPv4 | IPv4 ICMP (1) | The public IPv4 address of your computer, a specific IPv4 address, or an IPv4 or IPv6 address from anywhere. | 

To use the **ping6** command to ping the IPv6 address for your instance, you must add the following inbound ICMPv6 rule.


| Type | Protocol | Source | 
| --- | --- | --- | 
| All ICMP - IPv6 | IPv6 ICMP (58) | The IPv6 address of your computer, a specific IPv4 address, or an IPv4 or IPv6 address from anywhere. | 

## DNS server rules
<a name="sg-rules-dns"></a>

If you've set up your EC2 instance as a DNS server, you must ensure that TCP and UDP traffic can reach your DNS server over port 53. 

For the source IP, specify one of the following:
+ An IP address or range of IP addresses (in CIDR block notation) in a network
+ The ID of a security group for the set of instances in your network that require access to the DNS server


| Protocol type | Protocol number | Port | 
| --- | --- | --- | 
| TCP | 6 | 53 | 
| UDP | 17 | 53 | 

## Amazon EFS rules
<a name="sg-rules-efs"></a>

If you're using an Amazon EFS file system with your Amazon EC2 instances, the security group that you associate with your Amazon EFS mount targets must allow traffic over the NFS protocol. 


| Protocol type | Protocol number | Ports | Source IP | Notes | 
| --- | --- | --- | --- | --- | 
| TCP | 6 | 2049 (NFS) | The ID of the security group | Allows inbound NFS access from resources (including the mount target) associated with this security group | 

To mount an Amazon EFS file system on your Amazon EC2 instance, you must connect to your instance. Therefore, the security group associated with your instance must have rules that allow inbound SSH from your local computer or local network.


| Protocol type | Protocol number | Ports | Source IP | Notes | 
| --- | --- | --- | --- | --- | 
| TCP | 6 | 22 (SSH) | The IP address range of your local computer, or the range of IP addresses (in CIDR block notation) for your network. | Allows inbound SSH access from your local computer. | 

## Elastic Load Balancing rules
<a name="sg-rules-elb"></a>

If you register your EC2 instances with a load balancer, the security group associated with your load balancer must allow communication with the instances. For more information, see the following in the Elastic Load Balancing documentation.
+ [Security groups for your Application Load Balancer](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-update-security-groups.html)
+ [Security groups for your Network Load Balancer](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-security-groups.html)
+ [Configure security groups for your Classic Load Balancer](https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-vpc-security-groups.html)

# NitroTPM for Amazon EC2 instances
<a name="nitrotpm"></a>

Nitro Trusted Platform Module (NitroTPM) is a virtual device that is provided by the [AWS Nitro System](https://aws.amazon.com//ec2/nitro/) and conforms to the [TPM 2.0 specification](https://trustedcomputinggroup.org/resource/trusted-platform-module-2-0-a-brief-introduction/). It securely stores artifacts (such as passwords, certificates, or encryption keys) that are used to authenticate the instance. NitroTPM can generate keys and use them for cryptographic functions (such as hashing, signing, encryption, and decryption).

NitroTPM provides *measured boot*, a process where the bootloader and operating system create cryptographic hashes of every boot binary and combine them with the previous values in NitroTPM internal Platform Configuration Registers (PCRs). With measured boot, you can obtain signed PCR values from NitroTPM and use them to prove to remote entities the integrity of the instance's boot software. This is known as remote *attestation*.

With NitroTPM, keys and secrets can be tagged with a specific PCR value so that they can never be accessed if the value of the PCR, and thus the instance integrity, changes. This special form of conditional access is referred to as *sealing and unsealing*. Operating system technologies, like [BitLocker](https://learn.microsoft.com/en-us/windows/security/operating-system-security/data-protection/bitlocker/), can use NitroTPM to seal a drive decryption key so that the drive can only be decrypted when the operating system has booted correctly and is in a known good state.

To use NitroTPM, you must select an [Amazon Machine Image](AMIs.md) (AMI) that has been configured for NitroTPM support, and then use the AMI to launch [Nitro-based instances](instance-types.md#instance-hypervisor-type). You can select one of Amazon's prebuilt AMIs or create one yourself.

**Pricing**  
There is no additional cost for using NitroTPM. You pay only for the underlying resources that you use.

**Topics**
+ [Requirements](enable-nitrotpm-prerequisites.md)
+ [Enable a Linux AMI for NitroTPM](enable-nitrotpm-support-on-ami.md)
+ [Verify that an AMI is enabled for NitroTPM](verify-nitrotpm-support-on-ami.md)
+ [Enable or stop using NitroTPM](nitrotpm-instance.md)
+ [Verify that an instance is enabled for NitroTPM](verify-nitrotpm-support-on-instance.md)
+ [Retrieve the public endorsement key](retrieve-ekpub.md)

# Requirements for using NitroTPM with Amazon EC2 instances
<a name="enable-nitrotpm-prerequisites"></a>

To launch an instance with NitroTPM enabled, you must meet the following requirements.

**Topics**
+ [AMIs](#nitrotpm-ami)
+ [Instance types](#nitrotpm-instancetypes)
+ [Considerations](#nitrotpm-considerations)

## AMIs
<a name="nitrotpm-ami"></a>

The AMI must have NitroTPM enabled.

**Linux AMIs**  
There are no preconfigured AMIs. You must configure your own AMI. For more information, see [Enable a Linux AMI for NitroTPM](enable-nitrotpm-support-on-ami.md).

**Windows AMIs**  
To find an AWS Windows AMI that's preconfigured for NitroTPM and UEFI Secure Boot with Microsoft keys, see [Find Windows Server AMIs configured with NitroTPM and UEFI Secure Boot](https://docs.aws.amazon.com/ec2/latest/windows-ami-reference/ami-windows-tpm.html#ami-windows-tpm-find) in the *AWS Windows AMIs Reference*.

**Note**  
**Operating system** — The AMI must include an operating system with a TPM 2.0 Command Response Buffer (CRB) driver. Most current operating systems include a TPM 2.0 CRB driver.  
**UEFI boot mode** — The AMI must be configured for UEFI boot mode. For more information, see [UEFI Secure Boot for Amazon EC2 instances](uefi-secure-boot.md).

## Instance types
<a name="nitrotpm-instancetypes"></a>

You must use one of the following virtualized instance types:
+ **General purpose**: M5, M5a, M5ad, M5d, M5dn, M5n, M5zn, M6a, M6g, M6gd, M6i, M6id, M6idn, M6in, M7a, M7g, M7gd, M7i, M7i-flex, M8a, M8azn, M8g, M8gb, M8gd, M8gn, M8i, M8id, M8i-flex, T3, T3a, T4g
+ **Compute optimized**: C5, C5a, C5ad, C5d, C5n, C6a, C6g, C6gd, C6gn, C6i, C6id, C6in, C7a, C7g, C7gd, C7gn, C7i, C7i-flex, C8a, C8g, C8gb, C8gd, C8gn, C8i, C8ib, C8id, C8in, C8i-flex
+ **Memory optimized**: R5, R5a, R5ad, R5b, R5d, R5dn, R5n, R6a, R6g, R6gd, R6i, R6id, R6idn, R6in, R7a, R7g, R7gd, R7i, R7iz, R8a, R8g, R8gb, R8gd, R8gn, R8i, R8id, R8i-flex, U7i-6tb, U7i-8tb, U7i-12tb, U7in-16tb, U7in-24tb, U7in-32tb, X2idn, X2iedn, X2iezn, X8g, X8aedz, X8i, z1d
+ **Storage optimized**: D3, D3en, I3en, I4i, I7i, I7ie, I8g, I8ge, Im4gn
+ **Accelerated computing**: F2, G4dn, G5, G6, G6e, G6f, Gr6, Gr6f, G7e, Inf1, Inf2, P5, P5e, P5en, P6-B200, P6-B300, Trn2, Trn2u
+ **High-performance computing**: Hpc6a, Hpc6id, Hpc8a

## Considerations
<a name="nitrotpm-considerations"></a>

The following considerations apply when using NitroTPM:
+ After you launch an instance using an AMI with NitroTPM enabled, if you want to change the instance type, the new instance type that you choose must also support NitroTPM.
+ BitLocker volumes that are encrypted with NitroTPM-based keys can only be used on the original instance.
+ The NitroTPM state is not displayed in the Amazon EC2 console.
+ The NitroTPM state is not included in [Amazon EBS snapshots](https://docs.aws.amazon.com/ebs/latest/userguide/ebs-snapshots.html).
+ The NitroTPM state is not included in [VM Import/Export](https://docs.aws.amazon.com/vm-import/latest/userguide/) images.
+ NitroTPM is not supported on AWS Outposts., Local Zones, or Wavelength Zones.

# Enable a Linux AMI for NitroTPM
<a name="enable-nitrotpm-support-on-ami"></a>

To enable NitroTPM for an instance, you must launch the instance using an AMI with NitroTPM enabled. You must configure your Linux AMI with NitroTPM support when you register it. You can't configure NitroTPM support later on.

For the list of Windows AMIs that are preconfigured for NitroTPM support, see [Requirements for using NitroTPM with Amazon EC2 instances](enable-nitrotpm-prerequisites.md).

You must create an AMI with NitroTPM configured by using the [RegisterImage](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_RegisterImage.html) API. You can't use the Amazon EC2 console or VM Import/Export.

**To enable a Linux AMI for NitroTPM**

1. Launch a temporary instance with your required Linux AMI. Note the ID of its root volume, which you can find in the console on the **Storage** tab for the instance.

1. After the instance reaches the `running` state, create a snapshot of the instance's root volume. For more information, see [Create a snapshot of an EBS volume](https://docs.aws.amazon.com/ebs/latest/userguide/ebs-create-snapshot.html).

1. Register the snapshot you created as an AMI. In the block device mapping, specify the snapshot that you created for the root volume.

   The following is an example [register-image](https://docs.aws.amazon.com/cli/latest/reference/ec2/register-image.html) command. For `--tpm-support`, specify `v2.0`. For `--boot-mode`, specify `uefi`. 

   ```
   aws ec2 register-image \
       --name my-image \
       --boot-mode uefi \
       --architecture x86_64 \
       --root-device-name /dev/xvda \
       --block-device-mappings DeviceName=/dev/xvda,Ebs={SnapshotId=snap-0abcdef1234567890} \
       --tpm-support v2.0
   ```

   The following is an example for the [Register-EC2Image](https://docs.aws.amazon.com/powershell/latest/reference/items/Register-EC2Image.html) cmdlet.

   ```
   $block = @{SnapshotId=snap-0abcdef1234567890}
   Register-EC2Image `
       -Name my-image `
       -Architecture "x86_64" `
       -RootDeviceName /dev/xvda `
       -BlockDeviceMapping @{DeviceName="/dev/xvda";Ebs=$block} `
       -BootMode Uefi `
       -TpmSupport V20
   ```

1. Terminate the temporary instance that you launched in step 1.

# Verify that an AMI is enabled for NitroTPM
<a name="verify-nitrotpm-support-on-ami"></a>

To enable NitroTPM for an instance, you must launch the instance using an AMI with NitroTPM enabled. You can describe an image to verify that it is enabled for NitroTPM. If you are the AMI owner, you can describe the `tpmSupport` image attribute.

The Amazon EC2 console does not display `TpmSupport`.

------
#### [ AWS CLI ]

**To verify that NitroTPM is enabled**  
Use the [describe-images](https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-images.html) command.

```
aws ec2 describe-images \
    --image-ids ami-0abcdef1234567890 \
    --query Images[*].TpmSupport
```

If NitroTPM is enabled for the AMI, the output is as follows. If TPM is not enabled, the output is empty.

```
[
    "v2.0"
]
```

Alternatively, if you are the AMI owner, you can use the [describe-image-attribute](https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-image-attribute.html) command with the `tpmSupport` attribute.

```
aws ec2 describe-image-attribute \
    --image-id ami-0abcdef1234567890 \
    --attribute tpmSupport
```

 The following is example output.

```
{
    "ImageId": "ami-0abcdef1234567890",
    "TpmSupport": {
        "Value": "v2.0"
    }
}
```

**To find AMIs with NitroTPM enabled**  
The following example lists the IDs of the AMIs that you own with NitroTPM enabled.

```
aws ec2 describe-images \
    --owners self \
    --filters Name=tpm-support,Values=v2.0 \
    --query Images[].ImageId
```

------
#### [ PowerShell ]

**To verify that NitroTPM is enabled**  
Use the [Get-EC2Image](https://docs.aws.amazon.com/powershell/latest/reference/items/Get-EC2Image.html) cmdlet.

```
Get-EC2Image `
    -ImageId ami-0abcdef1234567890 | Select TpmSupport
```

If NitroTPM is enabled for the AMI, the output is as follows. If TPM is not enabled, the output is empty.

```
TpmSupport
----------
v2.0
```

Alternatively, if you are the AMI owner, you can use the [Get-EC2ImageAttribute](https://docs.aws.amazon.com/powershell/latest/reference/items/Get-EC2ImageAttribute.html) cmdlet with the `tpmSupport` attribute.

```
Get-EC2ImageAttribute `
    -ImageId ami-0abcdef1234567890 `
    -Attribute tpmSupport
```

**To find AMIs with NitroTPM enabled**  
The following example lists the IDs of the AMIs that you own with NitroTPM enabled.

```
Get-EC2Image `
    -Owner self `
    -Filter @{Name="tpm-support; Values="v2.0"} | Select ImageId
```

------

# Enable or stop using NitroTPM on an Amazon EC2 instance
<a name="nitrotpm-instance"></a>

You can enable an Amazon EC2 instance for NitroTPM only at launch. Once an instance is enabled for NitroTPM, you can't disable it. If you no longer need to use NitroTPM, you must configure the operating system to stop using it.

**Topics**
+ [Launch an instance with NitroTPM enabled](#launch-instance-with-nitrotpm)
+ [Stop using NitroTPM on an instance](#disable-nitrotpm-support-on-instance)

## Launch an instance with NitroTPM enabled
<a name="launch-instance-with-nitrotpm"></a>

When you launch an instance with the [ prerequisites](enable-nitrotpm-prerequisites.md), NitroTPM is automatically enabled on the instance. You can enable NitroTPM on an instance only at launch. For information about launching an instance, see [Launch an Amazon EC2 instance](LaunchingAndUsingInstances.md).

## Stop using NitroTPM on an instance
<a name="disable-nitrotpm-support-on-instance"></a>

After launching an instance with NitroTPM enabled, you can't disable NitroTPM for the instance. However, you can configure the operating system to stop using NitroTPM by disabling the TPM 2.0 device driver on the instance by using the following tools:
+ For **Linux instances**, use tpm-tools.
+ For **Windows instances**, use the TPM management console (tpm.msc).

For more information about disabling the device driver, see the documentation for your operating system.

# Verify that an Amazon EC2 instance is enabled for NitroTPM
<a name="verify-nitrotpm-support-on-instance"></a>

You can verify whether an Amazon EC2 instance is enabled for NitroTPM. If NitroTPM support is enabled on the instance, the command returns `"v2.0"`. Otherwise, the `TpmSupport` field is not present in the output.

The Amazon EC2 console does not display the `TpmSupport` field.

------
#### [ AWS CLI ]

**To verify whether an instance is enabled for NitroTPM**  
Use the [describe-instances](https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-instances.html) command.

```
aws ec2 describe-instances \
    --instance-ids i-1234567890abcdef0 \
    --query Reservations[].Instances[].TpmSupport
```

------
#### [ PowerShell ]

**To verify whether an instance is enabled for NitroTPM**  
Use the [Get-EC2Instance](https://docs.aws.amazon.com/powershell/latest/reference/items/Get-EC2Instance.html) cmdlet.

```
(Get-EC2Instance `
    -InstanceId i-1234567890abcdef0).Instances.TpmSupport
```

------

## Verify NitroTPM access on your Windows instance
<a name="verify-nitrotpm-support-windows-instance"></a>

**(Windows instances only) To verify whether the NitroTPM is accessible to Windows**

1. [Connect to your EC2 Windows instance](connecting_to_windows_instance.md).

1. On the instance, run the tpm.msc program.

   The **TPM Management on Local Computer** window opens.

1. Check the **TPM Manufacturer Information** field. It contains the manufacturer's name and the version of the NitroTPM on the instance.  
![\[The TPM Management on Local Computer window and the TPM Manufacturer Information field showing the version of the NitroTPM on the instance.\]](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/images/tpm-1.png)

# Retrieve the public endorsement key for an EC2 instance
<a name="retrieve-ekpub"></a>

You can securely retrieve the public endorsement key for an instance at any time.

------
#### [ AWS CLI ]

**To retrieve the public endorsement key for an instance**  
Use the [get-instance-tpm-ek-pub](https://docs.aws.amazon.com/cli/latest/reference/ec2/get-instance-tpm-ek-pub.html) command.

**Example 1**  
The following example gets the `rsa-2048` public endorsement key in `tpmt` format for the specified instance.

```
aws ec2 get-instance-tpm-ek-pub \
    --instance-id i-1234567890abcdef0 \
    --key-format tpmt \ 
    --key-type rsa-2048
```

The following is the example output.

```
{
    "InstanceId": "i-01234567890abcdef",
    "KeyFormat": "tpmt",
    "KeyType": "rsa-2048",
    "KeyValue": "AAEACwADALIAIINxl2dEhLEXAMPLEUal1yT9UtduBlILZPKh2hszFGmqAAYAgABDA
    EXAMPLEAAABAOiRd7WmgtdGNoV1h/AxmW+CXExblG8pEUfNm0LOLiYnEXAMPLERqApiFa/UhvEYqN4
    Z7jKMD/usbhsQaAB1gKA5RmzuhSazHQkax7EXAMPLEzDthlS7HNGuYn5eG7qnJndRcakS+iNxT8Hvf
    0S1ZtNuItMs+Yp4SO6aU28MT/JZkOKsXIdMerY3GdWbNQz9AvYbMEXAMPLEPyHfzgVO0QTTJVGdDxh
    vxtXCOu9GYf0crbjEXAMPLEd4YTbWdDdgOKWF9fjzDytJSDhrLAOUctNzHPCd/92l5zEXAMPLEOIFA
    Ss50C0/802c17W2pMSVHvCCa9lYCiAfxH/vYKovAAE="
}
```

**Example 2**  
The following example gets the `rsa-2048` public endorsement key in `der` format for the specified instance.

```
aws ec2 get-instance-tpm-ek-pub \
    --instance-id i-1234567890abcdef0 \
    --key-format der \ 
    --key-type rsa-2048
```

The following is the example output.

```
{
    "InstanceId": "i-1234567890abcdef0",
    "KeyFormat": "der",
    "KeyType": "rsa-2048",
    "KeyValue": "MIIBIjANBgEXAMPLEw0BAQEFAAOCAQ8AMIIBCgKCAQEA6JF3taEXAMPLEXWH8DGZb4
    JcTFuUbykRR82bQs4uJifaKSOv5NGoEXAMPLEG8Rio3hnuMowP+6xuGxBoAHWAoDlGbO6FJrMdEXAMP
    LEnYUHvMO2GVLsc0a5ifl4buqcmd1FxqRL6I3FPwe9/REXAMPLE0yz5inhI7ppTbwxP8lmQ4qxch0x6
    tjcZ1Zs1DP0EXAMPLERUYLQ/Id/OBU7RBNMlUZ0PGG/G1cI670Zh/RytuOdx9iEXAMPLEtZ0N2A4pYX
    1+PMPK0lIOGssA5Ry03Mc8J3/3aXnOD2/ASRQ4gUBKznQLT/zTZEXAMPLEJUe8IJr2VgKIB/Ef+9gqi
    8AAQIDAQAB"
}
```

------
#### [ PowerShell ]

**To retrieve the public endorsement key for an instance**  
Use the [Get-EC2InstanceTpmEkPub](https://docs.aws.amazon.com/powershell/latest/reference/items/Get-EC2InstanceTpmEkPub.html) cmdlet.

**Example 1**  
The following example gets the `rsa-2048` public endorsement key in `tpmt` format for the specified instance.

```
Get-EC2InstanceTpmEkPub `
    -InstanceId i-1234567890abcdef0 `
    -KeyFormat tpmt `
    -KeyType rsa-2048
```

**Example 2**  
The following example gets the `rsa-2048` public endorsement key in `der` format for the specified instance.

```
Get-EC2InstanceTpmEkPub `
    -InstanceId i-1234567890abcdef0 `
    -KeyFormat der `
    -KeyType rsa-2048
```

------

# Amazon EC2 instance attestation
<a name="nitrotpm-attestation"></a>

Attestation is a process that allows you to cryptographically prove to any party that only trusted software, drivers, and boot processes are running on an Amazon EC2 instance. Amazon EC2 instance attestation is powered by the Nitro Trusted Platform Module (NitroTPM) and *Attestable AMIs*.

The first step to attestation is to **build an Attestable AMI** and determine the *reference measurements* of that AMI. An Attestable AMI is an AMI built from the ground up for attestation. The reference measurements are measurements of all of your software and configurations that you have included in your AMI. For more information about how you can obtain the reference measurements, see [Build the sample image description](build-sample-ami.md).

![\[Generating a reference measurements with Attestable AMIs.\]](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/images/attestable-ami.PNG)


The next step is to launch a [Nitro-TPM enabled EC2 instance](enable-nitrotpm-prerequisites.md#nitrotpm-instancetypes) with the Attestable AMI. After you have launched the instance, you can use the [ NitroTPM tools](attestation-get-doc.md) to generate the *Attestation Document*. Then you can compare the actual measurements of your EC2 instance from the Attestation Document against the reference measurements to check if the instance has the software and configurations that you trust.

By comparing the reference measurements generated during the Attestable AMI creation process with the measurements included in an instance's Attestation Document, you can validate that only software and code that you trust are running on the instance.

![\[Generating a Attestation Document.\]](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/images/attestation-document.PNG)


## Integration with AWS KMS
<a name="attestation-kms"></a>

To make the process of comparing measurements easier, you can use AWS Key Management Service (AWS KMS) as a verifier for Attestation Documents. With AWS KMS, you can create attestation-based KMS key policies that allow specific operations with the KMS key only if you provide an Attestation Document with measurements that match the reference measurements. To do this, you add specific condition keys to your KMS key policies that use the reference measurements as the condition key values, and then specify which KMS operations are allowed if the condition key is satisfied.

When you perform KMS operations using the KMS key, you must attach an Attestation Document to the KMS request. AWS KMS then validates the measurements from the Attestation Document against the reference measurements in the KMS key policy, and allows key access only if the measurements match.

Additionally, when you generate the Attestation Document for an instance, you must specify a public key for a key pair that you own. The specified public key is included in the Attestation Document. When AWS KMS validates the Attestation Document and allows a decryption operation, it automatically encrypts the response with the public key included in the Attestation Document before it is returned. This ensures that the response can be decrypted and used only with the matching private key for the public key included in the Attestation Document. 

This ensures that only instances running trusted software and code can perform cryptographic operations using a KMS key.

## Attesting isolated compute environments
<a name="attestation-isolated-compute-environments"></a>

In general, you can build and configure an EC2 instance to be an **isolated compute environment**, which provides no interactive access and no mechanism for your administrators and users to access the data that is being processed in the EC2 instance. With EC2 instance attestation you can prove to a third-party or service that your instance is running as an isolated compute environment. For more information, see [Isolate data from your own operators](isolate-data-operators.md).

For an example, see the [sample Amazon Linux 2023 image description](build-sample-ami.md) that creates an isolated compute environment. You can use this sample image description as a starting point and customize it to meet your requirements.

## AWS shared responsibility model
<a name="attestation-shared-responsibility"></a>

NitroTPM and Attestable AMIs are building blocks that can help you to set up and configure attestation on your EC2 instances. You are responsible for configuring the AMI to meet your respective use case. For more information, see [AWS Shared Responsibility Model](https://aws.amazon.com/compliance/shared-responsibility-model/).

**Topics**
+ [Integration with AWS KMS](#attestation-kms)
+ [Attesting isolated compute environments](#attestation-isolated-compute-environments)
+ [AWS shared responsibility model](#attestation-shared-responsibility)
+ [Attestable AMIs](attestable-ami.md)
+ [Prepare AWS KMS for attestation](prepare-attestation-service.md)
+ [Get the NitroTPM Attestation Document](attestation-get-doc.md)
+ [Integrating with AWS KMS](attestation-attest.md)
+ [Isolate data from your own operators](isolate-data-operators.md)

# Attestable AMIs
<a name="attestable-ami"></a>

An Attestable AMI is an Amazon Machine Image (AMI) with a corresponding cryptographic hash that represents all of its contents. The hash is generated during the AMI creation process, and it is calculated based on the entire contents of that AMI, including the applications, code, and boot process.

## Maintaining an Attestable State
<a name="maintain-attestability"></a>

An instance's measurements are based on its initial boot state. Any software or code changes made to the instance after launch and that persist after restarts will change the instance's measurement after restarts. If the measurements are altered, they deviate from the reference measurements of the Attestable AMI, and the instance will no longer be able to successfully attest to AWS KMS after the instance restarts. Therefore, for Attestable AMIs to be useful, instances need to return to their original boot state after they restart.

Always returning to the original boot state ensures that an instance can successfully attest after it restarts. The following utilities can be used to ensure that your instances remain attestable after restarts:
+ `erofs` — Enhanced Read-Only File System. This utility ensures that your root filesystem is read-only. With this utility, writes to the filesystem, including `/etc`, `/run`, and `/var`, are stored in memory and lost when the instance is restarted, leaving the root filesystem in its original launch state. For more information, see the [erofs documentation](https://docs.kernel.org/filesystems/erofs.html).
+ `dm-verity` — Provides integrity protection for the read-only root filesystem. The utility calculates a hash of the filesystem blocks and stores it in the kernel command line. This allows the kernel to verify the integrity of the filesystem during boot. For more information, see the [ dm-verity documentation](https://docs.kernel.org/admin-guide/device-mapper/verity.html).

## Requirements for creating Attestable AMIs
<a name="ami-attestable-requirements"></a>

Attestable AMIs have the following requirements:
+ **Base operating system** – Amazon Linux 2023 and [NixOS](https://github.com/aws/nitrotpm-attestation-samples)
+ **Architecture** – `x86_64` or `arm64` architecture
+ **TPM support** – NitroTPM must be enabled. For more information, see [Requirements for using NitroTPM with Amazon EC2 instances](enable-nitrotpm-prerequisites.md).
+ **Boot mode** – UEFI boot mode must be enabled.

**Topics**
+ [Maintaining an Attestable State](#maintain-attestability)
+ [Requirements for creating Attestable AMIs](#ami-attestable-requirements)
+ [Creating Attestable AMIs](#sample-ami)
+ [Build the sample image description](build-sample-ami.md)
+ [Sample Amazon Linux 2023 image description](al2023-isolated-compute-recipe.md)
+ [Customize the sample image description](customize-sample-ami.md)
+ [Compute PCR measurements](create-pcr-compute.md)

## Creating Attestable AMIs
<a name="sample-ami"></a>

To create an Attestable AMI, you will need to use Amazon Linux 2023 with [KIWI Next Generation (KIWI NG)](https://osinside.github.io/kiwi/). Amazon Linux 2023 provides all of the software and utilities needed to build an Attestable AMI using KIWI NG. 

KIWI NG is an open-source tool for building pre-configured Linux-based images. KIWI NG uses XML *image descriptions* that define the contents of an image. The image description specifies the base operating system, software, kernel configuration, and scripts to run in order to build a ready-to-use AMI for a specific use case.

During AMI build time, you need to use the `nitro-tpm-pcr-compute` utility to generate the reference measurements based on the Unified Kernel Image (UKI) generated by KIWI NG. For more information about using the `nitro-tpm-pcr-compute` utility, see [Compute PCR measurements for a custom AMI](create-pcr-compute.md).

AWS provides a sample Amazon Linux 2023 image description that includes all configurations needed to configure an EC2 instance in an isolated compute environment. For more information, see [Build the sample Amazon Linux 2023 image description](build-sample-ami.md).

# Build the sample Amazon Linux 2023 image description
<a name="build-sample-ami"></a>

AWS provides a sample Amazon Linux 2023 image description that you can use as a starting point for creating your own custom Attestable AMIs for your workloads. The sample image description includes Amazon Linux 2023 as the base operating system, `dm-verity` and `erofs` configurations for filesystem immutability, and it removes all interactive access (such as SSH, EC2 instance connect, and serial console) to create an isolated compute environment. For more information about the sample image description, see the [ Github repo](https://github.com/amazonlinux/kiwi-image-descriptions-examples).

The sample image description automatically installs the NitroTPM tools (`nitro-tpm-pcr-compute` and `nitro-tpm-attest`) in the built image in the `/usr/bin/` directory. This ensures that the tools are preinstalled on instances launched from the AMI.

The sample image description includes a script, `edit_boot_install.sh`, which includes the commands needed to generate the reference measurements. The script mounts the raw disk image file (`.raw`) created by KIWI NG to a loopback device, locates the UKI, which has the `.efi` file extension, and then runs the `nitro-tpm-pcr-compute` utility to generate the reference measurements for the AMI. The script is automatically executed by KIWI NG during build time.

This tutorial shows you how to build the sample image description to create an Attestable AMI.

For more information about creating your own image descriptions, see the following KIWI NG documentation:
+ [Quick Start](https://osinside.github.io/kiwi/quickstart.html)
+ [Image Description](https://osinside.github.io/kiwi/image_description.html)
+ [Sample Amazon Linux 2023 image description](https://github.com/amazonlinux/kiwi-image-descriptions-examples)

Prerequisites

Your IAM identity must have the following permissions to complete this tutorial:
+ `ebs:CompleteSnapshot`, `ebs:StartSnapshot`, and `ebs:PutSnapshotBlock` on `arn:aws:ec2:*::snapshot/*`
+ `ec2:RegisterImage` on all resources

**To build the sample Amazon Linux 2023 image description using KIWI NG**

1. Launch an Amazon EC2 instance using the latest AL2023 AMI. To ensure that your instance has enough storage space to build the AMI, ensure that you provision at least 12 GB of storage.

1. Install the required dependencies. The following command installs the following utilities:
   + `kiwi-cli`
   + `veritysetup`
   + `erofs-utils`
   + `aws-nitro-tpm-tools`

   ```
   sudo dnf install -y kiwi-cli python3-kiwi kiwi-systemdeps-core python3-poetry-core qemu-img veritysetup erofs-utils git cargo aws-nitro-tpm-tools
   ```

1. Install the `coldsnap` utility. This utility enables you to create Amazon EBS snapshots from raw image data. You'll use this utility to create an EBS snapshot from the raw disk image file created by KIWI NG.

   ```
   git clone https://github.com/awslabs/coldsnap.git
   cd coldsnap
   cargo install --locked coldsnap
   cd ..
   ```

1. Get the sample image description files.

   ```
   sudo dnf install kiwi-image-descriptions-examples
   ```

   The sample image description files are downloaded to the following directory: `/usr/share/kiwi-image-descriptions-examples/al2023/attestable-image-example`

1. Build the sample image description using the KIWI NG `system build` command. The following command creates a raw disk image file in the `./image` directory.

   ```
   sudo kiwi-ng \
   --color-output \
   --loglevel 0 \
   system build \
   --description /usr/share/kiwi-image-descriptions-examples/al2023/attestable-image-example \
   --target-dir ./image
   ```

   For more information, see the [ kiwi-ng system build](https://osinside.github.io/kiwi/commands/system_build.html) documentation.

1. Get the reference measurements for the AMI. The measurements are generated by the `nitro-tpm-pcr-compute` utility during image build time in the previous step. You can locate the reference measurements in the following file: `./image/pcr_measurements.json`.

   The measurements are provided in the following JSON format:

   ```
   {
     "Measurements": {
       "HashAlgorithm": "SHA384 { ... }",
       "PCR4": "PCR4_measurement",
       "PCR7": "PCR7_measurement",
       "PCR12": "PCR12_measurement"
     }
   }
   ```

1. Use the `coldsnap` utility to upload the raw disk image created by KIWI NG to an EBS snapshot. The command returns the snapshot ID. Make a note of the ID, you'll need it for the next step.

   ```
   SNAPSHOT=$(.cargo/bin/coldsnap upload ./image/al2023*.raw)
   echo "Created snapshot: $SNAPSHOT"
   ```

   For more information about the `coldsnap` utility, see the [ coldsnap GitHub repo](https://github.com/awslabs/coldsnap).

1. Register a TPM 2.0-enabled AMI with UEFI boot mode using the snapshot from the previous step. For `--architecture`, specify `x86_64` for Intel, or `arm64` for Graviton.

   ```
   aws ec2 register-image \
   --name "attestable_isolated_al2023_ami" \
   --virtualization-type hvm \
   --boot-mode uefi \
   --architecture x86_64|arm64 \
   --root-device-name /dev/xvda \
   --block-device-mappings DeviceName=/dev/xvda,Ebs={SnapshotId=${SNAPSHOT}} \
   --tpm-support v2.0 \
   --ena-support
   ```

# Sample Amazon Linux 2023 image description
<a name="al2023-isolated-compute-recipe"></a>

The sample Amazon Linux 2023 image description has the following characteristics: 

1. **Unified Kernel Image (UKI) boot** — Boot using a single, signed binary that combines the kernel, `initrd`, and boot parameters into one immutable image.

1. **Read-only root filesystem** — Use Enhanced Read-Only File System (`erofs`) with dm-verity protection to ensure that the root filesystem cannot be modified and maintains cryptographic integrity verification.

1. **Ephemeral overlay filesystem** — Create a temporary overlay filesystem that allows temporary writes to directories like `/etc`, `/run`, and `/var`. Since this overlay filesystem exists only in memory, all changes are automatically lost when the instance reboots, ensuring the system returns to its original trusted state.

1. **Disabled remote access methods** — Remove the following remote access mechanisms to prevent remote access:    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/al2023-isolated-compute-recipe.html)

   \$1 For more information, see [ Image Description Elements](https://osinside.github.io/kiwi/image_description/elements.html#packages-ignore).

# Customize the sample Amazon Linux 2023 image description for your workload
<a name="customize-sample-ami"></a>

You can customize the sample Amazon Linux 2023 image description and include the software packages, scripts, and files that are needed for your specific workload. Customizations are achieved by adding to or modifying various elements in the KIWI NG image description.

**Topics**
+ [Repository management](#prepare-custom-image-repos)
+ [Package management](#customize-sample-ami-packages)
+ [Adding files and directories](#customize-sample-ami-overlay)
+ [Adding custom scripts](#customize-sample-ami-script)

## Repository management
<a name="prepare-custom-image-repos"></a>

By default, the sample image description includes a single `<repository>` element that points to a mirror endpoint for the Amazon Linux 2023 core repositories. If needed, you can add references to other repositories from which to install your required software.

The sample image description uses the `dnf` package manager, as defined in the `<packagemanager>` element.

For more information about adding repositories, see [Setting up Repositories](https://osinside.github.io/kiwi/concept_and_workflow/repository_setup.html).

## Package management
<a name="customize-sample-ami-packages"></a>

By default, the sample image description includes all of the packages needed to create an Amazon Linux 2023 Attestable AMI for an isolated compute environment with an `erofs` read-only file system.

You can include additional software packages in the image description by adding them to the `<packages>` element in the image description. The `<packages>` element defines all of the software that should be installed into the AMI.

You can also use the `<packages>` element to uninstall or delete specific software packages.

For more information about adding or removing packages in the image description, see [Adding and Removing Packages](https://osinside.github.io/kiwi/concept_and_workflow/packages.html#).

## Adding files and directories
<a name="customize-sample-ami-overlay"></a>

The sample image description includes an overlay tree directory (`/root/`). The overlay tree directory is a directory that contains files and directories that will be copied into the image during the image build process. Any files and directories that you place into the overlay tree directory will be copied directly into the root filesystem of the image during the image building process.

The overlay tree directory is copied into the image after all the packages have been installed. New files are added and existing files are overwritten.

## Adding custom scripts
<a name="customize-sample-ami-script"></a>

The sample image description includes a single custom script, `edit_boot_install.sh`. This script includes the commands that are needed to run the `nitro-tpm-pcr-compute` utility, which generates the reference measurements based on the image content. This script is called immediately after the bootloader is installed.

If needed, you can include your own custom scripts in the image description to perform tasks or configurations during the image build process or at first boot of the image. Using scripts enables you to customize your images in ways that cannot be achieved using the image description alone.

To include custom scripts in your image description, you need to name them correctly based on the type of script, and add them to the same directory as the `appliance.kiwi` file. KIWI NG automatically detects and executes the scripts if they are named correctly and placed in the correct location, without the need to explicitly reference them in the image description file.

For more information about the scripts supported by KIWI NG, see [User-Defined Scripts](https://osinside.github.io/kiwi/concept_and_workflow/shell_scripts.html).

# Compute PCR measurements for a custom AMI
<a name="create-pcr-compute"></a>

The `nitro-tpm-pcr-compute` utility enables you to generate the reference measurements for an Attestable AMI during build time based on its Unified Kernel Image (UKI).

The sample Amazon Linux 2023 image description automatically installs the utility in the built image in the `/usr/bin/` directory. The sample image description also includes a script with the commands needed to run the utility to generate the reference measurements during image build time. If you are using the sample image description, you don't need to install the utility or run it manually. For more information, see [Build the sample Amazon Linux 2023 image description](build-sample-ami.md).

## Install the `nitro-tpm-pcr-compute` utility
<a name="nitro-tpm-compute-install"></a>

If you are using Amazon Linux 2023, you can install the `nitro-tpm-pcr-compute` utility from the Amazon Linux repository as follows.

```
sudo yum install aws-nitro-tpm-tools
```

The tools are installed in the `/usr/bin` directory.

## Use the `nitro-tpm-pcr-compute` utility
<a name="nitro-tpm-compute-use"></a>

The utility provides a single command, `nitro-tpm-pcr-compute`, for generating the reference measurements.

When you run the command, you must specify the following:
+ Unified kernel image (`UKI.efi`) — Required for Standard boot and UEFI.

**To generate the reference measurements for an Attestable AMI:**  
Use the following command and parameters:

```
/usr/bin/nitro-tpm-pcr-compute \
--image UKI.efi
```

The utility returns the reference measurements in the following JSON format:

```
{
  "Measurements": {
    "HashAlgorithm": "SHA384 { ... }",
    "PCR4": "PCR4_measurement",
    "PCR7": "PCR7_measurement",
    "PCR12": "PCR12_measurement"
  }
}
```

For a practical example of how to use the `nitro-tpm-pcr-compute` utility, see the `edit_boot_install.sh` script included in the [ sample Amazon Linux 2023 image description](build-sample-ami.md).

# Prepare AWS KMS for attestation
<a name="prepare-attestation-service"></a>

**Note**  
If you are attesting to a third-party service, you must build your own custom mechanisms for receiving, parsing, and validating Attestation Documents. For more information, see [Validate a NitroTPM Attestation Document](nitrotpm-attestation-document-validate.md).

After you have created your Attestable AMI, you should have reference measurements that you can use to validate requests from an Amazon EC2 instance. AWS KMS provides built-in support for attestation with NitroTPM.

For the AWS KMS key that you used to encrypt your secret data, add a key policy that allows key access only if API requests include an Attestation Document with measurements that match the reference measurements you generated during the Attestable AMI creation process. Use PCR4 and PCR12 measurements for standard boot or PCR7 measurements for Secure Boot. This ensures that only requests from instances launched using the Attestable AMI can perform cryptographic operations using the AWS KMS key.

AWS KMS provides `kms:RecipientAttestation:NitroTPMPCR4`, `kms:RecipientAttestation:NitroTPMPCR7`, and `kms:RecipientAttestation:NitroTPMPCR12` condition keys that enable you to create attestation-based conditions for NitroTPM KMS key policies. For more information, see [Condition keys for NitroTPM](https://docs.aws.amazon.com/kms/latest/developerguide/conditions-nitro-tpm.html).

For example, the following AWS KMS key policy allows key access only if the request originates from an instance with the `MyEC2InstanceRole` instance profile attached, and if the request includes an Attestation Document with specific PCR 4 and PCR 12 values.

```
{
  "Version": "2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "Allow requests from instances with attested AMI only",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::111122223333:role/MyEC2InstanceRole"
      },
      "Action": [
        "kms:Decrypt",
        "kms:GenerateDataKey",
        "kms:GenerateRandom"
      ],
      "Resource": "*",
      "Condition": {
        "StringEqualsIgnoreCase": {
          "kms:RecipientAttestation:NitroTPMPCR4":"EXAMPLE6b9b3d89a53b13f5dfd14a1049ec0b80a9ae4b159adde479e9f7f512f33e835a0b9023ca51ada02160EXAMPLE",
          "kms:RecipientAttestation:NitroTPMPCR12":"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
        }
      }
    }
  ]
}
```

# Get the NitroTPM Attestation Document
<a name="attestation-get-doc"></a>

The Attestation Document is a key component of the NitroTPM attestation process. It contains a series of cryptographic measurements that can be used to verify the identity of the instance and to prove that it is running only trusted software. You can use the Attestation Document with AWS KMS, which provides built-in support for NitroTPM attestation, or to build your own cryptographic attestation mechanisms.

The `nitro-tpm-attest` utility enables you to retrieve a signed NitroTPM Attestation Document for an Amazon EC2 instance during runtime.

The sample Amazon Linux 2023 image description automatically installs the utility in the built image in the `/usr/bin/` directory. This ensures that the utility is preinstalled on instances launched using the AMI. You don't need to manually install the utility. For more information, see [Build the sample Amazon Linux 2023 image description](build-sample-ami.md).

**Topics**
+ [Install the `nitro-tpm-attest` utility](#nitro-tpm-attest-install)
+ [Use the `nitro-tpm-attest` utility](#nitro-tpm-attest-use)
+ [NitroTPM Attestation Document](nitrotpm-attestation-document-content.md)
+ [Validate Attestation Document](nitrotpm-attestation-document-validate.md)

## Install the `nitro-tpm-attest` utility
<a name="nitro-tpm-attest-install"></a>

If you are using Amazon Linux 2023, you can install the `nitro-tpm-attest` utility from the Amazon Linux repository as follows.

```
sudo yum install aws-nitro-tpm-tools
```

## Use the `nitro-tpm-attest` utility
<a name="nitro-tpm-attest-use"></a>

The utility provides a single command, `nitro-tpm-attest`, for retrieving the Attestation Document. The command returns the Attestation Document encoded in Concise Binary Object Representation (CBOR) and signed using CBOR Object Signing and Encryption (COSE).

When you run the command, you can specify the following optional parameters:
+ `public-key` — A public key that can be used by AWS KMS or an external service to encrypt response data before it is returned. This ensures that only the intended recipient, that has possession of the private key, can decrypt the data. For example, if you are attesting with AWS KMS, the service encrypts the plaintext data with the public key in the Attestation Document, and returns the resulting ciphertext in the `CiphertextForRecipient` field in the response. Only RSA keys are supported.
+ `user-data` — The user data can be used to deliver any additional signed data to an external service. This user data can be used to complete an agreed protocol between the requesting instance and the external service. Not used for attestation with AWS KMS.
+ `nonce` — The nonce can be used to set up challenge-response authentication between the instance and the external service to help prevent impersonation attacks. Using a nonce enables the external service to verify that it is interacting with a live instance and not an impersonator that is reusing an old Attestation Document. Not used for attestation with AWS KMS.

**To retrieve the Attestation Document**  
Use the following command and optional parameters:

```
/usr/bin/nitro-tpm-attest \
--public-key rsa_public_key \
--user-data user_data \
--nonce nonce
```

For a complete example that shows how to generate an RSA key pair, and how to request an attestation with the public key, see the [nitro-tpm-attest GitHub repo](https://github.com/aws/NitroTPM-Tools/).

# NitroTPM Attestation Document contents
<a name="nitrotpm-attestation-document-content"></a>

An Attestation Document is generated by the NitroTPM and it is signed by the Nitro Hypervisor. It includes a series of platform configuration registers (PCR) values related to an Amazon EC2 instance. The following PCRs are included in the Attestation Document:

**Important**  
PCR0 and PCR1 are generally used to measure the initial boot code, which is controlled by AWS. To allow safe updates of early boot code, these PCRs will always contain constant values.
+ `PCR0` — Core System Firmware Executable Code
+ `PCR1` — Core System Firmware Data
+ `PCR2` — Extended or pluggable executable code
+ `PCR3` — Extended or pluggable Firmware Data
+ `PCR4` — Boot Manager Code
+ `PCR5` — Boot Manager Code Configuration and Data and GPT Partition Table
+ `PCR6` — Host Platform Manufacturer Specifics
+ `PCR7` — Secure Boot Policy
+ `PCR8 - 15` — Defined for use by the Static Operating System
+ `PCR16` — Debug
+ `PCR23` — Application Support

**PCR4**, **PCR7**, and **PCR12** specifically are used to validate that an instance was launched using an Attestable AMI. PCR4 and PCR12 can be used to validate with standard boot, and PCR7 can be used to validate with Secure Boot.
+ **PCR4 (Boot Manager Code)** — When an instance starts, the NitroTPM creates cryptographic hashes of all the binaries executed by its UEFI environment. With Attestable AMIs, these boot binaries embed hashes that prevent future loading of binaries that do not have matching hashes. This way, the single boot binary hash can describe exactly what code an instance will execute.
+ **PCR7 (Secure Boot Policy)** — UEFI boot binaries can be signed with a UEFI Secure Boot signing key. When UEFI Secure Boot is enabled, UEFI will prevent execution of UEFI boot binaries that do not match the configured policy. PCR7 contains a hash of the instance’s UEFI Secure Boot policy.

  If you need to maintain a single KMS policy that persists across instance updates, you can create a policy that validates against PCR7 to validate a UEFI Secure Boot certificate. During creation of an Attestable AMI, you can then sign the boot binary with your certificate and install it as the only permitted certificate in the AMI’s UEFI-data. Keep in mind that this model requires you to still generate a new certificate, install it in your policy and update AMIs if you want to prevent instances launched from old (untrusted) AMIs from passing your KMS policy.
+ **PCR12** — Contains the hash of the command line passed to the UEFI boot binary. Required in conjunction with PCR4 for standard boot to validate the command line was not modified.

# Validate a NitroTPM Attestation Document
<a name="nitrotpm-attestation-document-validate"></a>

**Note**  
This topic is intended for users who are using a third-party key management service, and need to build their own Attestation Document validation mechanisms.

This topic provides a detailed overview of the entire NitroTPM attestation flow. It also discusses what is generated by the AWS Nitro system when an Attestation Document is requested, and explains how a key management service should process an Attestation Document.

**Topics**
+ [The Attestation Document](#doc-def)
+ [Attestation Document validation](#validation-process)

The purpose of attestation is to prove that an instance is a trustworthy entity, based on the code and configuration that it is running. The root of trust for the instance resides within the AWS Nitro system, which provides Attestation Documents. 

Attestation Documents are signed by the AWS Nitro Attestation Public Key Infrastructure (PKI), which includes a published certificate authority that can be incorporated into any service. 

## The Attestation Document
<a name="doc-def"></a>

Attestation Documents are encoded in Concise Binary Object Representation (CBOR), and signed using CBOR Object Signing and Encryption (COSE).

For more information about CBOR, see [RFC 8949: Concise Binary Object Representation (CBOR)](https://www.rfc-editor.org/rfc/rfc8949.html).

### Attestation Document specification
<a name="doc-spec"></a>

The following shows the structure of an Attestation Document.

```
AttestationDocument = {
    module_id: text,                     ; issuing Nitro hypervisor module ID
    timestamp: uint .size 8,             ; UTC time when document was created, in
                                         ; milliseconds since UNIX epoch
    digest: digest,                      ; the digest function used for calculating the
                                         ; register values
    nitrotpm_pcrs: { + index => pcr },   ; map of PCRs at the moment the Attestation Document was generated
    certificate: cert,                   ; the public key certificate for the public key 
                                         ; that was used to sign the Attestation Document
    cabundle: [* cert],                  ; issuing CA bundle for infrastructure certificate
    ? public_key: user_data,             ; an optional DER-encoded key the attestation
                                         ; consumer can use to encrypt data with
    ? user_data: user_data,              ; additional signed user data, defined by protocol
    ? nonce: user_data,                  ; an optional cryptographic nonce provided by the
                                         ; attestation consumer as a proof of authenticity
}

cert = bytes .size (1..1024)       ; DER encoded certificate
user_data = bytes .size (0..1024)
pcr = bytes .size (32/48/64)       ; PCR content
index = 0..31
digest = "SHA384"
```

The optional parameters in the Attestation Document (`public_key`, `user_data`, and `nonce`) can be used to establish a custom validation protocol between an attesting instance and the external service.

## Attestation Document validation
<a name="validation-process"></a>

When you request an Attestation Document from the Nitro Hypervisor, you receive a binary blob that contains the signed Attestation Document. The signed Attestation Document is a CBOR-encoded, COSE-signed (using the COSE\$1Sign1 signature structure) object. The overall validation process includes the following steps:

1. Decode the CBOR object and map it to a COSE\$1Sign1 structure.

1. Extract the Attestation Document from the COSE\$1Sign1 structure.

1. Verify the certificate's chain.

1. Ensure that the Attestation Document is properly signed.

Attestation Documents are signed by the AWS Nitro Attestation PKI, which includes a root certificate for the commercial AWS partitions. The root certificate can be downloaded from [https://aws-nitro-enclaves.amazonaws.com/AWS\$1NitroEnclaves\$1Root-G1.zip](https://aws-nitro-enclaves.amazonaws.com/AWS_NitroEnclaves_Root-G1.zip), and it can be verified using the following fingerprint.

```
64:1A:03:21:A3:E2:44:EF:E4:56:46:31:95:D6:06:31:7E:D7:CD:CC:3C:17:56:E0:98:93:F3:C6:8F:79:BB:5B
```

The root certificate is based on an AWS Certificate Manager Private Certificate Authority (AWS Private CA) private key and it has a lifetime of 30 years. The subject of the PCA has the following format.

```
CN=aws.nitro-enclaves, C=US, O=Amazon, OU=AWS
```

**Topics**
+ [COSE and CBOR](#COSE-CBOR)
+ [Semantic validity](#semantic-validation)
+ [Certificate validity](#cert-validity)
+ [Certificate chain validity](#chain)

### COSE and CBOR
<a name="COSE-CBOR"></a>

Usually, the COSE\$1Sign1 signature structure is used when only one signature is going to be placed on a message. The parameters dealing with the content and the signature are placed in the protected header rather than having the separation of COSE\$1Sign. The structure can be encoded as either tagged or untagged, depending on the context it will be used in. A tagged COSE\$1Sign1 structure is identified by the CBOR tag 18. 

The CBOR object that carries the body, the signature, and the information about the body and signature is called the COSE\$1Sign1 structure. The COSE\$1Sign1 structure is a CBOR array. The array includes the following fields.

```
[
  protected:   Header,
  unprotected: Header,
  payload:     This field contains the serialized content to be signed,
  signature:   This field contains the computed signature value.
]
```

In the context of an Attestation Document, the array includes the following.

```
18(/* COSE_Sign1 CBOR tag is 18 */
    {1: -35}, /* This is equivalent with {algorithm: ECDS 384} */
    {}, /* We have nothing in unprotected */
    $ATTESTATION_DOCUMENT_CONTENT /* Attestation Document */,
    signature /* This is the signature */
)
```

For more information about CBOR, see [RFC 8949: Concise Binary Object Representation (CBOR)](https://www.rfc-editor.org/rfc/rfc8949.html).

### Semantic validity
<a name="semantic-validation"></a>

An Attestation Document will always have their CA bundle in the following order.

```
[ ROOT_CERT - INTERM_1 - INTERM_2 .... - INTERM_N]
      0          1          2             N - 1
```

Keep this ordering in mind, as some existing tools, such as Java’s CertPath from [ Java PKI API Programmer’s Guide](https://docs.oracle.com/javase/8/docs/technotes/guides/security/certpath/CertPathProgGuide.html), might require them to be ordered differently.

To validate the certificates, start from the Attestation Document CA bundle and generate the required chain, Where `TARGET_CERT` is the certificate in the Attestation Document.

```
[TARGET_CERT, INTERM_N, ..... , INTERM_2, INTERM_1, ROOT_CERT]
```

### Certificate validity
<a name="cert-validity"></a>

For all of the certificates in the chain, you must ensure that the current date falls within the validity period specified in the certificate.

### Certificate chain validity
<a name="chain"></a>

In general, a chain of multiple certificates might be needed, comprising a certificate of the public key owner signed by one CA, and zero or more additional certificates of CAs signed by other CAs. Such chains, called certification paths, are required because a public key user is only initialized with a limited number of assured CA public keys. Certification path validation procedures for the internet PKI are based on the algorithm supplied in X.509. Certification path processing verifies the binding between the subject distinguished name and/or subject alternative name and subject public key. The binding is limited by constraints that are specified in the certificates that comprise the path and inputs that are specified by the relying party. The basic constraints and policy constraint extensions allow the certification path processing logic to automate the decision making process.

**Note**  
CRL must be disabled when doing the validation.

Using Java, starting from the root path and the generated certificate chain, the chain validation is as follows.

```
validateCertsPath(certChain, rootCertficate) {
    /* The trust anchor is the root CA to trust */
    trustAnchors.add(rootCertificate);

    /* We need PKIX parameters to specify the trust anchors
     * and disable the CRL validation
     */
    validationParameters = new PKIXParameters(trustAnchors);
    certPathValidator = CertPathValidator.getInstance(PKIX);
    validationParameters.setRevocationEnabled(false);

    /* We are ensuring that certificates are chained correctly */
    certPathValidator.validate(certPath, validationParameters);
}
```

# Integrating with AWS KMS
<a name="attestation-attest"></a>

Your instance should have an application that can make AWS KMS API requests with the Attestation Document retrieved from the NitroTPM. When you make a request with an Attestation Document, AWS KMS validates the measurements in the provided Attestation Document against the reference measurements in the KMS key policy. Requests are allowed only if the measurements in the Attestation Document match the reference measurements in the KMS key policy.

When you call the [Decrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html), [DeriveSharedSecret](https://docs.aws.amazon.com/kms/latest/APIReference/API_DeriveSharedSecret.html), [GenerateDataKey](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html), [GenerateDataKeyPair](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKeyPair.html), or [GenerateRandom](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateRandom.html) API operations with an Attestation Document, these APIs encrypt the plaintext in the response under the public key from the Attestation Document, and return ciphertext instead of plaintext. This ciphertext can be decrypted only by using the matching private key that was generated in the instance.

For more information, see the [ Cryptographic attestation for NitroTPM](https://docs.aws.amazon.com/kms/latest/developerguide/services-nitro-enclaves.html) in the *AWS Key Management Service Developer Guide*.

**Note**  
If you are attesting to a third-party service, you must build your own custom mechanisms for receiving, parsing, and validating Attestation Documents. For more information, see [Validate a NitroTPM Attestation Document](nitrotpm-attestation-document-validate.md).

# Isolate data from your own operators
<a name="isolate-data-operators"></a>

The AWS Nitro System has [ zero operator access](https://docs.aws.amazon.com/whitepapers/latest/security-design-of-aws-nitro-system/no-aws-operator-access.html). There is no mechanism for any AWS system or person to log in to Amazon EC2 Nitro hosts, access the memory of EC2 instances, or access any customer data stored on local encrypted instance storage or remote encrypted Amazon EBS volumes.

When processing highly sensitive data, you might consider restricting access to that data by preventing even your own operators from accessing the EC2 instance.

You can create custom Attestable AMIs that are configured to provide an isolated compute environment. The AMI configuration depends on your workload and application requirements. Consider these best practices when building your AMI to create an isolated compute environment.
+ **Remove all interactive access** to prevent your operators or users access to the instance.
+ **Ensure that only trusted software and code** is included in the AMI.
+ **Configure a network firewall** within the instance to block access.
+ **Ensure read-only and immutable states** for all storage and file systems.
+ **Restrict instance access** to authenticated, authorized, and logged API calls.

# Updating Attestable AMIs that have no interactive access
<a name="working-with-isolated-amis"></a>

Once you launch an instance using an isolated compute environment AMI, there is no way for any user or operator to connect to the instance. This means that there is no way to install or update any software on the instance after launch.

If new software or a software update is required, you must create a new Attestable AMI that includes the required software or software updates. Then, use that AMI to launch a new instance, or to perform a root volume replacement on the original instance. Any software changes made to the AMI will result in a new hash being generated.

The following actions will result in a change to the reference measurements in the NitroTPM Attestation Document:
+ Stopping and starting an instance launched with an Attestable AMI
+ Performing a root volume replacement with a different AMI

If you perform any of these actions, you must then update your attestation service with the new reference measurements. For example, you must update your KMS key policy to the new reference measurements if you are using AWS KMS for attestation.

An instance retains its NitroTPM key material for the entire instance lifecycle, and persists through stop/starts and root volume replacement operations.

# Credential Guard for Windows instances
<a name="credential-guard"></a>

The AWS Nitro System supports Credential Guard for Amazon Elastic Compute Cloud (Amazon EC2) Windows instances. Credential Guard is a Windows virtualization-based security (VBS) feature that enables the creation of isolated environments to protect security assets, such as Windows user credentials and code integrity enforcement, beyond Windows kernel protections. When you run EC2 Windows instances, Credential Guard uses the AWS Nitro System to protect Windows login credentials from being extracted from the operating system's memory.

**Topics**
+ [Prerequisites](#credential-guard-prerequisites)
+ [Launch a supported instance](#credential-guard-launch-instance)
+ [Disable memory integrity](#disable-memory-integrity)
+ [Turn on Credential Guard](#turn-on-credential-guard)
+ [Verify that Credential Guard is running](#verify-credential-guard)

## Prerequisites
<a name="credential-guard-prerequisites"></a>

Your Windows instance must meet the following prerequisites to utilize Credential Guard.

**Amazon Machine Images (AMIs)**  
The AMI must be preconfigured to enable NitroTPM and UEFI Secure Boot. For more information on supported AMIs, see [Requirements for using NitroTPM with Amazon EC2 instances](enable-nitrotpm-prerequisites.md).

**Memory integrity**  
*Memory integrity*, also known as *hypervisor-protected code integrity (HVCI)* or *hypervisor enforced code integrity*, isn't supported. Before you turn on Credential Guard, you must ensure this feature is disabled. For more information, see [Disable memory integrity](#disable-memory-integrity).

**Instance types**  
The following instance types support Credential Guard across all sizes unless noted otherwise: `C5`, `C5d`, `C5n`, `C6i`, `C6id`, `C6in`, `C7i`, `C7i-flex`, `M5`, `M5d`, `M5dn`, `M5n`, `M5zn`, `M6i`, `M6id`, `M6idn`, `M6in`, `M7i`, `M7i-flex`, `R5`, `R5b`, `R5d`, `R5dn`, `R5n`, `R6i`, `R6id`, `R6idn`, `R6in` `R7i`, `R7iz`, `T3`.  
+ Though NitroTPM has some required instance types in common, the instance type must be one of the preceding instance types to support Credential Guard.
+ Credential Guard isn't supported for:
  + Bare metal instances.
  + The following instance types: `C7i.48xlarge`, `M7i.48xlarge`, and `R7i.48xlarge`.
For more information about instance types, see the [Amazon EC2 Instance Types Guide](https://docs.aws.amazon.com/ec2/latest/instancetypes/instance-types.html).

## Launch a supported instance
<a name="credential-guard-launch-instance"></a>

You can use the Amazon EC2 console or AWS Command Line Interface (AWS CLI) to launch an instance which can support Credential Guard. You will need a compatible AMI ID for launching your instance which is unique for each AWS Region.

**Tip**  
You can use the following link to discover and launch instances with compatible Amazon provided AMIs in the Amazon EC2 console:  
[https://console.aws.amazon.com/ec2/v2/home?#Images:visibility=public-images;v=3;search=:TPM-Windows_Server;ownerAlias=amazon](https://console.aws.amazon.com/ec2/v2/home?#Images:visibility=public-images;v=3;search=:TPM-Windows_Server;ownerAlias=amazon)

------
#### [ Console ]

**To launch an instance**  
Follow the steps to [launch an instance](ec2-launch-instance-wizard.md), specifying a supported instance type and a preconfigured Windows AMI.

------
#### [ AWS CLI ]

**To launch an instance**  
Use the [https://docs.aws.amazon.com/cli/latest/reference/ec2/run-instances.html](https://docs.aws.amazon.com/cli/latest/reference/ec2/run-instances.html) command to launch an instance using a supported instance type and preconfigured Windows AMI.

```
aws ec2 run-instances \
    --image-id resolve:ssm:/aws/service/ami-windows-latest/TPM-Windows_Server-2022-English-Full-Base \
    --instance-type c6i.large \
    --region us-east-1 \
    --subnet-id subnet-0abcdef1234567890
    --key-name key-name
```

------
#### [ PowerShell ]

**To launch an instance**  
Use the [https://docs.aws.amazon.com/powershell/latest/reference/items/New-EC2Instance.html](https://docs.aws.amazon.com/powershell/latest/reference/items/New-EC2Instance.html) command to launch an instance using a supported instance type and preconfigured Windows AMI.

```
New-EC2Instance `
    -ImageId resolve:ssm:/aws/service/ami-windows-latest/TPM-Windows_Server-2022-English-Full-Base `
    -InstanceType c6i.large `
    -Region us-east-1 `
    -SubnetId subnet-0abcdef1234567890 `
    -KeyName key-name
```

------

## Disable memory integrity
<a name="disable-memory-integrity"></a>

You can use the Local Group Policy Editor to disable memory integrity in supported scenarios. The following guidance can be applied for each configuration setting under **Virtualization Based Protection of Code Integrity**:
+ **Enabled without lock** – Modify the setting to **Disabled** to disable memory integrity.
+ **Enabled with UEFI lock** – Memory integrity has been enabled with UEFI lock. Memory integrity can't be disabled once it has been enabled with UEFI lock. We recommend creating a new instance with memory integrity disabled and terminating the unsupported instance if it's not in use.

**To disable memory integrity with the Local Group Policy Editor**

1. Connect to your instance as a user account with administrator privileges using the Remote Desktop Protocol (RDP). For more information, see [Connect to your Windows instance using an RDP client](connect-rdp.md).

1. Open the Start menu and search for **cmd** to start a command prompt.

1. Run the following command to open the Local Group Policy Editor: `gpedit.msc`

1. In the Local Group Policy Editor, choose **Computer Configuration**, **Administrative Templates**, **System**, **Device Guard**.

1. Select **Turn On Virtualization Based Security**, then select **Edit policy setting**.

1. Open the settings drop-down for **Virtualization Based Protection of Code Integrity**, choose **Disabled**, then choose **Apply**.

1. Reboot the instance to apply the changes.

## Turn on Credential Guard
<a name="turn-on-credential-guard"></a>

After you have launched a Windows instance with a supported instance type and compatible AMI, and confirmed that memory integrity is disabled, you can turn on Credential Guard.

**Important**  
Administrator privileges are required to perform the following steps to turn on Credential Guard.

**To turn on Credential Guard**

1. Connect to your instance as a user account with administrator privileges using the Remote Desktop Protocol (RDP). For more information, see [Connect to your Windows instance using an RDP client](connect-rdp.md).

1. Open the Start menu and search for **cmd** to start a command prompt.

1. Run the following command to open the Local Group Policy Editor: `gpedit.msc`

1. In the Local Group Policy Editor, choose **Computer Configuration**, **Administrative Templates**, **System**, **Device Guard**.

1. Select **Turn On Virtualization Based Security**, then select **Edit policy setting**.

1. Choose **Enabled** within the **Turn On Virtualization Based Security** menu.

1. For **Select Platform Security Level**, choose **Secure Boot and DMA Protection**.

1. For **Credential Guard Configuration**, choose **Enabled with UEFI lock**.
**Note**  
The remaining policy settings are not required to enable Credential Guard and can be left as **Not Configured**.

   The following image displays the VBS settings configured as described previously:  
![\[\]](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/images/vbs-credential-guard-gpo-enabled.png)

1. Reboot the instance to apply the settings.

## Verify that Credential Guard is running
<a name="verify-credential-guard"></a>

You can use the Microsoft System Information (`Msinfo32.exe`) tool to confirm that Credential Guard is running.

**Important**  
You must first reboot the instance to finish applying the policy settings required to enable Credential Guard.

**To verify Credential Guard is running**

1. Connect to your instance using the Remote Desktop Protocol (RDP). For more information, see [Connect to your Windows instance using an RDP client](connect-rdp.md).

1. Within the RDP session to your instance, open the Start menu and search for **cmd** to start a command prompt.

1. Open System Information by running the following command: `msinfo32.exe`

1. The Microsoft System Information tool lists the details for VBS configuration. Next to Virtualization-based security Services, confirm that **Credential Guard** appears as **Running**.

   The following image displays VBS is running as described previously:  
![\[\]](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/images/vbs-credential-guard-msinfo32-enabled.png)

# Access Amazon EC2 using an interface VPC endpoint
<a name="interface-vpc-endpoints"></a>

You can improve the security posture of your VPC by creating a private connection between resources in your VPC and the Amazon EC2 API. You can access the Amazon EC2 API as if it were in your VPC, without the use of an internet gateway, NAT device, VPN connection, or Direct Connect connection. EC2 instances in your VPC don't need public IP addresses to access the Amazon EC2 API.

For more information, see [Access AWS services through AWS PrivateLink](https://docs.aws.amazon.com/vpc/latest/privatelink/privatelink-access-aws-services.html) in the *AWS PrivateLink Guide*.

**Topics**
+ [Create an interface VPC endpoint](#create-endpoint)
+ [Create an endpoint policy](#endpoint-policy)

## Create an interface VPC endpoint
<a name="create-endpoint"></a>

Create an interface endpoint for Amazon EC2 using the following service name:
+ **com.amazonaws.*region*.ec2** — Creates an endpoint for the Amazon EC2 API actions.

For more information, see [Access an AWS service using an interface VPC endpoint](https://docs.aws.amazon.com/vpc/latest/privatelink/create-interface-endpoint.html) in the *AWS PrivateLink Guide*.

## Create an endpoint policy
<a name="endpoint-policy"></a>

An endpoint policy is an IAM resource that you can attach to your interface endpoint. The default endpoint policy allows full access to the Amazon EC2 API through the interface endpoint. To control the access allowed to the Amazon EC2 API from your VPC, attach a custom endpoint policy to the interface endpoint.

An endpoint policy specifies the following information:
+ The principals that can perform actions.
+ The actions that can be performed.
+ The resource on which the actions can be performed.

**Important**  
When a non-default policy is applied to an interface VPC endpoint for Amazon EC2, certain failed API requests, such as those failing from `RequestLimitExceeded`, might not be logged to AWS CloudTrail or Amazon CloudWatch.

For more information, see [ Control access to services using endpoint policies](https://docs.aws.amazon.com/vpc/latest/privatelink/vpc-endpoints-access.html) in the *AWS PrivateLink Guide*.

The following example shows a VPC endpoint policy that denies permission to create unencrypted volumes or to launch instances with unencrypted volumes. The example policy also grants permission to perform all other Amazon EC2 actions.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
    {
        "Action": "ec2:*",
        "Effect": "Allow",
        "Resource": "*",
        "Principal": "*"
    },
    {
        "Action": [
            "ec2:CreateVolume"
        ],
        "Effect": "Deny",
        "Resource": "*",
        "Principal": "*",
        "Condition": {
            "Bool": {
                "ec2:Encrypted": "false"
            }
        }
    },
    {
        "Action": [
            "ec2:RunInstances"
        ],
        "Effect": "Deny",
        "Resource": "*",
        "Principal": "*",
        "Condition": {
            "Bool": {
                "ec2:Encrypted": "false"
            }
        }
    }]
}
```

------