【EC2】新しい鍵を作らずにAlmaLinux9のAMIを作る

# はじめに
[前回](https://qiita.com/vidil/items/d31827f952cdf676a9a8)コンソールが使える環境(オンプレ)におけるAlmalinux9の勘所を紹介した。
ただこれがクラウドサービス(今回の場合はEC2)になると今度は別の問題が発生してくる。
今回はその問題を解決しつつ前回とおなじOSの違いを気にせず使える環境を作るというところやっていこうと思う。
本当はRundeckと連携させた発展形まで考えているがそれだと詰込みすぎなので次回にする予定。
今回の状態としてはAWSをすでに利用していてCentOS6,7が乱立しているところにAlmalinux9を立てるという想定。
相変わらずニッチ。いやニッチでもないのか？

# そもそもの話
では実際にAlmalinux9でEC2のインスタンスを立てる事を考えてみたい。
そこで諸兄は一つ問題が発生することに気付くだろう。(聡明な方は最初から)

**EC2は認証が鍵認証。**
**そしてAlmalinux9は既存のRSA鍵が使えない。**
**結果**

#### 「え？一回しか使わないキーペアつくるの！？」
となる。

まぁ最終的に使うようなるのであろうがそれは何年も先だしそのころには誰もアクセスキーとか覚えていないだろう。
なので新しい鍵は作らずにどうすればいいかと3秒ほど悩んだ。
そしてpackerを使うことにした。

# packerとは
検索していただければ記事はたくさん出てくるが結構微妙な知名度だと思っている。
使う人は日常的に使うが使わない人は一切使わない的な。
ここでは「EC2のAMIを作るツール」とひとまず理解いただければ問題ない。
(packerについてちゃんと調べたい方は先述の通り検索してみてください)

# packerのインストール
### IAM作成
実際にpackerをインストールする前にAWSのIAMポリシーが必要となる。
以下のポリシーを作成の上、適当なユーザにアタッチしておく。

```ruby:Packer用ポリシー
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ec2:AttachVolume",
                "ec2:AuthorizeSecurityGroupIngress",
                "ec2:CopyImage",
                "ec2:CreateImage",
                "ec2:CreateKeypair",
                "ec2:CreateSecurityGroup",
                "ec2:CreateSnapshot",
                "ec2:CreateTags",
                "ec2:CreateVolume",
                "ec2:DeleteKeyPair",
                "ec2:DeleteSecurityGroup",
                "ec2:DeleteSnapshot",
                "ec2:DeleteVolume",
                "ec2:DeregisterImage",
                "ec2:DescribeImageAttribute",
                "ec2:DescribeImages",
                "ec2:DescribeInstances",
                "ec2:DescribeInstanceStatus",
                "ec2:DescribeRegions",
                "ec2:DescribeSecurityGroups",
                "ec2:DescribeSnapshots",
                "ec2:DescribeSubnets",
                "ec2:DescribeTags",
                "ec2:DescribeVolumes",
                "ec2:DetachVolume",
                "ec2:GetPasswordData",
                "ec2:ModifyImageAttribute",
                "ec2:ModifyInstanceAttribute",
                "ec2:ModifySnapshotAttribute",
                "ec2:RegisterImage",
                "ec2:RunInstances",
                "ec2:StopInstances",
                "ec2:TerminateInstances"
            ],
            "Resource": "*"
        }
    ]
}
```

### packerインストール
[公式](https://developer.hashicorp.com/packer/downloads)の記載そのままでOK。
ただし慣れてない人だと「Centos/RHEL」の手順に行きづらいと思うので油断しないこと。
```ruby:packerインストール
 sudo yum install -y yum-utils
 sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
 sudo yum -y install packer
```

### バグ？
申し遅れたが今回AlmaLinux9の環境でインストールしている。(本末転倒ではあるが時間的コストの関係でご容赦頂きたい。)
他の環境で発生するかは不明だが念のため記載しておく。
上述のpackerインストール後コマンドが動かないので確認したところ以下のようになっていた。

```ruby:バグ？
[root@ip-192-168-0-205 ~]# whereis packer
packer: /usr/bin/packer /usr/sbin/packer
[root@ip-192-168-0-205 ~]# ls -l /usr/sbin/packer
lrwxrwxrwx 1 root root 15 Nov 20 06:38 /usr/sbin/packer -> cracklib-packer
```

cracklib-packerってだれ？

```ruby:解決
[root@ip-192-168-0-205 ~]# rm -rf /usr/sbin/packer
[root@ip-192-168-0-205 ~]# ln -s /usr/bin/packer /usr/sbin/packer
```

これで解決。
もしほかの環境でも同じ事象は発生した際に参考になれば。

そしてここまででAMIを作る準備が完了した。

# AMI作成
packerはAnsibleのような複雑なディレクトリ構成もできるが今回は簡単に以下の1ファイルで作成する。
置き場所は適当なディレクトリでOK。

```ruby:test.json
{
  "builders": [
    {
      "type": "amazon-ebs",
      "ami_name": "AlmaLinux9-{{isotime | clean_resource_name}}",
      "temporary_key_pair_type": "ed25519",
      "access_key": "XXXXXXXXXXXXXXXXXXXXXXXXX",
      "secret_key": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
      "region": "ap-northeast-1",
      "source_ami": "ami-0c376282479945650",
      "instance_type": "t3.micro",
      "vpc_id": "vpc-093046de5a854c9c5",
      "ssh_username": "ec2-user",
      "security_group_ids": [
        "sg-03179fefab86413aa"
      ],
      "subnet_id": "subnet-095c2be997f1ffc36",
      "associate_public_ip_address": true
    }
  ],
      "provisioners": [
  {
      "type": "shell",
      "inline": [
      "sudo update-crypto-policies --set DEFAULT:SHA1",
      "sudo su -c\"echo PubkeyAcceptedAlgorithms=+ssh-rsa >> /etc/ssh/sshd_config\"",
      "sudo sed -i \"s/=enforcing/=disabled/\" /etc/selinux/config"
       ]
  }
 ]
}
```

6行目`"temporary_key_pair_type": "ed25519",`が本体。
packerはインスタンス起動後→自前の鍵で認証→操作→AMI作成という動きをする。
`temporary_key_pair_type`の設定によりAlmalinux9で使える鍵を自前で作成して認証してくれる。
わざわざ手元で鍵を作る必要がないのである。

#### わざわざ手元で鍵を作る必要がないのである。
大事なことのなので2回書いた。

ちなみに`access_key`と`secret_key`さすがに伏せた。
それぞれのお手元のアクセスキーを設定していただきたい。
ちなみに当然ではあるが作成されたAMIからインスタンスを作成するときに改めてキーペアは設定できる。
このためこの時点で手元の鍵を設定する必要はない。
あとここまで書いていなかったがAWS版のAlmaLinux9はfirewalldは無効化されているため、`systemctl disable firewalld`は入れていない。

この状態で以下を実行するとAMIができる。
`packer validate test.json`については`Template validated successfully.`みたいなメッセージが返るらしいが私の環境ではでなかった。
とりあえずエラー吐かなければ`packer build test.json`は実行してよさそう。

```ruby:AMI作成
packer validate test.json
packer build test.json
```

# 新しい鍵を作らずにAlmalinux9のAMIでインスタンスを作る。

というわけで出来上がったAMIでインスタンスを立ててみる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1092362/7d2c61fb-8c87-47e4-ff3e-9008f5ad1fb9.png)

先述した通りAMIからインスタンスを立てる際に改めてキーペアを指定できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1092362/0a013a33-fa24-1d5e-4883-dd0fa0560913.png)

無駄にスクリーンショット貼り付けてもあれなので軽くログを流して終わろうと思う。

```ruby:ログ
[ec2-user@ip-192-168-0-78 ~]$ more /etc/redhat-release
AlmaLinux release 9.1 (Lime Lynx)
[ec2-user@ip-192-168-0-78 ~]$ getenforce
Disabled
[ec2-user@ip-192-168-0-78 ~]$
```

- 旧来のRSA鍵でログインできている。
- ちゃんとAlmalinux9である。
- selinuxはちゃんと無効になっている。
- firewalldは・・・まぁね無効になっているからね。

というわけで課題解決＆タイトル回収である。

#### 私は久しぶりに勝利した！


# あとがき
最近負けが込んでいたがここにきて勝利を飾ることができた。
ネタがなくても絞り出してみるものである。
実はpackerはいつかネタにしたいと思いつつ単体では冗長なので扱いに困っていた。
今回AlmaLinux9を呼び水にして形にできたのは大変によかったと思っている。
ちなみに私はAlmaLinuxの回し者ではない。
今後rockeyLinuxその他が権勢を誇れば簡単に宗旨替えするくらいプライドはない。
次回は冒頭で記載したとおり発展形としてRundeckと連携させた仕組みを一つ作ろうと思う。
きっとすぐに書く多分。ネタが急につまり始めた。