Answers: <p><code>Alternatively, is there another way I could allow an IAM user to launch an instance in line with a template, while preventing them from making changes (such as choosing a super-expensive instance type)?</code></p>
  
  <p>I've encountered this problem last year and have circulated up to our AWS account's architect, who contacted their IAM division. </p>
  
  <p>AWS's response is that this is <strong>intended behavior</strong>. Reason given was that <strong>"An instance-type spec on a launch template is not a resource, or conditional that can be used to granted/deny permissions to"</strong>. Notice that inside the IAM policy, specifying a launch template is a condition to action "RunInstance", and the resource of said policy is an ec2 instance. </p>
  
  <p>According to AWS IAM team, in order for you to restrict instance-type (a condition on the resource, "instance"), you must specify the restriction as part of the condition clause to be applied to the instance, like the following:</p>
  
  <pre><code>{
    "Effect": "Allow",
    "Action": "ec2:RunInstances",
    "Resource": "*",
    "Condition": {
      "ArnLike": {
        "ec2:LaunchTemplate": "arn:aws:ec2:ap-southeast-2:xxxxxxx:launch-template/lt-xxxxxxx"
      },
      "Bool": {
        "ec2:IsLaunchTemplateResource": "true"
      },
      "StringNotLikeIfExists": {
        "ec2:InstanceType": [
          "c5.*xlarge",
          "p3.*xlarge"
        ]
      }
    }
  }
  </code></pre>
  
  <p>Obviously, it is near impossible to list all of the expensive instances we don't want our users to use, and kinda defeats the purpose of using a launch template.  But in a messed-up way, in the IAM world AWS created, this actually makes sense. </p>
  
  <p>Consider the docs here: <a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ExamplePolicies_EC2.html#iam-example-runinstances-launch-templates" rel="nofollow noreferrer">https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ExamplePolicies_EC2.html#iam-example-runinstances-launch-templates</a></p>
  
  <p>Note the language: <code>The policy uses the ec2:IsLaunchTemplateResource condition key to prevent users from overriding any of the launch template *resources* in the RunInstances request.</code>  So that clause only applies to resources (like NICs, IPs, etc), but not instance-type, which is not considered as a resource. </p>
  
  <p>I asked that they revise their docs to explain this, and of course, nothing's changed. </p>
  
Answers: CC BY-SA 4.0
Answers: 2019-07-07T01:09:17.060Z
Answers: Thank you for taking the time to track that down and understand it. While it’s disappointing, like you said it does make a lot of sense!
Answers: Tim Malone
Answers: CC BY-SA 4.0
Answers: 2019-07-05T22:52:50.250Z
Answers: 2019-07-05T22:52:50.250Z
Answers: Ying-Chi I
Body: <p>I'm trying to set up an IAM policy that allows a user to run an instance (<code>ec2:RunInstances</code>), but only from a specific launch template - <em>and</em> without making any changes to that launch template's parameters.</p>
  
  <p>The relevant section of my policy looks like this:</p>
  
  <pre><code>{
    "Effect": "Allow",
    "Action": "ec2:RunInstances",
    "Resource": "*",
    "Condition": {
      "ArnLike": {
        "ec2:LaunchTemplate": "arn:aws:ec2:ap-southeast-2:xxxxxxx:launch-template/lt-xxxxxxx"
      },
    }
  }
  </code></pre>
  
  <p>This works great. Running the following using the user's credentials works:</p>
  
  <pre><code>aws ec2 run-instances --launch-template LaunchTemplateName=test
  </code></pre>
  
  <p>...and specifying a different launch template fails. So far so good.</p>
  
  <p>However, the user can override values in the launch template, and pretty much do whatever they like:</p>
  
  <pre><code>aws ec2 run-instances --launch-template LaunchTemplateName=test --instance-type t2.micro
  </code></pre>
  
  <p>This is despite me setting the instance type in the launch template as <code>t2.nano</code>.</p>
  
  <p><a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ExamplePolicies_EC2.html#iam-example-runinstances-launch-templates" rel="nofollow noreferrer">The documentation</a> has a solution for this: require the <code>ec2:IsLaunchTemplateResource</code> condition to be <code>"true"</code>, which apparently only is so if the user has not overridden the launch template.</p>
  
  <p>Perfect - exactly what I was after! The Condition statement in my IAM policy now looks like this:</p>
  
  <pre><code>  "Condition": {
      "ArnLike": {
        "ec2:LaunchTemplate": "arn:aws:ec2:ap-southeast-2:xxxxxxx:launch-template/lt-xxxxxxx"
      },
      "Bool": {
        "ec2:IsLaunchTemplateResource": "true"
      }
    }
  </code></pre>
  
  <p>However, with this additional condition present, the <code>RunInstances</code> call fails <em>even if the user makes no changes</em>. After <a href="https://docs.aws.amazon.com/cli/latest/reference/sts/decode-authorization-message.html" rel="nofollow noreferrer">decoding the authorization failure message</a>, I can see that AWS is reporting <code>ec2:IsLaunchTemplateResource</code> was not <code>"true"</code>:</p>
  
  <pre><code>{
    "key": "ec2:IsLaunchTemplateResource",
    "values": {
      "items": [
        {
          "value": "false"
        }
      ]
    }
  }
  </code></pre>
  
  <hr>
  
  <p><strong>EDIT</strong>: After posting this, I continued to iterate, and noticed that the specific resource that was hitting up against this issue was the subnet - which wasn't defined in the launch template. Taking cues from additional examples in the documentation I linked to, I tried adding another statement to allow the subnet resource even without <code>ec2:IsLaunchTemplateResource</code> being true, and this worked. I also tried, alternatively, explicitly defining the subnet in the launch template: this worked too.</p>
  
  <p><em>However,</em> now I am not getting access denied <em>even when changing the instance type</em>! So it appears that it was the subnet all along that was triggering the original denial. While I've sort of taken a step forward, the symptom of the issue has now flipped from what I was initially experiencing... and now although the user can launch, they can also launch instances I don't want them to. So my initial question below still remains. :)</p>
  
  <hr>
  
  <p>So, my question is... have I done something wrong? Does <code>ec2:IsLaunchTemplateResource</code> work in the way I have understood it (which I think is fairly clear in the documentation)?</p>
  
  <p>Alternatively, is there another way I could allow an IAM user to launch an instance in line with a template, while preventing them from making changes (such as choosing a super-expensive instance type)?</p>
  
Comments: CC BY-SA 4.0
Comments: 2018-06-29T07:45:07.667Z
Comments: This mostly sounds like a bug on AWS side, did you open a case at AWS also ? They'd be far more authoritative than us to answer that.
Comments: Tensibai
Comments: CC BY-SA 4.0
Comments: 2018-06-29T08:17:11.037Z
Comments: I guess that is possible... I generally assume that issues like this are not bugs (because I'm sure AWS would have a massively decent amount of testing), but rather me misunderstanding how it works :P Having said that, I've iterated on this and am just about to edit my question with additional findings.
Comments: Tim Malone
Comments: CC BY-SA 4.0
Comments: 2018-06-29T08:32:29.577Z
Comments: On another note, I know I could add the instance type to the IAM policy as well. I guess this will be the fallback solution, but I'd much rather not be maintaining the launch template parameters in two places - particularly because I'll probably need to add more checks, eg. for the image ID as well, and also because the documentation does seem to imply that this doesn't have to be done. :/
Comments: Tim Malone
Comments: CC BY-SA 4.0
Comments: 2019-04-22T09:20:26.923Z
Comments: I am little bit lost in how the current IAM permissions for the executing user look like. Can you maybe create a test user with ONLY relevant permissions & test & share the full policy? For maintaining the conditions on two places CloudFormation template can be a good help - with parameters you can still have the definition at one place.
Comments: petrchpetr
Tags: <amazon-ec2><aws-iam>
Title: Preventing an IAM user from overriding launch template parameters on RunInstance
UserDisplayName: Tim Malone
ThreadText: # Preventing an IAM user from overriding launch template parameters on RunInstance
  
  (Asked by: username_0 on 2018-06-29)
  
  I'm trying to set up an IAM policy that allows a user to run an instance (`ec2:RunInstances`), but only from a specific launch template - *and* without making any changes to that launch template's parameters.
  
  The relevant section of my policy looks like this:
  
  ```
  {
    "Effect": "Allow",
    "Action": "ec2:RunInstances",
    "Resource": "*",
    "Condition": {
      "ArnLike": {
        "ec2:LaunchTemplate": "arn:aws:ec2:ap-southeast-2:xxxxxxx:launch-template/lt-xxxxxxx"
      },
    }
  }
  
  ```
  
  This works great. Running the following using the user's credentials works:
  
  ```
  aws ec2 run-instances --launch-template LaunchTemplateName=test
  
  ```
  
  ...and specifying a different launch template fails. So far so good.
  
  However, the user can override values in the launch template, and pretty much do whatever they like:
  
  ```
  aws ec2 run-instances --launch-template LaunchTemplateName=test --instance-type t2.micro
  
  ```
  
  This is despite me setting the instance type in the launch template as `t2.nano`.
  
  [The documentation](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ExamplePolicies_EC2.html#iam-example-runinstances-launch-templates) has a solution for this: require the `ec2:IsLaunchTemplateResource` condition to be `"true"`, which apparently only is so if the user has not overridden the launch template.
  
  Perfect - exactly what I was after! The Condition statement in my IAM policy now looks like this:
  
  ```
    "Condition": {
      "ArnLike": {
        "ec2:LaunchTemplate": "arn:aws:ec2:ap-southeast-2:xxxxxxx:launch-template/lt-xxxxxxx"
      },
      "Bool": {
        "ec2:IsLaunchTemplateResource": "true"
      }
    }
  
  ```
  
  However, with this additional condition present, the `RunInstances` call fails *even if the user makes no changes*. After [decoding the authorization failure message](https://docs.aws.amazon.com/cli/latest/reference/sts/decode-authorization-message.html), I can see that AWS is reporting `ec2:IsLaunchTemplateResource` was not `"true"`:
  
  ```
  {
    "key": "ec2:IsLaunchTemplateResource",
    "values": {
      "items": [
        {
          "value": "false"
        }
      ]
    }
  }
  
  ```
  
  ---
  
  **EDIT**: After posting this, I continued to iterate, and noticed that the specific resource that was hitting up against this issue was the subnet - which wasn't defined in the launch template. Taking cues from additional examples in the documentation I linked to, I tried adding another statement to allow the subnet resource even without `ec2:IsLaunchTemplateResource` being true, and this worked. I also tried, alternatively, explicitly defining the subnet in the launch template: this worked too.
  
  *However,* now I am not getting access denied *even when changing the instance type*! So it appears that it was the subnet all along that was triggering the original denial. While I've sort of taken a step forward, the symptom of the issue has now flipped from what I was initially experiencing... and now although the user can launch, they can also launch instances I don't want them to. So my initial question below still remains. :)
  
  ---
  
  So, my question is... have I done something wrong? Does `ec2:IsLaunchTemplateResource` work in the way I have understood it (which I think is fairly clear in the documentation)?
  
  Alternatively, is there another way I could allow an IAM user to launch an instance in line with a template, while preventing them from making changes (such as choosing a super-expensive instance type)?
  
  **Tags:** amazon-ec2, aws-iam
  
  > **Comments:**
  > **username_1**: This mostly sounds like a bug on AWS side, did you open a case at AWS also ? They'd be far more authoritative than us to answer that.  
  > **username_0**: I guess that is possible... I generally assume that issues like this are not bugs (because I'm sure AWS would have a massively decent amount of testing), but rather me misunderstanding how it works :P Having said that, I've iterated on this and am just about to edit my question with additional findings.  
  > **username_0**: On another note, I know I could add the instance type to the IAM policy as well. I guess this will be the fallback solution, but I'd much rather not be maintaining the launch template parameters in two places - particularly because I'll probably need to add more checks, eg. for the image ID as well, and also because the documentation does seem to imply that this doesn't have to be done. :/  
  > **username_2**: I am little bit lost in how the current IAM permissions for the executing user look like. Can you maybe create a test user with ONLY relevant permissions & test & share the full policy? For maintaining the conditions on two places CloudFormation template can be a good help - with parameters you can still have the definition at one place.  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_3 on 2019-07-05. Score: 1 | Accepted answer
  
  `Alternatively, is there another way I could allow an IAM user to launch an instance in line with a template, while preventing them from making changes (such as choosing a super-expensive instance type)?`
  
  I've encountered this problem last year and have circulated up to our AWS account's architect, who contacted their IAM division.
  
  AWS's response is that this is **intended behavior**. Reason given was that **"An instance-type spec on a launch template is not a resource, or conditional that can be used to granted/deny permissions to"**. Notice that inside the IAM policy, specifying a launch template is a condition to action "RunInstance", and the resource of said policy is an ec2 instance.
  
  According to AWS IAM team, in order for you to restrict instance-type (a condition on the resource, "instance"), you must specify the restriction as part of the condition clause to be applied to the instance, like the following:
  
  ```
  {
    "Effect": "Allow",
    "Action": "ec2:RunInstances",
    "Resource": "*",
    "Condition": {
      "ArnLike": {
        "ec2:LaunchTemplate": "arn:aws:ec2:ap-southeast-2:xxxxxxx:launch-template/lt-xxxxxxx"
      },
      "Bool": {
        "ec2:IsLaunchTemplateResource": "true"
      },
      "StringNotLikeIfExists": {
        "ec2:InstanceType": [
          "c5.*xlarge",
          "p3.*xlarge"
        ]
      }
    }
  }
  
  ```
  
  Obviously, it is near impossible to list all of the expensive instances we don't want our users to use, and kinda defeats the purpose of using a launch template. But in a messed-up way, in the IAM world AWS created, this actually makes sense.
  
  Consider the docs here: <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ExamplePolicies_EC2.html#iam-example-runinstances-launch-templates>
  
  Note the language: `The policy uses the ec2:IsLaunchTemplateResource condition key to prevent users from overriding any of the launch template *resources* in the RunInstances request.` So that clause only applies to resources (like NICs, IPs, etc), but not instance-type, which is not considered as a resource.
  
  I asked that they revise their docs to explain this, and of course, nothing's changed.
  
  > **Comments:**
  > **username_0**: Thank you for taking the time to track that down and understand it. While it’s disappointing, like you said it does make a lot of sense!  
  
  ---
  
  