Memo/Terraform

http://dexlab.net/pukiwiki/index.php?Memo%2FTerraform
 

Terraform

  • https://www.terraform.io/
    • CHANGELOG.md
    • HashiCorp?製ツール(Vagrant, Packer, Serf等の開発元)
    • AWS, Heroku等の複数のクラウドサービスに対応している
    • Terraformの不具合の多さを理解しつつ、Terraformの不具合報告等のオープンソース活動を行える余裕がある人向け。
    • https://github.com/hashicorp/terraform/issues を見ると分かるが1000 issue以上が作成されており、不具合の修正が間に合っていない印象
    • 状態をステートファイル(terraform.tfstate)に持ち、これを元に差分更新する。
      • 無くすと大変。更新ができなくなる。
      • ステートファイルはAWS S3等に置く事はできる。
      • ステートファイルの管理が面倒。リソースの差分がうまく比較できないようで、リソースの更新には不向き。新規作成・破棄を繰り返す用途向き
    • ドキュメント・サンプルがほとんど無い。α版の印象
    • マイナーバージョンが0.0.1変わっても、仕様が大きく変わり、互換性が無くなる事も多い。
      • 開発方針がdevしかなく、stable等の安定版が無い
    • AWS:対応しているリソースの新規立ち上げは楽だが、非対応の項目がかなりあるため、自分が必要としている機能をサポートしているか要確認
    • 遭遇したトラブル
      • v0.0.1上がるとコードに無いheroku configを消すように仕様変更
      • API GatewayのSSL証明書の登録が成功したように見えるが、実は成功していない。
      • destroy時は削除確認があるが、EC2セキュリティグループの変更で、EC2が作り直される時には警告はない。plan時に予期しない変更が無いか強く確認が必要。さもなければ簡単にリソースが消える
      • セキュリティグループに変更を加えると、EC2を作り直そうとする
      • ELBにリスナー追加しようとすると、リスナー全て消えた
      • SSL証明書のアップロードが成功したように見えて壊れている
      • EC2にEBSを追加しようすると、EC2を作り直そうとする

タイムアウトの延長

リソースの作成/削除等で、timeoutする場合がある。

  • Timeouts
  • aws_db_instanceの場合
    1. resource "aws_db_instance" "timeout_example" {
    2.   name              = "mydb"
    3.   # ...
    4.   timeouts {
    5.     create = "60m"
    6.     delete = "2h"
    7.   }
    8. }

alicloud(aliyun alibaba)

中国のalicloud用プロバイダー


セキュリティグループルールはaws_security_group_ruleを使う

ルールの追加は「aws_security_group_rule」推奨。
aws_security_groupに書くとplan時に順番が変わって、diffとして表示されてしまう。


ヒアドキュメントでJSON等を綺麗に書く

  • terraformでは引用が「"」のみで、JSON等を書こうとすると、「\"」のエスケープが必要で見難い
  • JSON Formatter & Validator JSONの検証と整形
  • ヒアドキュメント「var = <<EOF 〜 EOF」が使える
    1. resource "aws_iam_policy" "policy" {
    2.     name = "test_policy"
    3.     path = "/"
    4.     description = "My test policy"
    5.     policy = <<EOF
    6. {
    7.   "Version": "2012-10-17",
    8.   "Statement": [
    9.     {
    10.       "Action": [
    11.         "ec2:Describe*"
    12.       ],
    13.       "Effect": "Allow",
    14.       "Resource": "*"
    15.     }
    16.   ]
    17. }
    18. EOF
    19. }

変数にmap(連想配列)を使う

  • type = "map" は省略できる
  • aws.tf
    1. # https://aws.amazon.com/marketplace/fulfillment?productId=b7ee8a69-ee97-4a49-9e68-afaee216db2e&ref=cns_srchrow&versionTitle=1708
    2. # "${lookup(var.aws_ami_ids, "ap-northeast-1_centos7_2017-10-12")}"
    3. variable "aws_ami_ids" {
    4.   default = {
    5.     "us-east-1_centos7_2017-10-12"      = "ami-db48ada1"
    6.     "us-west-2_centos7_2017-10-12"      = "ami-e535c59d"
    7.     "ap-southeast-1_centos7_2017-10-12" = "ami-1fbad07c"
    8.     "ap-northeast-1_centos7_2017-10-12" = "ami-e4599a82"
    9.     "eu-central-1_centos7_2017-10-12"   = "ami-2540f74a"
    10.     "eu-west-1_centos7_2017-10-12"      = "ami-5f76b626"
    11.   }
    12. }
    13.  
    14. output "aws_ami_ids" { value = "${var.aws_ami_ids}" }
    15. output "aws_ami_id_centos7" { value = "${lookup(var.aws_ami_ids, "ap-northeast-1_centos7_2017-10-12")}" }
  • 実行結果
    1. terraform apply
    2. ...
    3. aws_ami_id_centos7 = ami-e4599a82
    4. aws_ami_ids = {
    5.   ap-northeast-1_centos7_2017-10-12 = ami-e4599a82
    6.   ap-southeast-1_centos7_2017-10-12 = ami-1fbad07c
    7.   eu-central-1_centos7_2017-10-12 = ami-2540f74a
    8.   eu-west-1_centos7_2017-10-12 = ami-5f76b626
    9.   us-east-1_centos7_2017-10-12 = ami-db48ada1
    10.   us-west-2_centos7_2017-10-12 = ami-e535c59d

No valid credential sources found for AWS Provider.

  • チェックポイント
    • terraformは「~/.aws/credentials」内のkeyしか読まない。このファイル内にクレデンシャルが必要。ansibleは「~/.aws/config」にkeyがあれば読んでくれるので誤解する。
      1. cat ~/.aws/credentials
      2. [myprofile]
      3. aws_access_key_id = AK****
      4. aws_secret_access_key = ****
    • ちょっとしたフォーマットの違い(ダブルクオートの有無、スペースの有無等)で読めていない。一度セクションを消して、awsコマンドで生成する。
      1. aws configure --profile myprofile

tfファイル内で複数AWSアカウント、複数リージョンを扱う

  • tfファイルで、異なるリージョンを扱う。デフォルトproviderは必須のようで、存在しないとエラーになる(terraform v0.10.2)
    1. variable "aws_profile" {} # awscli profile name. terraform plan/apply時にプロンプトを出す
    2.  
    3. provider "aws" {
    4.   profile = "${var.aws_profile}"
    5.   region  = "ap-northeast-1" # tokyo
    6. }
    7.  
    8. provider "aws" {
    9.   profile = "${var.aws_profile}"
    10.   region  = "us-east-1"
    11.   alias   = "virginia"
    12. }
    13.  
    14. resource "aws_s3_bucket" "tokyo-example" {
    15.   bucket = "tokyo.example.com"
    16.   acl = "private"
    17. }
    18.  
    19. resource "aws_s3_bucket" "virginia-example" {
    20.   provider = "aws.virginia"
    21.   bucket = "virginia.example.com"
    22.   acl = "private"
    23. }
  • 作成済みリソースを terraform importする場合
    1. terraform import aws_s3_bucket.tokyo-example tokyo.example.com
    2. terraform import -provider=aws.virginia aws_s3_bucket.virginia-example virginia.example.com

VPC Peering

  • 異なるAWSアカウント間で、VPC peeringを設定する
    • アクセプタ側でVPC > ピア接続 > 選択 > アクション > 許可する
    • 手動で許可する場合、terraform applyが必ず失敗する(auto_accept = false でも)。許可した後、もう一度実行が必要
  • aws.tf
    1. variable "aws_region" { default = "ap-northeast-1" }
    2. // リクエスタ側のAWS account情報. aws configure --profile <name> で設定しておく
    3. variable "main_aws_profile" {}
    4. variable "main_aws_vpc_id" { default = "vpc-aaaaa" }
    5. variable "main_aws_route_table_id" { default = "rtb-11111111" }
    6. variable "main_aws_cidr" { default = "172.31.0.0/16" }
    7.  
    8. provider "aws" {
    9.   profile = "${var.main_aws_profile}"
    10.   region  = "${var.aws_region}"
    11. }
    12.  
    13. // "${data.aws_caller_identity.main.account_id}" として参照可能
    14. data "aws_caller_identity" "main" {
    15. }
    16.  
    17. // アクセプタ側のAWS account情報
    18. variable "peer_aws_account_id" { default = "2222222222" }
    19. variable "peer_vpc_id" { default = "vpc-bbbbb" }
    20. variable "peer_vpc_cidr" { default = "10.5.0.0/16" }
  • iam.tf
    1. output "aws_iam_role.vpc_peering.arn"     { value = "${aws_iam_role.vpc_peering.arn}" }
    2.  
    3. resource "aws_iam_role" "vpc_peering" {
    4.     name               = "main-vpcpeering"
    5.     assume_role_policy = "${data.aws_iam_policy_document.sts-assumerole.json}"
    6. }
    7.  
    8. # AWS console上だとIAM > ロール > ロール名 > 信頼関係タブの部分
    9. data "aws_iam_policy_document" "sts-assumerole" {
    10.   statement {
    11.     actions = [
    12.       "sts:AssumeRole",
    13.     ]
    14.     effect = "Allow"
    15.     principals = {
    16.       type = "AWS"
    17.       identifiers = [
    18.         "arn:aws:iam::${var.peer_aws_account_id}:root",
    19.       ]
    20.     }
    21.   }
    22. }
    23.  
    24. # AWS console上だとIAM > ロール > ロール名 > アクセス許可タブ > インラインポリシーの部分
    25. resource "aws_iam_role_policy" "vpc_peering" {
    26.     name   = "main-vpcpeering"
    27.     role   = "${aws_iam_role.vpc_peering.id}"
    28.     policy = "${data.template_file.vpc_peering.rendered}"
    29. }
    30.  
    31. data "template_file" "vpc_peering" {
    32.   template = "${file("./policy/vpc-peering-connection.tpl")}"
    33.  
    34.   vars {
    35.     aws_region          = "${var.aws_region}"
    36.     main_aws_account_id = "${data.aws_caller_identity.main.account_id}"
    37.     main_aws_vpc_id     = "${var.main_aws_vpc_id}"
    38.     peer_aws_account_id = "${var.peer_aws_account_id}"
    39.     peer_aws_vpc_id     = "${var.peer_vpc_id}"
    40.   }
    41. }
  • ./policy/vpc-peering-connection.tpl
    1. {  "Version":"2012-10-17",  "Statement":[    {      "Effect":"Allow",      "Action":"ec2:AcceptVpcPeeringConnection",      "Resource":"arn:aws:ec2:${aws_region}:${main_aws_account_id}:vpc-peering-connection/*",      "Condition":{        "ArnEquals":{          "ec2:RequesterVpc":"arn:aws:ec2:${aws_region}:${peer_aws_account_id}:vpc/${peer_aws_vpc_id}"        }      }    },    {      "Effect":"Allow",      "Action":"ec2:AcceptVpcPeeringConnection",      "Resource":"arn:aws:ec2:${aws_region}:${main_aws_account_id}:vpc/${main_aws_vpc_id}"    }  ] }
  • vpc_peering.tf
    1. // Requester's side of the connection.
    2. // https://www.terraform.io/docs/providers/aws/r/vpc_peering.html
    3. resource "aws_vpc_peering_connection" "main" {
    4.   vpc_id        = "${var.main_aws_vpc_id}"
    5.   peer_vpc_id   = "${var.peer_vpc_id}"
    6.   peer_owner_id = "${var.peer_aws_account_id}"
    7.   auto_accept   = false
    8.  
    9.   tags {
    10.     Name = "VPC Peering between main and peer"
    11.     Side = "Requester"
    12.   }
    13. }
    14.  
    15. resource "aws_route" "main" {
    16.   route_table_id            = "${var.main_aws_route_table_id}"
    17.   destination_cidr_block    = "${var.peer_vpc_cidr}"
    18.   vpc_peering_connection_id = "${aws_vpc_peering_connection.main.id}"
    19. }
  • アクセプタ側のAWSアカウントも自分で管理している時
    1. variable "peer_aws_route_table_id" { default = "rtb-22222" }
    2.  
    3. // Accepter's credentials.
    4. provider "aws" {
    5.   alias = "peer"
    6.   profile = "peer" // aws configure --profile <name> で設定しておく
    7.   region = "ap-northeast-1"
    8. }
    9.  
    10. // Accepter's side of the connection.
    11. // https://www.terraform.io/docs/providers/aws/r/vpc_peering_accepter.html
    12. resource "aws_vpc_peering_connection_accepter" "peer" {
    13.   provider                  = "aws.peer"
    14.   vpc_peering_connection_id = "${aws_vpc_peering_connection.main.id}"
    15.   auto_accept               = true
    16.  
    17.   tags {
    18.     Name = "VPC Peering between main and peer"
    19.     Side = "Accepter"
    20.   }
    21. }
    22.  
    23. resource "aws_route" "peer" {
    24.   provider                  = "aws.peer"
    25.   route_table_id            = "${var.peer_aws_route_table_id}"
    26.   destination_cidr_block    = "${var.main_aws_cidr}"
    27.   vpc_peering_connection_id = "${aws_vpc_peering_connection_accepter.peer.id}"
    28. }

AWS account_id/arn/user_idの取得

  1. // "${data.aws_caller_identity.main.account_id}" として参照できる
  2. data "aws_caller_identity" "main" {
  3. }

import: 既存のリソースからtfstateを作成する

GitHub - dtan4/terraforming? でやっていた事が公式で一部可能になった。

  • Command: import - Terraform by HashiCorp
    • 既存リソースからtf, tfstateファイルを生成できる
    • リソースIDを一つ一つ指定しなければいけないので面倒
    • v0.9.4: route53をimportしようとするとcrashした

変数

  • パスワード等はtfファイルに書かないようにしたい場合。「-var "key=value"」が複数使える
    1. cat rds.tf
    2. variable db_root_password {}
    3.  
    4. db_root_password=$(mkpasswd -l 16 -s 0)
    5. terraform plan -var "db_root_password=$db_root_password"
  • 別ファイルにしたい場合: 「-var-file="secret.tfvars"」

バージョン変更によるアップグレード方法


VPCの作成


lifecycle: 指定リソースの差分を無視する

EBSを追加したり、SGを追加しようとするとEC2を作り直してしまう場合がある。

  • Configuring Resources - Terraform by HashiCorp
    • create_before_destroy: 既存リソースが有った場合、削除してから作成する
    • prevent_destroy: リソース保護。削除する時にエラーになる
    • ignore_changes: 差分があっても無視する
  • 後から追加したroot_block_deviceの差分を無視したい。
    1. lifecycle {
    2.   ignore_changes = ["root_block_device"]
    3. }

AWS


aws_nat_gateway

  • subnet毎にnat-gatewayを作成
  • terraform v0.10.0
    1. variable aws_subnets {
    2.   type = "list"
    3.   default = [
    4.     "subnet-aaaa",  # AZ: ap-northeast-1a
    5.     "subnet-cccc",  # AZ: ap-northeast-1c
    6.   ]
    7. }
    8.  
    9. resource "aws_nat_gateway" "gw" {
    10.   allocation_id = "${aws_eip.gw.*.id[count.index]}"
    11.   subnet_id     = "${var.aws_subnets[count.index]}"
    12.   count         = "${length(var.aws_subnets)}"
    13. }
    14.  
    15.  
    16. resource "aws_eip" "gw" {
    17.   vpc   = true
    18.   count = "${length(var.aws_subnets)}"
    19. }

複数リソースの指定

  • 変数と配列を指定 v0.10.2
    1. variable "cidr_common" { default = "192.168.2.1/32" }
    2. variable "cidr_example" { default = ["192.168.1.0/24", "10.5.1.0/24"] }
    3.  
    4. resource "aws_security_group" "common" {
    5. ...
    6.   cidr_blocks = [
    7.     "${var.cidr_common}",
    8.     "${var.cidr_example}"
    9.   ]
  • EC2インスタンスにEIPを付ける v0.10.2
    1. variable "instance_count_web"       { default = 1 }
    2.  
    3. # aws_elbは複数リソースがそのまま指定できる
    4. resource "aws_elb" "frontend" {
    5.     instances = ["${aws_instance.web.*.id}"]
    6. }
    7.  
    8. # aws_eipは一つのリソースしか指定できないので変換して渡す
    9. resource "aws_eip" "web" {
    10.     count = "${var.instance_count_web}"
    11.     instance = "${element(aws_instance.web.*.id, count.index)}"
    12.     vpc = true
    13. }
  • Resource '〜' not found for variable '〜.1.id': 「.0.id」はアクセスできるが、「.1.id」がエラーになった。terraformの不具合か分からないが、以下の様に明示的に指定できる
    1. "${element(aws_instance.web.*.id, 1)}"

RDS

AWS: aws_db_instance - Terraform by HashiCorp

  • classic network上にRDSを作る場合にsubnetのエラーが出る。v0.8.6で確認
    • 「publicly_accessible = true」が必要

デバッグ

  • デバッグログを出す
    1. TF_LOG=DEBUG terraform plan

heroku postgresqlのplan変更


output: 出力だけを見る

public dns, IP等、後で参照したい情報を出力するのに便利

  1. terraform output

outputで複数リソースの値を出力

Output Variablesでは1つの値しか出力できないようだ。

  • いつのバージョンからかJSONで出力できるようになっていた
    1. output "web.private_ip" { value = "${aws_instance.web.*.private_ip}" }
    2.  
    3. Outputs:
    4. web.private_ip = [
    5.     i-1111,
    6.     i-2222
    7. ]
  • 複数EC2のprivate ipをカンマ区切りで出力
    1. output "web.private_ip" { value = "${join(",",aws_instance.web.*.private_ip)}" }

backend: : S3等に変数を置く

  • terraform.tf:
    • このファイル内で変数は使えなかった。「configuration cannot contain interpolations」エラー
      1. terraform {
      2.   backend "s3" {
      3.     profile = "myprofile"
      4. #    shared_credentials_file = "~/.aws/config" # v0.9.3 で試しても失敗
      5.     region  = "ap-northeast-1"
      6.     bucket  = "mybucket"
      7.     key     = "web/terraform.tfstate" # path/file で1バケットに複数のtfstateを置ける
      8.   }
      9. }
  • 実行: terraform v0.9.3
    1. aws --profile myprofile configure
    2.  
    3. # ~/.aws/credentials に該当キーが出来ているのが重要。
    4.  
    5. terraform init
    6.  
    7. terraform plan

REMOTE STATE: S3等に変数を置く

  • terraform_remote_state
    • v0.6.14,15ではうまく動作しなかった。terraform.tfstate にユーザのAWS KEYSが入ってしまうので注意。
    • v0.7で廃止。

REMOTE CONFIG: S3等にterraform.tfstateを置く

terraform.tfstate にAWS KEYSやパスワード等が入っているため、git/svnにコミットしにくい。
S3等にpushする機能がある。

  • 「terraform.tfstate」がS3のバケットにアップロードされる。localの「terraform.tfstate」は「.terraform/terraform.tfstate」に移動する。
    1. export AWS_ACCESS_KEY_ID=<YOUR ACCESS KEY>
    2. export AWS_SECRET_ACCESS_KEY=<YOUR SECRET KEY>
    3. terraform remote config \
    4.  -backend=S3 \
    5.  -backend-config="region=ap-northeast-1" \
    6.  -backend-config="bucket=mybucket-terraform" \
    7.  -backend-config="key=terraform.tfstate"
  • localにある「terraform.tfstate」をremoteにpushする
    1. terraform remote push
  • remoteにある「terraform.tfstate」をlocalに持ってくる
    1. terraform remote pull
  • 無効化する。localの「terraform.tfstate」が復活する。remoteのファイルは消えなかった
    1. terraform remote config -disable

指定したリソースだけplan/apply

  • 「-target=resource 」オプションがある。複数指定したい場合は「-target=resource1 -target=resource2」とする
    1. terraform plan -target=aws_instance.web[0]
  • Command: plan - Terraform by HashiCorp

変数で配列が扱えない

  • 変数に配列が使用できない。(v0.6.6で確認) v0.7以降で使用可能
  • [v0.7以降]
    1. # example.tf
    2. variable "security_groups" {                                                                                                                                                                                                             
    3.   default = ["sg-xx", "sg-x,sg-xxx"]
    4. }
    5.  
    6. resource "aws_instance" "web" {
    7.   ...
    8.   security_groups = "${var.security_groups}"
    9. }
  • Store arrays in variables Issue #57 hashicorp/terraform GitHubで要望は上がっているようだ。
  • [v0.7未満] 擬似的に配列を設定する
    1. # example.tf
    2. variable "security_groups" {                                                                                                                                                                                                             
    3.   default = "sg-xx,sg-x,sg-xxx"
    4. }
    5.  
    6. resource "aws_instance" "web" {
    7.   ...
    8.   security_groups = "${split(",", var.security_groups)}"
    9. }

EC2起動時にuser_dataを渡す

  • ec2.tf
    1. resource "aws_instance" "web01" {
    2. ...
    3.   user_data = "${file("cloud-config.yaml")}"
    4. ...
    5. }

既存のheroku appからterraform.tfstateを生成する

  • Terraformingは2015-09-02現在herokuは未対応
  • 以下の方法で、heroku configで取得できる値は terraform.tfstate に入るため、svn/git等で差分管理に使える
  • 例:heroku app-idが"my-heroku-app-dev"
  • terraform.tfvars
    1. email = "myname@example.com"
    2. api_key = "1111-2222-3333-4444-5555"
  • heroku.tf
    1. variable "email" {}
    2. variable "api_key" {}
    3.  
    4. provider "heroku" {
    5.     email   = "${var.email}"
    6.     api_key = "${var.api_key}"
    7. }
    8.  
    9. resource "heroku_app" "my-heroku-app" {
    10.     name   = "my-heroku-app-dev"
    11.     region = "us"
    12. }
  • terraform.tfstate
    1. {    "version": 1,    "serial": 0,    "modules": [        {            "path": [                "root"            ],            "outputs": {},            "resources": {                "heroku_app.my-heroku-app": {                    "type": "heroku_app",                    "primary": {                        "id": "my-heroku-app-dev",                        "attributes": {                        }                     }                 }             }         }    ] }
  • 実行
    1. terraform refresh
  • 既存のaddonをterraform.tfstateに追加する
  1. Memo/Heroku#j7b76ec9 でaddonのidを調べる
  2. terraform.tfstate に追加。herokuのアプリIDが「my-app」の場合
    1.                 "heroku_addon.ssl": {                    "type": "heroku_addon",                    "depends_on": [                        "heroku_app.my-app"                    ],                    "primary": {                        "id": "****-****-****-****-****",                        "attributes": {                            "app": "my-app",                        }                    }                },
  3. attributesの中身を更新
    1. terraform refresh

Terraforming: 既存のインフラを Terraform で管理できるように

terraform v0.7.0からimport機能が実装されたため、Terraformingは不要かもしれない。

terraform.tfstate や tf形式のソースを生成する [#f45434d2]

  • CentOS6.xの場合。ruby 2.1.0以上なので、rbenvやrvmで新しいrubyを使えるようにする
    1. rvm use 2.1.5
    2. ruby --version
    3. ruby 2.1.5p273 (2014-11-13 revision 48405) [x86_64-linux]
    4.  
    5. rvmsudo gem install terraforming aws-sdk
    6. ln -s ~/.aws/config ~/.aws/credentials
    7.  
    8. # なぜか --profileオプションが動作せず
    9. export AWS_ACCESS_KEY_ID=****
    10. export AWS_SECRET_ACCESS_KEY=****
    11. export AWS_REGION=ap-northeast-1
    12. terraforming ec2 > terraforming.ec2.tf
    13. terraforming ec2 --tfstate >terraforming.terraform.tfstate

複数バージョンの切り替え

  • バージョンによって動作しない機能があり、古いバージョンに切り替えたい時がある。
    • 0.7.1: terraformコマンドが1ファイルになった
    • 0.6.0: CentOS6.x ReleaseMedia?が起動しないのが直った?
    • 0.5.3: AWS EC2でCentOS6.x ReleaseMedia?が起動しない
    • 0.3.7: 1回目は成功するが、2回目は、AWS EC2セキュリティグループが壊れる
  • CentOS6.x 64bitの場合
    1. TERRAFORM_VER=0.8.5
    2. sudo mkdir -p /opt/terraform.${TERRAFORM_VER}
    3. sudo wget -O /opt/terraform.${TERRAFORM_VER}/terraform_${TERRAFORM_VER}_linux_amd64.zip https://releases.hashicorp.com/terraform/${TERRAFORM_VER}/terraform_${TERRAFORM_VER}_linux_amd64.zip
    4. sudo unzip -d /opt/terraform.${TERRAFORM_VER}/ /opt/terraform.${TERRAFORM_VER}/terraform_${TERRAFORM_VER}_linux_amd64.zip
    5.  
    6. # v0.7.x以上の場合
    7. sudo alternatives --install /usr/local/bin/terraform terraform /opt/terraform.${TERRAFORM_VER}/terraform 70
    8.  
    9. # v0.6.x以下の場合
    10. echo alternatives --install /usr/local/bin/terraform terraform /opt/terraform.${TERRAFORM_VER}/terraform 60 \\ > /tmp/install-terraform.sh
    11. find /opt/terraform.${TERRAFORM_VER}/ -name 'terraform-*' -type f -printf ' --slave /usr/local/bin/%f %f %p \\\n' >> /tmp/install-terraform.sh
    12. sudo bash /tmp/install-terraform.sh
  • バージョンの切り替え
    1. alternatives --display terraform
    2. sudo alternatives --set terraform /opt/terraform.${TERRAFORM_VER}/terraform
    3.  
    4. # 削除
    5. sudo alternatives --set terraform /opt/terraform.${TERRAFORM_VER}/terraform

[heroku] 既存環境からtfファイルの作成

  • terraform.tfstateからconfigをkey = value形式で抽出
    1. cat terraform.tfstate \
    2.  | jq '.modules[].resources[].primary[]' \
    3.  | grep '"all_config_vars.' | grep -v '"all_config_vars.#' \
    4.  | perl -ane 'if(/"([^"]+)":\s*"([^"]+)"/){$k=$1;$v=$2;$k=~s/all_config_vars.//;print "$k = \"$v\"\n";}' \
    5.  | sort

不具合

  • v0.6.16: v0.6.15と同様にawsリソースを作り直す不具合有り
  • v0.6.15: awsリソースを全部作り直そうとする不具合がある。destroy, apply, refresh, planで確認
  • v0.6.14: heroku_app SSL証明書更新でクラッシュした
  • v0.4.2: awsのroot_block_deviceでvolume_size等を変更しようとすると「logicalType cannot be modified on root device」のエラーが出る。v0.3.7へダウングレードした。
  • v0.4.2: aws_instance の *_block_device が毎回違うように表示される
  • v0.4.2: aws_security_group の 自己参照、他セキュリティグループIDの指定がうまくいかない
  • v0.4.2: --target=リソース名で、ハイフン(-)に対応していない。 例:--target=aws_route53_record.web-01 はNG、web_01ならOK

セキュリティグループを後から変更しようとするとEC2を作り直してしまう

  • VPCの場合、security_groups ではなく vpc_security_group_ids を使う

インストール

  • CentOS6.x /usr/local/binにインストールする
    1. wget -O terraform_0.3.7_linux_amd64.zip https://dl.bintray.com/mitchellh/terraform/terraform_0.3.7_linux_amd64.zip
    2. sudo unzip terraform_0.3.7_linux_amd64.zip -d /usr/local/bin/
    3.  
    4. terraform version
    5. Terraform v0.3.7

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2018-04-11 (水) 16:16:30 (15d)