SDK for RubyでAWSの環境作ってみるよハンズオン

## 概要
コードでAWS環境を構築する、いわゆるInfrastructure as Code（Iac）と言えば**CloudFormation**や**Terraform**が主流ですが、主要なプログラミング言語でリソースの構築や操作ができるSDKがAWSからは提供されています。
そのSDKのうち今回はRubyを使って環境（VPC、IGW、Subnet、RouteTable）を構築するハンズオンを紹介したいと思います！
※作業環境はMacOS、SDK for Rubyのバージョン3になります

## おしながき
1. 事前準備
2. SDKのインストールと設定
3. コードを書いていく
4. どうやってコードを書いているのか？
5. 今後
6. まとめ

## 1.事前準備
### 必要なもの
- AWSアカウント 
いわずもがなですが、各リソースを起動させるためにAWSのアカウントが必要です。もう持ってるという前提で進めますのでご了承

- Ruby（バージョン1.9以降） 
これもいわずもがな…Rubyでコードを書いていきますので作業端末にインストールしてください。

### 参考サイト
[AWS SDK for Ruby Developer Guide](https://docs.aws.amazon.com/ja_jp/sdk-for-ruby/v3/developer-guide/welcome.html)
こちらの公式サイトにそってやっていきます。

## 2.SDKのインストールと設定
### SDKをインストールする  
SDK for Rubyはgemとして配布されています。Rubyの外部ライブラリですね。

- bundlerを使用している場合  
Gemfileに下記を追記して`bundle install`を実行する

```
gem 'aws-sdk'
```

- bundler使わない場合  
下記のコマンドを実行してgemをインストール

```
sudo gem install aws-sdk
```
※けっこう時間がかかります。5分くらいターミナル画面が止まったままになりますが、フリーズではありません。


### 認証情報の設定
SDK経由でAWSにアクセスするための認証情報をローカルファイルに記述します。場所は`~/.aws/credentials`です。

```
# ディレクトリを作成
mkdir ~/.aws

# 移動
cd ~/.aws

# vimでcredentialsファイルを編集
sudo vim credentials
``` 

vimで下記を記述します

```
[default]
aws_access_key_id = your_access_key_id
aws_secret_access_key = your_secret_access_key
```
※上記の`your_access_key_id`、`your_secret_access_key`にアクセスキー、シークレットアクセスキーを入力するため、一旦おいといて下の作業を進めます

### アクセスキー、シークレットアクセスキーを作成する
1. AWSマネジメントコンソールにログインします
2. マネジメントコンソールの右上のアカウント部分をクリック
3. ドロップダウンメニューから**「マイセキュリティ資格情報」**を選択  
<img width="500" alt="スクリーンショット 2020-02-22 16.22.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495631/9ccc89f2-57f2-2799-2ef0-513c456cee65.png">
4. 「セキュリティ認証情報」画面に移動したら**「アクセスキーの作成」**ボタンを押す  
※アクセスキーは1アカウントにつき2つまでしか作成できません。既に2つある場合は使っていないものを削除するなどしてください  
<img width="500" alt="スクリーンショット 2020-02-22 10.58.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495631/2d11c5e8-754a-37d0-48a1-d0be3a9b62c0.png">
5. 「アクセスキーの作成」ボタンを押して出てきたウインドウの情報をメモする  
※このウインドウは一旦閉じると2度とシークレットアクセスキーを見られなくなるので注意！もし閉じた場合は、作成したキーを削除してもう一度作成しなおしてください  
※画像のアクセスキーは削除してるので使えません あしからず（笑）  
<img width="500" alt="スクリーンショット 2020-02-22 10.57.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495631/008e6619-2fc3-3544-f5b7-935837b388d4.png">
6. vimに戻ってメモしたアクセスキーとシークレットアクセスキーの情報をそれぞれコピペする
7. `esc`キー => `:wq`で編集内容を保存してvimを閉じる

### 環境変数でリージョンを設定する
東京リージョンを使用するよう設定します

```
export AWS_REGION=ap-northeast-1
```

## 3.コードを書いていく
今回のゴールは**VPC**、**サブネット**、**インターネットゲートウェイ**、**ルートテーブル**を作るところまでです。出来上がったrbファイルを実行するだけでAWSリソースが立ち上がる！というハンディさを実感してもらうのが目的なのでひとまずここまでで。

```
# sdkをrubyファイルに読み込み
require 'aws-sdk'

# VPCなどはEC2のカテゴリなのでAws::EC2::Clientクラスからインスタンスを作成
client = Aws::EC2::Client.new(region: "ap-northeast-1")


# VPC ----------------------------------------------------------------
# VPCを作成 上で作成したclientインスタンスに対してcreate_vpc()メソッドを適用する
resp_vpc = client.create_vpc({
  cidr_block: "10.0.0.0/16", # 必須項目 IPアドレス範囲を指定する
})

# 出来上がったVPCのIDを取得（他のリソース作成時やアタッチする時に使用する）
VPC_ID = resp_vpc.vpc.vpc_id

puts VPC_ID


# IGW ----------------------------------------------------------------
# インターネットゲートウェイ（IGW）を作成
resp_igw = client.create_internet_gateway({
})

# IGWのID
IGW_ID = resp_igw.internet_gateway.internet_gateway_id

# IGWをVPCにアタッチ
client.attach_internet_gateway({
  internet_gateway_id: IGW_ID, # 上で作成したIGWのID 
  vpc_id: VPC_ID, # 上で作成したVPCのID 
})

puts IGW_ID


# Subnet ----------------------------------------------------------------
# サブネットを作成（インターネット向けパブリックサブネット）
resp_pubsub1 = client.create_subnet({
  availability_zone: "ap-northeast-1a",
  cidr_block: "10.0.0.0/24", # 必須項目
  vpc_id: VPC_ID, # 必須項目
})

# サブネットのID
SUB_ID1 = resp_pubsub1.subnet.subnet_id

puts SUB_ID1


# RouteTable ----------------------------------------------------------------
# ルートテーブルを作成
resp_rt = client.create_route_table({
  vpc_id: VPC_ID, # 必須項目
})

# ルートテーブルのID
RT_ID = resp_rt.route_table.route_table_id

# ルートを作成（IGWに向けたルート）
resp_route = client.create_route({
  destination_cidr_block: "0.0.0.0/0", # インターネット向けルート
  gateway_id: IGW_ID, # IGWのID
  route_table_id: RT_ID, # 必須項目 ルートテーブルのID
})

# ルートテーブルをサブネットに紐付け
client.associate_route_table({
  route_table_id: RT_ID, # 必須項目 ルートテーブルのID
  subnet_id: SUB_ID1, # 紐付けるサブネットのID
})

puts RT_ID


# まとめてリソースにタグ（名前）を追加 ----------------------------------------------------------------
client.create_tags({
  resources: [VPC_ID, IGW_ID, SUB_ID1, RT_ID], # 必須項目 名前をつけるリソースのID
  tags: [
    {
      key: 'Name',
      value: 'HogeTestVPC', # VPCの名前
    },
    {
      key: 'Name',
      value: 'HogeTestIGW', # IGWの名前
    },
    {
      key: 'Name',
      value: 'HogeTestPublicSubnet1a', # Subnetの名前
    },
    {
      key: 'Name',
      value: 'HogeTestPublicRT', # RTの名前
    },
  ],
})

puts "Create environment successfully done!"
```
適当なディレクトリに上記のコードを**.rbファイル**として保存して、`cd`コマンドで保存したディレクトリに移動。`ruby 保存したファイル名.rb`で実行するとリソースの作成がAWS上で始まります。

## 4.どうやってコードを書いているのか？
ひたすら下記の公式ドキュメントから該当するコードを引っ張ってきて、必要な要素を記述するだけです。ここが一番のツボというか、どのリソースに対して何をしたいのか？というのを考えてドキュメントから探し出すことさえ出来れば（書き方の良し悪しは置いておいて）リソースを操作するためのコードが書けるようになるはずです。

[AWS SDK for Ruby V3](https://docs.aws.amazon.com/sdk-for-ruby/v3/api/_index.html)

## 5.今後
**公式ドキュメントの読み方**や、**EC2やその他のリソースに関する記述方法**なども記事にしていけたらと考えています。また、今回はリソースを作成するだけでしたが、SDKの本領はプログラマブルなところで、書き方次第でAWSリソースを思い通りに操作することもできるみたいなので、そのへんも研究して記事にできたらいいなぁ、と思っています。

## 6.まとめ
ボク自身、ぜんぜんRubyやAWSに関しては初心者をようやく脱したかな？というレベルで、業務でSDK for Rubyを使うことになりました。思いの外、日本語での記事が少なく、四苦八苦しながら英語ドキュメントと戦って書いたので、同じようにSDKを使い始めようかという方の一助になればと思い記事を書きました。
また、SDKが提供されている言語を学習している方であれば、Gitでバージョン管理しつつGitHubに上げてポートフォリオとしてもいいかもな〜とか思いました。（CFnでもTerraformでもなくなぜSDK？ってツッコミには答えられるようにしたほうがいいかもですが笑…個人的にはSDKの方が学習コスト低いし、柔軟なリソース操作ができる可能性を感じます。）

最後に、掲載したコードはちゃんと走ることを確認していますが「書き方がなってない、もっとうまい書き方があるぞ」というコメントやご指摘などあれば、お手柔らかにお願いします(＞人＜;)