EC2 metadata service API returns 401 unauthorized error

1

Hi AWS, I am trying to print the IP address of an EC2 instance using a PowerShell script. I am using an IAM user for the same. These are the set of policies attached to my user:

  • AmazonEC2ReadOnlyAccess
  • AmazonEC2FullAccess

Original code is:

  $privateIp = $null
  $publicIp = $null
  if ($privateIp -eq $null) {
    try {
        $privateIp = Invoke-RestMethod -Uri "http://169.254.169.254/latest/meta-data/local-ipv4" -ErrorAction Stop
        echo "The deploy job server IP (private) is $privateIp"
    } catch {
        echo "Unable to retrieve private IP address."
    }
  } elseif ($publicIp -eq $null) {
      try {
          $publicIp = Invoke-RestMethod -Uri "http://169.254.169.254/latest/meta-data/public-ipv4" -ErrorAction Stop
          echo "The deploy job server IP (public) is $publicIp"
      } catch {
          echo "Unable to retrieve public IP address."
      }
  } else {
      echo "Unable to retrieve either private or public IP address."
  }

However while running this code it was printing what's written under the catch statement. I tweaked the code to get more insights why this is occurring and the modified code looks like:

          $privateIp = $null
          $publicIp = $null
          if ($privateIp -eq $null) {
            try {
                $privateIp = Invoke-RestMethod -Uri "http://169.254.169.254/latest/meta-data/local-ipv4" -ErrorAction Stop
                echo "The deploy job server IP (private) is $privateIp"
            } catch {
                $errorMessage = $_.Exception.Message
                echo "Error: $errorMessage"
            }
          } elseif ($publicIp -eq $null) {
              try {
                  $publicIp = Invoke-RestMethod -Uri "http://169.254.169.254/latest/meta-data/public-ipv4" -ErrorAction Stop
                  echo "The deploy job server IP (public) is $publicIp"
              } catch {
                  $errorMessage = $_.Exception.Message
                  echo "Error: $errorMessage"
              }
          } else {
              $errorMessage = $_.Exception.Message
              echo "Error: $errorMessage"
          }

and it gave this error message Error: The remote server returned an error: (401) Unauthorized.

Is it because I am missing some IAM permissions as I am not using an EC2 Instance Profile rather using an IAM user or is there any bug in the code. Please suggest.

1 Answer
1

Hi,

Your powershell script has to endorse the execution role of the EC2 instance before querying the metadata to avoid unauthorized.

See https://docs.aws.amazon.com/powershell/latest/reference/items/Use-STSRole.html

Have a look here for access to execution by an application running in the instance: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html

Best,

Didier

profile pictureAWS
EXPERT
answered 3 months ago
  • Hi Didier, can you simplify it down please as I am a little confused.

  • I updated my answer with more details that should allow you to go through

  • I tried to provision the infrastructure following the links above as suggested above. The steps I performed are:

    1. Created an Instance Profile Role ec2-instance-role. Attached AmazonEC2FullAccess to it. This role has trust relationship with ec2.amazonaws.com endpoint.
    2. Created an IAM User and Attached AmazonEC2FullAccess policy to it. Apart from it I have attached one inline policy to it i.e.
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": [
                    "ec2:RunInstances",
                    "ec2:AssociateIamInstanceProfile",
                    "ec2:ReplaceIamInstanceProfileAssociation",
                    "iam:ListInstanceProfiles"
                ],
                "Resource": "*"
            },
            {
                "Effect": "Allow",
                "Action": "iam:PassRole",
                "Resource": [
                    "arn:aws:iam::xxxxxxxxxxxx:role/ec2-instance-role",
                    "arn:aws:iam::xxxxxxxxxxxx:instance-profile/ec2-instance-role"
                ]
            }
        ]
    }
    
    1. I have attached the Instance Profile role to EC2 instance.

    But when I triggered the script I am still getting 401 error. Please check if I still missed something or not from IAM perspective.

    Thanks

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions