diadia

興味があることをやってみる。自分のメモを残しておきます。

基本の基本 EC2にssh接続する(復習)

コンテンツ

  1. マネージドコンソールを使ってEC2を立ち上げ、SSH接続を行う
  2. TERRAFORMから同じことを実現させる

一番最初の基本形としてEC2インスタンスを立ち上げて、ssh接続するまでをマネージドコンソールでどのようにセッティングすればよいかメモしておく。

手順

  1. VPC領域を決める
  2. VPC領域内に存在させるサブネットを作成する
  3. インターネットゲートウェイを作成し、VPCにアタッチする
  4. ルートテーブルを作成し、サブネットにアタッチする。ルートテーブルには作成したインターネットゲートウェイをアタッチする。
  5. セキュリティグループを作成し、sshのポートを開けておく。
  6. 最後にec2のインスタンスを作成する。この際に上記で作成したものがきちんと使用されているか注意する。またパブリックIPの確保も気をつける。

相関関係

要素 割り当てる、アタッチ対象
サブネット VPC
インターネットゲートウェイ VPC
ルートテーブル サブネット
セキュリティグループ EC2インスタンス
要素 何を設定スべき
VPC ネットワークの構成
サブネット サブネットの領域
ルートテーブル インターネットに接続したい場合はこちらにインターネットゲートウェイの情報を登録する
セキュリティグループ IPとポートを制限しているが、sshやhttp,DBの接続用にポートを開けること考えなければならない。

参考資料

【AWS EC2 エラー】ssh port 22 Operation timed out - Qiita

AWS EC2でパブリックDNS/IPが割り当てられない - huamutouの日記

pingで通信ができるようにする(補足)

さくらVPScentosでは特にicmpプロトコル(PINGが使うプロトコル)に関わるファイアウォールを設定しなくてもpingを通すことができた。 しかしec2の場合はicmpのポートを開けなければ、pingが使えない。セキュリティグループのインバウンドにおいてicmpを開けておく設定をしておくこと。

本題terraformで実行するとどうなるのか??

ちょうどやりたいことが以下の説明にあった。
AWSをテラフォーミングする会(Terraformハンズオン)

*注意点 上記の資料は結構昔のものなんだけれども、terraformは下方互換性がない。したがって自分のバージョンは0.12.5なんだけれども、このバージョンでは動かなかった。

修正点を以下に記す。

tags {} ではなくtags = {}と記述する

他にも良い記事があった。

SSHでアクセスできるEC2インスタンスを構築する - togatttiのエンジニアメモ

TerraformでVPC・EC2インスタンスを構築してssh接続する - Qiita

terraformで実現するための留意点

マネージドコンソールを使ってEC2を立ち上げる場合を考えてみると、EC2インスタンスを生成する時に.pemダウンロードすることになる。正確に言えば、新しい.pemをダウンロードするか、既存の.pemをec2インスタンスに登録する。そして、この.pemを使ってssh接続することになる。

そしてterraformを使ってec2を立ち上げるときのことを考えるとどうだろうか。 ec2を立ち上げるときに.pemをブラウザを通してダウンロードする事ができるだろうか。まずCUIで操作するのでそんな事は考えられない。したがってマネージドコンソールで自動的に行われていた.pemに関する作業は、自分で行わなければならないことがわかるだろう。

したがってマネージドコンソールで色んな要素を作成してEC2を組み立てること + ssh接続に関する設定を加えると想像することは明らかだ。以下の作業ではssh接続するためのkeyを生成すること、ec2に当該公開鍵を登録する操作ec2インスタンスを立ち上げる作業に加えている。

手順(全体)

  1. terraformを使えるようにセットアップする
  2. ディレクトリを準備する
  3. sshで接続するためのkeyを生成する
  4. ファイルを作成する
  5. terraform applyでec2を立ち上げssh接続を行う

terraformを使えるようにセットアップする

特に説明事項はない。brewでインストールして使う。

ディレクトリを準備する

$ mkdir example

sshで接続するためのkeyを生成する

$ cd example
$ ssh-keygen -t rsa -f id_rsa_ec2

ファイルを作成する

$ mkdir ec2_ssh
$ cd ec2_ssh
$ touch ec2.tf
$ vi  ec2.tf
# ec2_ssh/ec2.tfの内容

# EC2 Instance

resource "aws_instance" "example" {
  ami                    = "ami-0873b46c45c11058d"
  vpc_security_group_ids = [aws_security_group.example.id]
  subnet_id              = aws_subnet.example.id
  key_name               = "id_rsa_ec2" #EC2にKeyPairを登録
  instance_type          = "t2.micro"

  tags = {
    Name = "example"
  }
}


# Key Pair

resource "aws_key_pair" "example" {
  key_name   = "id_rsa_ec2"
  public_key = file("../id_rsa_ec2.pub") # 先程`ssh-keygen`コマンドで作成した公開鍵を指定
}
touch vpc.tf
# ec2_ssh/vpc.tfの内容


# VPC

resource "aws_vpc" "example" {
  cidr_block           = "10.0.0.0/16"
  enable_dns_support   = true # DNS解決を有効化
  enable_dns_hostnames = true # DNSホスト名を有効化

  tags = {
    Name = "example"
  }
}



# Subnet

resource "aws_subnet" "example" {
  cidr_block        = "10.0.1.0/24"
  availability_zone = "us-west-2a"
  vpc_id            = aws_vpc.example.id

  # trueにするとインスタンスにパブリックIPアドレスを自動的に割り当ててくれる
  map_public_ip_on_launch = true

  tags = {
    Name = "example"
  }
}




# Internet Gateway

resource "aws_internet_gateway" "example" {
  vpc_id = aws_vpc.example.id

  tags = {
    Name = "example"
  }
}



# Route Table

resource "aws_route_table" "example" {
  vpc_id = aws_vpc.example.id

  tags = {
    Name = "example"
  }
}

resource "aws_route" "example" {
  gateway_id             = aws_internet_gateway.example.id
  route_table_id         = aws_route_table.example.id
  destination_cidr_block = "0.0.0.0/0"
}

resource "aws_route_table_association" "example" {
  subnet_id      = aws_subnet.example.id
  route_table_id = aws_route_table.example.id
}



# Security Group

resource "aws_security_group" "example" {
  vpc_id = aws_vpc.example.id
  name   = "example"

  tags = {
    Name = "example"
  }
}

# インバウンドルール(ssh接続用)
resource "aws_security_group_rule" "in_ssh" {
  security_group_id = aws_security_group.example.id
  type              = "ingress"
  cidr_blocks       = ["0.0.0.0/0"]
  from_port         = 22
  to_port           = 22
  protocol          = "tcp"
}

# インバウンドルール(pingコマンド用)
resource "aws_security_group_rule" "in_icmp" {
  security_group_id = aws_security_group.example.id
  type              = "ingress"
  cidr_blocks       = ["0.0.0.0/0"]
  from_port         = -1
  to_port           = -1
  protocol          = "icmp"
}

# アウトバウンドルール(全開放)
resource "aws_security_group_rule" "out_all" {
  security_group_id = aws_security_group.example.id
  type              = "egress"
  cidr_blocks       = ["0.0.0.0/0"]
  from_port         = 0
  to_port           = 0
  protocol          = "-1"
}

terraform applyでec2を立ち上げssh接続を行う

terraform apply
# yesを実行する
# EC2が立ち上がったら
# インスタンスのパブリックIPをチェックする

ssh -i id_rsa_ec2 ec2-user@インスタンスのパブリックIP
#EC2インスタンスを破棄する
terraform destroy