EC2インスタンスでメタデータが取れなくなった！？～IMDSv2がデフォルトで有効になるみたい～

# 概要

「ユーザーでインスタンスのメタデータが取得できないです。どうしたらよいでしょうか？」

と聞かれることがあり。
そんなことないでしょ！と思ったら[IMDSv2がデフォルトで有効になる](https://aws.amazon.com/jp/blogs/news/amazon-ec2-instance-metadata-service-imdsv2-by-default/)
ということが分かったので実際に検証してみました。

# IMDSv2 って？？

IMDSとはインスタンスメタデータサービスといってインスタンスのメタデータを取得出来るサービスです。
IMDSv1はURLを叩けばメタデータを取得できましたがIMDSv2はセッショントークンを取得してからじゃないとメタデータが取得できなくなってよりセキュアになったそうです。

https://blog.serverworks.co.jp/tech/2019/11/27/imdsv2/

https://dev.classmethod.jp/articles/use-ec2-imdsv2/


## 検証時にインスタンを立ち上げた際に利用したCloudFormationテンプレート(IMDSv1用でのメタデータ取得)

本テンプレートを利用して、AMI IDをAmazon Linux2023のAMIに変更することでIMDSv1とIMDSv2を切り替えて検証を実施。

### CloudFormationテンプレート
```yml
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
  KeyName:
    Type: "AWS::EC2::KeyPair::KeyName"
    Description: "EC2インスタンスに関連付けるKey Pairの名前"
Resources:
  MyInstance:
    Type: "AWS::EC2::Instance"
    Properties:
      ImageId: "ami-xxxxxxxxxxxxxxxxx"  # EC2インスタンスに使用するAMIのIDを指定
      InstanceType: "t2.micro"
      KeyName: !Ref KeyName
      UserData:
        Fn::Base64: !Sub |
          #!/bin/bash
          echo "Hello from EC2 instance!" > /var/www/html/index.html
          echo "Instance ID: \$(curl http://169.254.169.254/latest/meta-data/instance-id)" >> /var/www/html/index.html
          yum -y install httpd
          systemctl start httpd.service
          systemctl enable httpd.service
      Tags:
        - Key: Name
          Value: "MyInstance"
      SecurityGroupIds:
        - sg-xxxxxxxxxxxxxxxxx  # EC2インスタンスに関連付けるセキュリティグループのIDを指定
      SubnetId: "subnet-xxxxxxxxxxxxxxxxx"  # EC2インスタンスを起動するサブネットのIDを指定
Outputs:
  InstanceId:
    Value: !Ref MyInstance
    Description: "起動したEC2インスタンスのID"

```


## IMDSv1の状態
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1985649/c794a2f8-a439-45f8-da1a-65775985d480.png)


## IMDSv2がデフォルトで有効になったAmazon Linux2023での状態
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1985649/a8335e0b-b469-4ea6-821a-161fff3633e1.png)


# 状況確認

## 401 - Unauthorized　が出る
```
$ curl -s http://169.254.169.254/latest/meta-data/instance-id
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
  <title>401 - Unauthorized</title>
 </head>
 <body>
  <h1>401 - Unauthorized</h1>
 </body>
</html>
```

# 対応方法

メタデータ取得箇所をTockenを利用した方法へ変更する。

https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html

```diff_yaml

- echo "Instance ID: \$(curl http://169.254.169.254/latest/meta-data/instance-id)" >> /var/www/html/index.html

+ TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600") && curl -s -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/instance-id >> /var/www/html/index2.html echo "Instance ID: $(cat /var/www/html/index2.html)" >> /var/www/html/index.html

```

# まとめ

EC2インスタンスを使っていたらUserDataからメタデータにアクセスしたりインスタンスメタデータにアクセスすることはほとんどだと思います。
2024年以降のEC2インスタンスはIMDSv2がデフォルトで有効になっています。

IMDSv1を有効にすることも可能なようですがIMDSv2への移行が推奨となっています。

https://aws.amazon.com/jp/blogs/news/amazon-ec2-instance-metadata-service-imdsv2-by-default/

普段意識しないIMDSがアップデートされ改めてAWS内部のネットワークなどについても考えたのでとても勉強になりました！