`aws-cli` を使ってコマンドラインからAWS EC2とVPCを構築する

2019-03-30Amazon, AWS, Bash, SSH

はじめに

AWS Transfer for SFTP の価格があまりにも高すぎたため、 EC2 上に SFTP サーバを構築することにしました。

今までは VPCインターネットゲートウェイ を使わずに EC2 作成をしていたため、これらを導入した場合の手順を整理してみました。

準備

  • aws-cli コマンドが利用できること
  • jq コマンドが利用できること

ja はなくてもいいが、今回各AWS構成要素を作成した際のJSONレスポンスをパースしてできる限りコマンドラインのみの操作としたかったので利用しました。

検証環境

$ uname -moi
x86_64 MacBookPro10,1 Darwin

$ bash -version
GNU bash, バージョン 5.0.2(1)-release (x86_64-apple-darwin18.2.0)

$ aws --version
aws-cli/1.16.110 Python/3.7.2 Darwin/18.2.0 botocore/1.12.100

ネットワーク周りの設定

VPCの作成

# VPCの新規作成 => 作成されたVPCのIDを保存
$ EC2_VPC_ID=$(
  aws ec2 create-vpc \
    --cidr-block '172.20.0.0/16' \
    | jq -r '.Vpc.VpcId'
)

## 確認
$ echo "${EC2_VPC_ID}"

Subnetの作成

# Subnetの新規作成 => 作成されたSubnetのIDを保存
$ EC2_SUBNET_ID=$(
  aws ec2 create-subnet \
    --cidr-block '172.20.0.0/16' \
    --vpc-id "${EC2_VPC_ID}" \
    | jq -r '.Subnet.SubnetId'
)

## 確認
$ echo "${EC2_SUBNET_ID}"

インターネットゲートウェイの作成

# インターネットゲートウェイの新規作成 => 作成されたインターネットゲートウェイのIDを保存
$ EC2_INTERNET_GATEWAY_ID=$(
  aws ec2 create-internet-gateway \
    | jq -r '.InternetGateway.InternetGatewayId'
)

## 確認
$ echo "${EC2_INTERNET_GATEWAY_ID}"

VPCへインターネットゲートウェイを割り当てる

$ aws ec2 attach-internet-gateway \
  --internet-gateway-id "${EC2_INTERNET_GATEWAY_ID}" \
  --vpc-id "${EC2_VPC_ID}"

ルートテーブルの設定

インターネットゲートウェイ経由でVPCへアクセスできるようにします。

# VPCに割り当てられたルートテーブルのIDを取得 => 作成されたルートテーブルのIDを保存
$ EC2_ROUTE_TABLE_ID=$(
  aws ec2 describe-route-tables \
    | jq -r '.RouteTables[]| .Associations[0].RouteTableId+","+.VpcId' \
    | grep "${EC2_VPC_ID}" \
    | sed 's/,.*$//'
)

## 確認
$ echo "${EC2_ROUTE_TABLE_ID}"

ルートテーブルの設定だけ、どうしてもコマンドラインから設定する方法を見つけられず、GUIから設定を行いました。



設定は以下のコンソールページから行いました。

※ここまでやって、やっとネットワーク周りの設定が終了。引き続きEC2の設定を行います。

EC2関連の設定

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

  • SSH(SFTP)用に 22 番ポートのみを開放したセキュリティグループを作成します。
# まずはからのセキュリティグループを作成
$ EC2_SECURITY_GROUP_ID=$(aws ec2 create-security-group \
  --description 'g-sftp-server-sg' \
  --group-name 'g-sftp-server-sg' \
  --vpc-id "${EC2_VPC_ID}" | jq -r .GroupId)

## 確認
$ echo "${EC2_SECURITY_GROUP_ID}"

# 22番ポートでのアクセスを許可する
$ aws ec2 authorize-security-group-ingress \
  --group-id "${EC2_SECURITY_GROUP_ID}" \
  --cidr '0.0.0.0/0' \
  --port 22 \
  --protocol tcp

SSH Keyの登録

  • EC2 に接続するときに利用するSSH-KEYの登録を行います。
# ここではすでに作成されている公開鍵を登録してる。未作成の場合には事前に作成しておく!
$ aws ec2 import-key-pair \
  --key-name "g-sftp-server-key" \
  --public-key-material "file://$HOME/.ssh/id_rsa.pub"

AWS EC2の起動

  • スペックはそんなに高機能なものは不要だと思っているので t3.small で。
  • AMI は CentOS7 を使う ( ami-Id = ami-045f38c93733dd48d )
$ EC2_IMAGE_ID="ami-045f38c93733dd48d"
$ EC2_INSTANCE_TYPE="t3.small"
$ KEY_NAME='g-sftp-server-key'
$ EC2_INSTANCE_NAME='g-sftp-server'
$ EC2_INSTANCE_ID=$(aws ec2 run-instances \
  --image-id "${EC2_IMAGE_ID}" \
  --instance-type "${EC2_INSTANCE_TYPE}" \
  --security-group-ids "${EC2_SECURITY_GROUP_ID}" \
  --key-name "${KEY_NAME}" \
  --subnet-id "${EC2_SUBNET_ID}" \
  --tag-specifications="ResourceType=instance,Tags=[{Key=Name,Value=${EC2_INSTANCE_NAME}}]" | jq -r '.Instances[0].InstanceId'
)

$ echo ${EC2_INSTANCE_ID}

ElasticIPの割当

  • 固定IPを割り当てて、外部からアクセスできるようにします。
$ EC2_EIP_ID=$(
  aws ec2 allocate-address \
    --domain vpc \
    | jq -r '.AllocationId'
)

## 確認
$ echo "${EC2_EIP_ID}"

# EC2インスタンスに固定IPを割り当てる
$ aws ec2 associate-address \
  --instance-id "${EC2_INSTANCE_ID}" \
  --allocation-id "${EC2_EIP_ID}"

# 接続用のパブリックIPを取得
$ PUBLIC_IP_ADDRESS=$(
  aws ec2 describe-instances \
    --instance-ids="${EC2_INSTANCE_ID}" \
    | jq -r '.Reservations[0].Instances[0].NetworkInterfaces[0].Association|.PublicIp'
)
$ echo "${PUBLIC_IP_ADDRESS}"

接続

設定が正しく行われていれば、以下のコマンドでsshログインできます。

$ ssh -i ~/.ssh/id_rsa centos@"${PUBLIC_IP_ADDRESS}"

ゴミ掃除

検証が終わったので、今回作ったものを全て削除します。

実行されたコマンドが反映されるまでに多少のタイムラグがあるため、気持ちsleepさせてきましょう。

# 停止まで数分かかる
aws ec2 terminate-instances \
  --instance-ids "${EC2_INSTANCE_ID}"
sleep 60

aws ec2 release-address \
  --allocation-id ${EC2_EIP_ID}
sleep 3

aws ec2 delete-security-group \
  --group-id "${EC2_SECURITY_GROUP_ID}"
sleep 3

aws ec2 delete-internet-gateway \
  --internet-gateway-id "${EC2_INTERNET_GATEWAY_ID}"
sleep 3

aws ec2 delete-subnet \
  --subnet-id ${EC2_SUBNET_ID}
sleep 3

aws ec2 delete-route-table \
  --route-table-id "${EC2_ROUTE_TABLE_ID}"
sleep 3

aws ec2 delete-vpc \
  --vpc-id "${EC2_VPC_ID}"
sleep 3

ひとこと

  • 今回は VPCインターネットゲートウェイ の設定から行ったが、こちらの設定がすでに存在している場合には既存のものを流用できます。
  • 各コマンド実行結果にタグを付与できていないので、その点が今後の課題です(汗)。

2019-03-30Amazon, AWS, Bash, SSH