【AWS】EC2インスタンスを作る方法3つ【AWSコンソール/AWS CLI/Terraform】

AWS, サーバーサイド, 便利ツール

AWSのEC2インスタンスを作る方法はいくつかあります。
コンソールでポチポチ操作するのが直感的で簡単なのですが、これを繰り返し行ったり複数人で行ったりすると、手作業なのでミスが起きたり手間になったりの原因になります。

コンソールでの作成方法をベースに、CLIとTerraformでの作成方法の違いを見ていきたいと思います。

AWS CLIはコマンドベースでAWSコンソールの操作ができるもの。Terraformは設定ファイルを作っておけば勝手に全部やってくれるもの。らしい。

前提

  • 解説で使用しているOS mac OS 10.15.3
  • AWSアカウント、IAMユーザー作成済
  • ACCESS_KEY_ID, SECRET_ACCESS_KEY発行済(参考:AWSアクセスキー作成 – Qiita

※ 僕も初心者なので間違ってるところもあるかもしれませぬが、どうかご容赦を。

『AWSコンソール』からのEC2インスタンス作成

まずはインスタンスを作成するアカウントでログインし、ダッシュボードを開きます。

キーペアの作成

いきなりインスタンスを作り始める前に、ログイン情報を暗号化するために、プライベートキーを使って安全にインスタンスにアクセスできるようにします。

  1. ダッシュボード>キーペア>Create key pair
  2. Nameを指定し、pemを選択してCreate key pair

ダウンロードされた.pemファイルはインスタンスを作るときに使います。
~/.ssh/aws_key.pem など、適当な場所と名前で保存します。

セキュリティグループの作成

セキュリティグループというのはAWSのファイアウォール機能で、受信(インバウンド)と送信(アウトバウンド)の規則を設定できます。(公式ドキュメント
OSに到達する前にネットワークレベルでバケットをフィルタリングできるので、EC2やRDSなど様々なリソースと紐付けるのに使います。

  1. ダッシュボード>セキュリティグループ
  2. セキュリティグループの作成>インバウンド>ルールの追加

SSHで接続したいので、こんな感じで設定します。

  • タイプ:SSH
  • プロトコル:TCP(固定)
  • ポート範囲:22(固定)
  • ソース:カスタム、0.0.0.0/0
  • 説明: 適当に(日本語不可)

アウトバウンドはデフォルトで「全てのトラフィック」が入っていますが、そのままの設定で進みます。

インスタンスの作成

  1. ダッシュボード>インスタンス>インスタンスの作成

インスタンスの設定

  • AMI:Amazon Linux 2 AMI (HVM), SSD Volume Type
  • Type:t2.micro(無料利用枠の対象)
  • 詳細の設定:デフォルト
  • ストレージ:デフォルト
  • タグの追加:なし
  • セキュリティグループの追加:既存のセキュリティグループの追加>作成したセキュリティグループ
  • 既存のキーペアの作成>作成したキーペア名を選択

インスタンスを作成して、しばらくすると起動します。

EC2にSSHで接続

Terminalで次のようにキーペアとパブリックIPを指定してSSHでEC2にログインします。

$ ssh -i ~/.ssh/aws_key.pem -l ec2-user 00.00.00.00

-i の後には保存したキーペアのパス、ec2-userの後はインスタンス一覧の「IPv4 パブリックIP」を入力します。

接続ができると「Are you sure you want to continue connecting (yes/no)?(接続を続行しますか?)」と聞かれるのでyesと入力します。
見事、SSHで接続できるようになりました。

 

『AWS CLI』からのEC2インスタンス作成

AWS CLIはMacであればTerminalがあればコマンド打ち込むだけですが、awsコマンドを使うにはawscliのインストールが必要です。

$ pip install awscli

インストールしたら $ aws configure などで設定ファイルを作ってあげるんですが、長くなるのでここでは割愛。

基本的にコマンドは $ aws (サービス名) (コマンド) –(パラメータ名) (パラメータ) で記述します。パラメータに何を書いたらわからない場合はコンソールを見ると説明があったりします。

キーペアの作成

キーペアの一覧を表示する

$ aws ec2 describe-key-pairs

An error occurred (UnauthorizedOperation) when calling the DescribeKeyPairs operation: You are not authorized to perform this operation.

こんなエラーが出るときは、~/.aws/configか~/.aws/credentialsの設定が間違ってるかもです。

キーペアの作成

コンソールでいうとこの画面です。

$ aws ec2 create-key-pair \
--key-name aws_key \
--query 'KeyMaterial' \
--output text > ~/.ssh/aws_key.pem
  • –key-name キーペア名
  • –query ‘KeyMaterial’を指定すると「unencryptedでPEMエンコードされたRSA秘密鍵」を生成する
  • –output 保存するキーペアファイルのパス

パラメータが長くて見にくいので ‘\’ で改行してますが、1行でも実行できるし、このままコピペしても実行できます。

きちんと作成されたか確認

$ aws ec2 describe-key-pairs \
--key-name aws-key

作ったキーペア名で絞り込んで、ヒットすればきちんと作成されてます。

パーミッションの変更

$ chmod 400 ~/.ssh/aws_key.pem

セキュリティグループの作成

セキュリティグループの一覧を表示する

$ aws ec2 describe-security-groups

特にセキュリティグループを設定したことがない場合、デフォルトのグループが1つあるだけだと思います。

セキュリティグループの作成

コンソールだとこの画面です。

$ aws ec2 create-security-group \
--group-name SSHGroupTest \
--description "Test SSH access"
  • –group-name セキュリティグループ名
  • –description 説明
  • –vpc-id VPC(設定しなければデフォルト)

インバウンドルールの設定

$ aws ec2 authorize-security-group-ingress \
--group-id sg-00000000000000000 \
--protocol tcp \
--port 22 \
--cidr 0.0.0.0/0
  • –group-id 上で作成したセキュリティグループのID
  • –protocol プロトコル
  • –port ポート番号(SSHなら22番)
  • –cidr ソース

セキュリティグループが作成できたか確認

$ aws ec2 describe-security-groups \
--group-id sg-00000000000000000

インスタンスの作成

インスタンスの一覧を表示する

$ aws ec2 describe-instances \
--query "Reservations[].Instances[].{InstanceId:InstanceId}"

–queryでインスタンスIDだけを出すように絞っています。絞らないと大量の情報が出てきてしまうので。

インスタンスの作成

$ aws ec2 run-instances \
--image-id ami-011facbea5ec0363b \
--count 1 \
--instance-type t2.micro \
--key-name aws-key \
--security-group-ids sg-00000000000000000
  • –image-id AMIのID(下図の赤枠部分。describe-imagesコマンドで自分で作成することもできる)

  • –count 起動するインスタンス数
  • –instance-type インスタンスタイプ
  • –key-name キーペア名
  • –security-group-ids セキュリティグループID
  • –subnet-id サブネットID

これを実行すると即時インスタンスができて起動が始まります。

インスタンスができたか確認する

$ aws ec2 describe-instances \
--query "Reservations[].Instances[].{InstanceId:InstanceId}"

作成前の実行結果よりInstanceId(i-00000000000000000)が増えていればOK。

EC2にSSHで接続

方法と入力内容は2.4と同じです。

パブリックIPは以下で取得できます。

$ aws ec2 describe-instances \
--filters "Name=instance-id,Values=i-00000000000000000" \
--query "Reservations[].Instances[].NetworkInterfaces[].PrivateIpAddresses[].Association[].PublicIp"

 

『Terraform』からのEC2インスタンス作成

Terraform 0.12系を使って解説します。

準備(Terraformの設定)

コンソールとCLIは順番にやりたいことを実行していましたが、Terraformではファイルに「やることリスト」を記述してからコマンドを実行するだけで、一気にTerraformがやってくれます。

Terraformの簡単な操作と設定を踏まえてインスタンスを作成します。差分管理や変数定義などは今回割愛します。

Terraformのインストール

おきまり。Terraformをまずはインストールしてください。

$ brew install terraform

続いて、適当なディレクトリに「sg.tf」「main.tf」ファイルをそれぞれ作成します。

キーペアの作成

Terraformでもキーペアを作れるのですが、少し手順が増える(正直に言うとよくわからない)ので今回はコンソールかCLIで作っておき(2.2か3.2を参照)、「aws_key」というキーペアがある前提とします。

セキュリティグループの作成

sg.tf ファイルの作成

sg.tf」ファイルをエディタで開き、次のように入力して保存します。.tfファイルはHCLという言語で書きます。

# セキュリティーグループの定義
resource "aws_security_group" "test-sg" {
    name = "test-sg"
    description = "Test security group."
}

# インバウンド
resource "aws_security_group_rule" "test-ingress" {
    type = "ingress"
    from_port = 22
    to_port = 22
    protocol = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
    security_group_id = aws_security_group.test-sg.id
}

# アウトバウンド
resource "aws_security_group_rule" "test-ec2-all-out" {
  type = "egress"
  from_port = 0
  to_port = 0
  protocol = "-1"
  cidr_blocks = ["0.0.0.0/0"]
  security_group_id = aws_security_group.test-sg.id
}

細かい説明は省略しますが、ingressというのがインバウンドのルールで、egressがアウトバウンドのルールです。
設定内容は2.2、3.2と同じです。

もちろん、このファイルを作って保存しただけではセキュリティグループは作られませんが、一旦このまま進みます。

インスタンスの作成

main.tf ファイルの作成

次にsg.tfファイルと同じ階層に「main.tf」ファイルを作成します。

provider "aws" {
    region = "ap-northeast-1"
    profile = "test-role"
    assume_role {
        role_arn = "arn:aws:iam::00000000000000000:role/test-role"
    }
}

resource "aws_instance" "test-ec2" {
    ami = "ami-011facbea5ec0363b"
    key_name = "aws_key"
    instance_type = "t3.micro"
    tags={
        Name = "test-ec2"
    }
}

provider “aws”の部分にはEC2だけでなくAWSの様々なリソースで共通する認証情報や環境変数を設定できます。

provider “aws”
  • region(必須項目) AWSリージョン(ap-northeast-1は東京リージョン)
  • profile AWSプロファイル名
  • assume_role スイッチロールするロール名

resource “aws_instance”の部分に作成するインスタンスの情報をセットしていきます。
設定項目はTerraformの公式ドキュメントに詳しく載っていますが、必要最低限だけ記述しました。

aws_instance
  • ami(必須項目) AMIのID
  • key_name キーペア名
  • instance_type インスタンスタイプ
  • tags.name コンソール上で表示されるNameの部分

編集したら保存します。

terraform init の実行

Terminalなどでmain.tfがある階層に移動し、次のコマンドを実行します。

$ terraform init

Terraformの実行に必要なプロバイダ用のバイナリファイルをダウンロードしてきます。

Initializing the backend...
Terraform has been successfully initialized!
...

と表示されたら成功です。

terraform plan の実行

自分が作成したtfファイルを実行すると何が起こるかを表示します。
入力内容にエラーが有る場合、ここで判明します。

作成するインスタンスの情報(すでに作成済みインスタンスの場合は差分)がズラッと表示されます。
内容を確認し、エラーがなければapplyする準備は完了です。

terraform apply の実行

planの内容で問題がなければ実際にAWSに反映させるコマンドを打ちます。

$ terraform apply

planをしたときと同じ内容が表示され、本当に実行するか?と聞かれます。

...
  # aws_security_group_rule.test-ingress will be created
  + resource "aws_security_group_rule" "test-ingress" {
      + cidr_blocks              = [
          + "0.0.0.0/0",
        ]
      + from_port                = 22
      + id                       = (known after apply)
      + protocol                 = "tcp"
      + security_group_id        = (known after apply)
      + self                     = false
      + source_security_group_id = (known after apply)
      + to_port                  = 22
      + type                     = "ingress"
    }

Plan: 4 to add, 0 to change, 1 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value:  yes

「yes」と入力。どん!

Apply complete! Resources: 4 added, 0 changed, 1 destroyed.

と表示されたらインスタンス作成成功です。

EC2にSSHで接続

2.4、3.4と同じです。

$ ssh -i ~/.ssh/aws_key.pem -l ec2-user 00.00.00.00

接続できればTerraformでのインスタンス作成とSSH接続は完了です。

まとめ

一見難しそうなCLIとかTerraformも、覚えてしまえばそっちのほうが楽で確実というこの世の摂理。


参考文献