ENGINEER BLOG

ENGINEER BLOG

Amazon LightSailをシュッと作る

ごきげんよう、じんぐうじです。

社内でちょっとしたWordpress環境が欲しいと言われたので、
ならばLightSailでCloudFormationを使って楽しましょうね、と思ったら対応してませんでした。切ないですね。
ということでTerraformです。

やっていく

テンプレートファイルにクレデンシャルを書きたくないので、事前にAWS CLIでaws configureしてクレデンシャルを設定しておきます。
また、キーペアもローカルで作ってから公開鍵だけインポートするのでssh-keygen -t rsa -b 4096 -f ./id_rsaして作成しておきます。

バックエンドを作成

Terraformは状態管理のために*.tfstateというファイルを保持する必要があるのですが、
ローカルで保持したくないのでリモートに保管します(Backends)

今回はS3をバックエンドとして使用します。バックエンドはTerraformの管理対象外とするためCLIで作成しました。
また、複数人が同時に操作する場合はDynamoDBでロックファイルを管理できますが、今回はこちらを使用していません。

backetName='*****.tfbackend'
region='ap-northeast-1'

# バケット作る
aws s3api create-bucket \
  --bucket "${backetName}" \
  --create-bucket-configuration LocationConstraint="${region}"

# バージョニング有効化
aws s3api put-bucket-versioning \
  --bucket "${backetName}" \
  --versioning-configuration Status=Enabled

バックエンドとしてのバケットができたら、ワーキングディレクトリにおいて
上記のバックエンドを使用するためにterraform initを実行します

terraform init \
  -backend=true \
  -backend-config="bucket=${backetName}" \
  -backend-config="key=terraform.tfstate" \
  -backend-config="region=${region}"

tfファイルを作る

TerraformはTerraform configurationsと呼ばれるテキストファイル(tfファイル)に構成情報を記載していきます。
LightSailで使用できるリソース(Terraformで操作できる対象)は2018/09時点で下記のものとなります。

  • aws_lightsail_domain
  • aws_lightsail_instance
  • aws_lightsail_key_pair
  • aws_lightsail_static_ip
  • aws_lightsail_static_ip_attachment

ということで、tfファイルを見ていきましょう。今回は単一のファイルにすべて記載しました。

まずはバックエンドを指定します。
クレデンシャルは環境変数やCLIで設定しておけば、特に記載する必要はありません。

terraform {
  backend "s3" {}
}

作成するリソースに名前を付ける際に統一感を出すため、一部変数を使用しました。
その変数の宣言を行います。

variable "ls_name" {}

プロバイダを指定します。プロバイダとは、一言でいうと操作対象のクラウドとなります。
今回はAWSとなりますが、リソースではなくプロバイダごとにリージョンの指定が必要であることと、
リソースによってリージョンが異なる構成(後述)となるためap-northeast-1us-east-1で2つのプロバイダを指定しています。
また、名前の重複が許されないためus-east-1の方はaliasを指定しています。

provider "aws" {
  region = "ap-northeast-1"
}

provider "aws" {
  region = "us-east-1"
  alias = "useast1"
}

ここからリソースに関する記述をしていきます。
記法としては下記のようになります。リソースごとの引数はリファレンスを参照してください。

resource リソース リソースの名前 {
  引数 = 値
  :
}

aws_lightsail_domainリソースでドメイン(ゾーン)を作成しますが、こちらはus-east-1でしか作成できません。
インスタンス等他のリソースはap-northeast-1に作成したかったため、このリソースは明示的に上述の2つ目のプロバイダを指定しています。

resource "aws_lightsail_domain" "domain" {
  provider = "aws.useast1"
  domain_name = "example.com"
}

キーペアを作成、正確にはパブリックキーをインポートします。
下記の例ではfile("./id_rsa.pub")でローカルのファイルを読み込んでいます。

resource "aws_lightsail_key_pair" "key_pair" {
  name = "key_pair_${var.ls_name}"
  public_key = "${file("./id_rsa.pub")}"
}

パブリックIPを固定したいので固定IPを作成します。

resource "aws_lightsail_static_ip" "static_ip" {
  name = "static_ip_${var.ls_name}"
}

下記例は最低限必要なパラメータのみでインスタンスを作成します。
blueprint_idはインスタンスのイメージで、aws lightsail get-blueprintsで確認可能です。
bundle_idはインスタンスタイプで、aws lightsail get-bundlesで確認可能です。
ちなみにkey_pair_nameではaws_lightsail_key_pairリソースの値を参照しています。

resource "aws_lightsail_instance" "instance" {
  name              = "${var.ls_name}"
  availability_zone = "ap-northeast-1a"
  blueprint_id      = "wordpress_4_9_6"
  bundle_id         = "micro_2_0"
  key_pair_name     = "${aws_lightsail_key_pair.key_pair.name}"
}

インスタンスと固定IPを紐づけます。

resource "aws_lightsail_static_ip_attachment" "static_ip_attachment" {
  static_ip_name = "${aws_lightsail_static_ip.static_ip.name}"
  instance_name = "${aws_lightsail_instance.instance.name}"
}

outputを記述しておくと、生成したリソースの設定値等を出力できます。
また、terraform outputで後から表示することも可能です。便利ですね。

output "static_ip" { value = "${aws_lightsail_static_ip.static_ip.ip_address}" }

シュッとつくる

tfファイルができたらあとはterraform planして内容を確認し、

terraform plan -var "ls_name=example"

問題なければterraform applyを実行すると

terraform apply -var "ls_name=example"

もりもりとリソースが作られます。便利ですね。
ちなみに-var引数で変数名=値と指定することでtfファイル内で定義した変数に値を渡しています。

シュッとつくれない

と、ここまではよいのですが実運用では不足するリソースがあります。
下記に関してはAWS CLIや手動での対応が必要となりました。

  • Firewall
  • DNS
    • レジストラ側でのDNSサーバの登録、または別DNSサーバでのNSレコードによる委譲
    • レコードの登録

また、今回は使用しませんでしたがLBや証明書、追加ストレージなどもTerraformでは対応していません。

おしまい

ということで思ったほどシュッとできませんでしたが、最近値下げもされましたしカジュアルな用途ではLightSailいいですね。
cfnの対応やTerraformのリソース拡充に期待です。