Akamai's cloud computing services で Metadata service が利用できるようになりました

# はじめに
Akamai's cloud computing servicesでは、インスタンスをデプロイする際にソフトウェアの自動構築をサポートする機能としてStackScriptsを提供しています。
今回新たにMetadata serviceを提供し、さらに自由度の高いソリューションを利用して構築の自動化を行うことが可能になりました。

https://www.linode.com/docs/products/compute/compute-instances/guides/metadata

:::note
Metadata serviceは執筆時点でBeta中となります。
Betaに参加するためには、[サポートチーム](https://www.linode.com/support/])への連絡が必要となります。
:::

## Linode’s Metadata serviceとは

Metadata serviceはインスタンス内からのみアクセスできるAPIを提供し、設定したMetadataの情報を取得できるようにするサービスです。
このMetadata serviceを使うと[**cloud-init**](https://cloudinit.readthedocs.io/en/latest/)を利用できるようになり、インスタンスの初期設定を自動化することができます。
[**cloud-init**](https://cloudinit.readthedocs.io/en/latest/)とは、MetadataとUserdataを受け取り、それに基づいた初期セットアップを行えるツールです。

:::note warn
Metadata serviceは執筆時点で対応するDistributionとRegionが限られています。
Data centers: Chicago (USA), Milan (Italy), Osaka (Japan), Paris (France), Seattle (USA), Stockholm (Sweden), and Washington DC (USA)
Distributions: Ubuntu 22.04 LTS, Ubuntu 20.04 LTS, Debian 11
:::

## cloud-initを利用してインスタンスの初期設定をやってみる

Akamai Cloud Managerからインスタンスを作成します。
作成する際には、Metadata serviceに対応しているDistributionとRegionを選択する必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49877/56e13d6e-d688-7920-ed95-a07d53cb678e.png)

Add User Dataにcloud-initの設定を記載します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49877/40be8f37-07e9-f24f-bf94-54cdd03e04a9.png)


今回のcloud-initの設定では以下の初期構築の自動化を行っています。

- タイムゾーンの設定
- SSH接続ユーザーの作成と公開鍵の配置
- パッケージのアップデート
- ツールの導入
- SSHパスワード認証を無効
- RootのSSH接続を無効
- HostnameをAkamai Cloud Managerで設定した値に変更
- 再起動

```yaml:User Data
#cloud-config

#Set timezone
timezone: Asia/Tokyo

#Add user and set SSH keys
users:
  - name: devuser
    sudo: ['ALL=(ALL) NOPASSWD:ALL']
    groups: sudo
    shell: /bin/bash
    ssh-authorized-keys:
      - ssh-rsa <公開鍵をここに記載する>
 
#Disable SSH password authentication
ssh_pwauth: false

#Update packages
package_update: true
package_upgrade: true

#Install necessary packages
packages:
  - git
  - tmux
  - htop
  - curl
  - wget
  - jq

#Write a script to fetch instance metadata and set hostname to the instance label
write_files:
  - path: /root/set_hostname.sh
    permissions: '0755'
    content: |
      #!/bin/sh

      export TOKEN=$(curl -s -X PUT -H "Metadata-Token-Expiry-Seconds: 3600" http://169.254.169.254/v1/token)
      export LABEL=$(curl -s -H "Metadata-Token: $TOKEN" http://169.254.169.254/v1/instance | grep label: | awk '{print $2}')
      echo $LABEL > /etc/hostname
      hostname $LABEL
      sed -i 's/^PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
      exit 0

#reboot
runcmd:
  - /root/set_hostname.sh
  - [ shutdown, -r, +1, 'Rebooting to apply changes' ]
```

:::note warn
Metadata serviceにアクセスするためにはインスタンスにPublic Interfaceが必要です。
Cloud Managerは日本語に対応していません、そのためコメントなどに２バイト文字を利用できません。
:::

作成したユーザーでSSHアクセスし、ツールなどがインストールされていることを確認します。

```
Last login: Wed Aug  2 15:40:01 2023 from 150.91.173.98
devuser@ubuntu-us-iad-001:~$
devuser@ubuntu-us-iad-001:~$ which htop
/usr/bin/htop
```

以上で構築は完了です。

## Metadata service APIにアクセスする

Metadata serviceはcloud-initに利用されるだけではなく、APIとしての利用もできます。
APIはリンクローカルアドレスの169.254.169.254とfd00:a9fe:a9fe::1にて提供されています。
執筆時点では３つの機能を提供しています。


APIにてアクセスする際にはトークン情報を取得する必要があります。

```bash
export TOKEN=$(curl -X PUT -H "Metadata-Token-Expiry-Seconds: 3600" http://169.254.169.254/v1/token)
```

インスタンスに設定されている情報を取得できます。
先程紹介したコードではMetadataの情報をもとに作成時に設定したHostnameを初期設定しています。

```bash
curl -s -H "Metadata-Token: $TOKEN" http://169.254.169.254/v1/instance

backups.enabled: false
host_uuid: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
id: xxxxxxxxxxxxx
label: ubuntu-us-iad-001
region: us-iad
specs.disk: 51200
specs.gpus: 0
specs.memory: 2048
specs.transfer: 2000
specs.vcpus: 1
type: g6-standard-1
```

インスタンスに設定されているネットワーク情報を取得することができます。

```bash
curl -s -H "Metadata-Token: $TOKEN" http://169.254.169.254/v1/network

ipv4.public: xxx.144.221.113/32
ipv6.link_local: fe80::xxxx:xxxx:xxxx:b519/128
ipv6.slaac: 2600:xxxx::xxxx:xxxx:fe57:b519/128
```

構築時に設定されたUser dataの情報を確認することができます。

```bash
curl -s -H "Metadata-Token: $TOKEN" http://169.254.169.254/v1/user-data | base64 --decode
```

## Terraformにてcloud-initを利用する

Terraformにてcloud-initを利用して、初期構築すべてを自動化することも可能です。
利用する際にはproviderのバージョンがlinode v2.5.2以上である必要があります。

https://github.com/linode/terraform-provider-linode/releases/tag/v2.5.2

cloud-initが利用する設定ファイルを用意し、それに対応するmetadataのセクションをlinode_instance内に追加することで、Terraformから利用できます。

```terraform:instance.tf
resource "linode_instance" "meta" {
  label = "metadata-test"
  image = var.web.image
  region = var.region
  type = var.web.type
  authorized_keys = ["${chomp(file(var.public_ssh_key))}"]
  # Metadataの設定
  metadata {
      user_data = base64encode(file("cloud-init.yml"))
  }

  group = var.web.group
  swap_size = 256
  root_pass = random_string.password.result
}
```

## デバッグについて

cloud-initまたはUserdataで問題が発生した場合には、以下のファイルにログが出力されますので、内容を確認し原因を特定していくことが可能です。

```
cat /var/log/cloud-init.log
cat /var/log/cloud-init-output.log
```

# まとめ

Metadata serviceを利用することで、構築の自動化がより一層簡単に行えるようになりました。
ぜひ、この機能を活用してインフラ構築の手間を削減してみてはいかがでしょうか。

# 関連記事

アカマイ・テクノロジーズ合同会社はQiitaでAkamai's cloud computing services関連など開発者向けの記事を掲載しております。

https://qiita.com/xenbase/items/52e2956a64cedc772bd9