aws-sdk gem で Amazon Lightsailを試す（１）

2016年12月1日にリリースされた[Amazon Lightsail](https://amazonlightsail.com/)に
[aws-sdk](https://rubygems.org/gems/aws-sdk)がはやくも対応していたので早速使ってみます。

### Lightsail?

ここにきてEC2より手軽に使えるVPSサービス登場ですね。

EC2もVPSのように紹介されることがありましたが、Route53をはじめとする複数のサービスを組み合わせていろいろなことができる分、技術者以外には扱いづらいものでした。

Lightsailの登場により敷居がぐっと低くなりそうですし、技術者にとっても「Redmine」「GitLab」「Wordpress」など急に必要になったときぱぱっと用意できてとても便利に使えそうです。

[Amazon Lightsail – AWSの力、VPSの簡単さ | Amazon Web Services ブログ](https://aws.amazon.com/jp/blogs/news/amazon-lightsail-the-power-of-aws-the-simplicity-of-a-vps/)

## インストール

### Gem

```sh
$ gem install aws-sdk -v 2.6.30
```

または

```sh
$ vi Gemfile
```

```ruby
# frozen_string_literal: true
source 'https://rubygems.org'

gem 'aws-sdk', '~> 2.6', '>= 2.6.30'

```

```sh
$ bundle install
```

### AWSのアクセスキー

`aws configure`コマンドでアクセスキーなどを設定しておくとRuby側で特に設定せずに試せるので楽です。

[AWS CLI のインストールと設定](http://docs.aws.amazon.com/ja_jp/streams/latest/dev/kinesis-tutorial-cli-installation.html)

```sh
$ aws configure
```

または環境変数で与える

```sh
$ export AWS_ACCESS_KEY=xxxxxxxxxxxxxx
$ export AWS_SECRET_KEY=yyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
$ export AWS_REGION=us-east-1
$ bundle exec ruby ....
```


## 起動してみる

### インスタンス作成

[Aws::Lightsail::Client#create_instances](http://docs.aws.amazon.com/sdkforruby/api/Aws/Lightsail/Client.html#create_instances-instance_method)を使います。

今回はLAMP環境がインストールされたVPSを3台ほど作ってみます。

```ruby
resp = lightsail.create_instances(
  instance_names: %w(vps1 vps2 vps3),
  availability_zone: 'us-east-1a',
  blueprint_id: 'lamp_5_6_27',
  bundle_id: 'nano_1_0',
)
pp resp.operations
```

[管理画面](https://lightsail.aws.amazon.com/ls/webapp/home/resources)を見てみると、確かに追加されていました。

![create_instances.PNG](https://qiita-image-store.s3.amazonaws.com/0/7000/adafb266-6cc1-87be-3b49-801495403f47.png)

#### Blueprint IDの取得

`create_instances`に渡す`blueprint_id`は[Aws::Lightsail::Client#get_blueprints](http://docs.aws.amazon.com/sdkforruby/api/Aws/Lightsail/Client.html#get_blueprints-instance_method)で得られます。

```ruby
resp = lightsail.get_blueprints
pp resp.blueprints.map(&:blueprint_id)
# => ["amazon_linux_2016_09_0", "ubuntu_16_04", "wordpress_4_6_1", "lamp_5_6_27", "nodejs_6_9_1", "joomla_3_6_3", "magento_2_1_2", "mean_3_2_10", "drupal_8_2_1", "gitlab_8_12_6", "redmine_3_3_1", "nginx_1_10_2"]
```

青写真という通り基本的な構築計画のようですね。


##### Bundle IDの取得

`create_instances`に渡す`bundle_id`は[Aws::Lightsail::Client#get_bundles](http://docs.aws.amazon.com/sdkforruby/api/Aws/Lightsail/Client.html#get_bundles-instance_method)で得られます。

```ruby
resp = lightsail.get_bundles
p resp.bundles.map(&:bundle_id)
# => ["nano_1_0", "micro_1_0", "small_1_0", "medium_1_0", "large_1_0"]
```

料金プランですね。

[Lightsail Pricing: $5 Virtual Private Servers from AWS](https://amazonlightsail.com/pricing/)


### 起動状態の確認

`running`になったら使えるみたいです。起動はとても速い印象でした。

```ruby
resp = lightsail.get_instance_state(
    instance_name: 'vps1'
)
p resp.state
# => #<struct Aws::Lightsail::Types::InstanceState code=16, name="running">
```

### インスタンスの確認

もっと詳しい情報は取得[get_instance](http://docs.aws.amazon.com/sdkforruby/api/Aws/Lightsail/Client.html#get_instance-instance_method)でできます。

```ruby
resp = lightsail.get_instance(
    instance_name: 'vps1'
)
pp resp.instance
=begin
#<struct Aws::Lightsail::Types::Instance
 name="vps1",
 arn=
  "arn:aws:lightsail:us-east-1:764044168140:Instance/1eb1f2d7-d6b0-40ce-a023-XXXXXXXXXXXX",
 support_code="775094070140/i-XXXXXXXXXXXXXXXXX",
 created_at=2016-12-01 21:56:57 +0900,
 location=
  #<struct Aws::Lightsail::Types::ResourceLocation
   availability_zone="us-east-1a",
   region_name="us-east-1">,
 resource_type="Instance",
 blueprint_id="lamp_5_6_27",
 blueprint_name="LAMP Stack",
 bundle_id="nano_1_0",
 is_static_ip=false,
 private_ip_address="172.XX.XX.XXX",
 public_ip_address="54.XXX.XXX.XX",
 ipv6_address=nil,
 hardware=
  #<struct Aws::Lightsail::Types::InstanceHardware
   cpu_count=1,
   disks=nil,
   ram_size_in_gb=0.5>,
 networking=
  #<struct Aws::Lightsail::Types::InstanceNetworking
   monthly_transfer=
    #<struct Aws::Lightsail::Types::MonthlyTransfer
     gb_per_month_allocated=1000>,
   ports=
    [#<struct Aws::Lightsail::Types::InstancePortInfo
      from_port=80,
      to_port=80,
      protocol="tcp",
      access_from="Anywhere (0.0.0.0/0)",
      access_type="public",
      common_name="",
      access_direction="inbound">,
     #<struct Aws::Lightsail::Types::InstancePortInfo
      from_port=22,
      to_port=22,
      protocol="tcp",
      access_from="Anywhere (0.0.0.0/0)",
      access_type="public",
      common_name="",
      access_direction="inbound">,
     #<struct Aws::Lightsail::Types::InstancePortInfo
      from_port=443,
      to_port=443,
      protocol="tcp",
      access_from="Anywhere (0.0.0.0/0)",
      access_type="public",
      common_name="",
      access_direction="inbound">]>,
 state=#<struct Aws::Lightsail::Types::InstanceState code=16, name="running">,
 username="bitnami",
 ssh_key_name="LightsailDefaultKeyPair">
=end
```


### 接続情報の取得

起動したインスタンスへのSSH接続情報もAPIで取得できます。

#### SSH

鍵もとれます。

```ruby
resp = lightsail.get_instance_access_details(
  instance_name: 'vps1'
)
pp resp.access_details
=begin
#<struct Aws::Lightsail::Types::InstanceAccessDetails
 cert_key=
  "ssh-rsa-cert-v01@openssh.com 共有鍵",
 expires_at=nil,
 ip_address="XXX.XXX.XXX.XXX",
 password=nil,
 private_key=
  "-----BEGIN RSA PRIVATE KEY-----\n秘密鍵\n-----END RSA PRIVATE KEY-----\n",
 protocol="ssh",
 instance_name="vps1",
 username="bitnami">
=end
```

#### RDP

ドキュメントによると`protocol: 'rdp'`を指定できるようです。試した環境では意味が無かったですが、使えるケースもあるのでしょうか？

```ruby
resp = lightsail.get_instance_access_details(
  instance_name: 'vps1',
  protocol: 'rdp'
)
pp resp.access_details
```

### ブラウザでアクセス


`get_instance`の`public_ip_address`や`get_instance_access_details`の`ip_address`にブラウザでHTTPアクセスすると、先ほど選択したLAMP環境のページが表示されました。

![browser.png](https://qiita-image-store.s3.amazonaws.com/0/7000/e8bb9037-a19b-b707-1d36-bf41743bdfd6.png)

### インスタンスの停止

[stop_instance](http://docs.aws.amazon.com/sdkforruby/api/Aws/Lightsail/Client.html#stop_instance-instance_method)で停止できます。

```ruby
resp = lightsail.stop_instance(
   instance_name: instance_name
)
pp resp.operations
```

停止が完了したら`stopped`になります。

```ruby
p lightsail.get_instance_status(instance_name: 'vps1').status
#<struct Aws::Lightsail::Types::InstanceState code=64, name="stopping">
p lightsail.get_instance_status(instance_name: 'vps1').status
#<struct Aws::Lightsail::Types::InstanceState code=80, name="stopped">
```

### インスタンスの再開

停止したインスタンスは[start_instance](http://docs.aws.amazon.com/sdkforruby/api/Aws/Lightsail/Client.html#start_instance-instance_method)で再開できます。

```ruby
resp = lightsail.start_instance(
   instance_name: 'vps1'
)
pp resp.operations
```


## 次回

運用していく上でとてもありがたい存在のスナップショットまわりを試してみようと思います。