だれでも簡単terraform入門
リリース日は決まっているのに仕様は決まりません!
どうも、とよです。
以前所属していたプロジェクトでは自社DCで運用していたため、今まで全く触れてこなかったAWSですが、今のプロジェクトではAWSを使うので、terraformを使ってインフラを管理していこうと思っています。
このエントリでできること
- terraformを使ってMacからAWSのインスタンスを立ち上げる
- Macからterraformで作ったインスタンスにSSHする
環境
- Mac OSX 10.9.5 Mavericks
- Terraform v0.5.3
Terraformとは
Terraformは安全にかつ効率的にインフラを構築、変更、バージョニングできるツール。
かの有名なVagrantやPackerなどを擁するHashiCorp者のプロダクトで、Goで書かれてます。
インフラ管理がプログラマブルになるので、アプリエンジニアでもちょっと知識がつけば専属インフラエンジニアが不要になったり不要にならなかったりするでしょう。
なんかやたらとサイトがカッコイイ。
Terraform by HashiCorp
AWSインスタンスを立ち上げてみる
成果物は以下のリポジトリにおいてあります。
Terraformのインストール
Goなのでバイナリをダウンロードしてきて、PATHを通します。
今回は /usr/local/terraform
解凍したディレクトリをぶちこみます。
$ terraform --version
Terraform v0.5.3
勘所
次に、要となる設定ファイルを記述します。
設定ファイル名
terraformは*.tf
のファイルをすべて読み込みますので、hoge.tf
のように命名したファイルを作成します。
terraformを利用するIAMユーザーを作成
terraformでAWSにアクセスするためのユーザーが必要なので、AWSコンソールで作ります。
作成したユーザーにはAdministratorAccess
のポリシーでもアタッチしておきましょう。
terraformで作成したユーザーにAmazonEC2FullAccess
をつけておけばインスタンスの作成ができると思っていましたが、どうやらterraform利用ユーザーに強い権限つけないといけないみたいです(そのうち調べます)。
provider
Terraformは様々なインフラサービスのプロバイダをサポートしています。
ここではAWSを使うので、awsのprovider
の設定を行います。
variable "access_key" {} variable "secret_key" {} provider "aws" { access_key = "${var.access_key}" secret_key = "${var.secret_key}" region = "ap-northeast-1" }
このように記述することで、awsのリソースを扱うのに必要な情報を設定することができます。
また、見ていただくと分かる通り、アクセスキーとシークレットキーの情報が書かれていません。
このようなバージョン管理したくない情報は.gitignore
したいので、別のファイルに外出しします。
Terraformでは*.tfvars
という拡張子でファイルを作ると変数を格納する設定ファイルを利用できるので、そのファイルだけignoreすればいいということになります。
$ cat terraform_iam.tfvars access_key = "ACCESS_KEY" secret_key = "SECRET_KEY"
このファイルを利用するには-var-file
オプションを使いますが、デフォルトではterraform.tfvars
ファイルを使用するのでその場合は指定する必要がありません。
resource
AWSの場合、仕様できるリソースは以下のページで一覧できます。
今回はインスタンスを立ち上げてSSHできるところまでできればいいので、
- aws_iam_instance_profile
- aws_iam_role
- aws_iam_role_policy
- aws_security_group
- aws_instance
この辺りを利用しています。
設定内容はリポジトリを御覧ください。
terraforming/simple_instance.tf at master · takasing/terraforming · GitHub
今回は後々Dockerを利用したいので、CoreOSのAMIを利用します。
実行
実行に際してはplan
, apply
を使用します。
plan
plan
はdryrunのようなもので、実行したら差分をチェックして反映される内容を出力してくれます。
$ terraform plan -var-file=terraform_iam.tfvars Refreshing Terraform state prior to plan... The Terraform execution plan has been generated and is shown below. Resources are shown in alphabetical order for quick scanning. Green resources will be created (or destroyed and then created if an existing resource exists), yellow resources are being changed in-place, and red resources will be destroyed. Note: You didn't specify an "-out" parameter to save this plan, so when "apply" is called, Terraform can't guarantee this is what will execute. + aws_iam_instance_profile.takasing_tf arn: "" => "<computed>" create_date: "" => "<computed>" name: "" => "takasing-tf" (略) + aws_iam_role.takasing_tf arn: "" => "<computed>" assume_role_policy: "" => "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Action\": (略) + aws_iam_role_policy.takasing_tf_policy name: "" => "takasing-tf-policy" policy: "" => "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Action\": \"ec2:*\",\n (略) + aws_instance.tf_instance ami: "" => "ami-9cc1119c" availability_zone: "" => "ap-northeast-1a" (略) + aws_security_group.allow_all description: "" => "TODO: limit cidr_blocks" (略)
ただ、このplan
なんですけど、chef-client
の-W
オプションのように、ここで成功してもapply
の実行が必ず成功するとは限らないので##注意が必要みたいです。
たとえばplan
実行して大丈夫そうだけど、実際に実行したらユーザーの権限足りなかった、みたいな。
apply
plan
で問題なさそうなことが確認できたら次はapply
を実行します。
$ terraform apply -var-file=terraform_iam.tfvars aws_iam_role.takasing_tf: Refreshing state... (ID: takasing-tf) aws_security_group.allow_all: Refreshing state... (ID: sg-XXXXXXXX) aws_iam_role_policy.takasing_tf_policy: Refreshing state... (ID: takasing-tf:takasing-tf-policy) aws_iam_instance_profile.takasing_tf: Refreshing state... (ID: takasing-tf) aws_instance.tf_instance: Creating... ami: "" => "ami-9cc1119c" availability_zone: "" => "ap-northeast-1a" (略) Apply complete! Resources: 1 added, 0 changed, 0 destroyed. The state of your infrastructure has been saved to the path below. This state is required to modify and destroy your infrastructure, so keep it safe. To inspect the complete state use the `terraform show` command. State path: terraform.tfstate
この実行結果はインスタンスだけ存在しない場合の結果なんですけど、
terraformが差分をチェックして実行しているので、すでにセキュリティグループやIAMが準備済みでインスタンスのみが存在しないような場合は、インスタンスの作成のみをしてくれるみたいです。
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
と書いてありますね。
terraform.tfstate
terraformはapply
実行後、次回以降の差分検出のためにterraform.tfstate
というファイルを生成しています。
これはRDSのパスワードなどが平文で入るらしいので、バージョン管理しないほうが良いようです。
SSHしてみる
今回は22番ポートを開放してあるので、key pairの登録をちゃんとしていれば、手元にある鍵でSSHできるはずなのでSSHしてみます。 https://github.com/takasing/terraforming/blob/master/simple_instance.tf#L65-L74
ssh -i ~/.ssh/key.pem core@ec2-XX-XX-XX-XX.ap-northeast-1.compute.amazonaws.com Last login: Thu Jun 4 04:13:04 2015 from XXX.XXX.XXX.XXX CoreOS stable (647.2.0) core@ip-XXX-XXX-XXX-XXX ~ $
CoreOS使っているのにec2-userでログインしようとしてしまって少しハマりましたw
TODO
- 立ち上げるインスタンスをよりカスタマイズする
- ECSのオペレーションをする
まとめ
Terraformを使うことで、Github上でインフラエンジニアとのコミュニケーションが取れるし、自動化も進みますし、管理も楽になるのでいいですね。
もっと自動化して働く時間減らしたいでござる。