ラベル terraform の投稿を表示しています。 すべての投稿を表示
ラベル terraform の投稿を表示しています。 すべての投稿を表示

2019年9月25日水曜日

terraformを使って、redisを作成する方法

terraformを使って、各AZに一つずつノード(合計3つ)が存在するredisクラスターを作成します。
完成イメージ は以下の通りです。






 tfファイルの内容は以下の通りです。
resource "aws_elasticache_subnet_group" "grp" {
  name = "redis-example"
  subnet_ids = ["${var.subnet_id_public_a}", "${var.subnet_id_public_c}", "${var.subnet_id_public_d}"]
}
resource "aws_elasticache_replication_group" "replica_grp" {
  automatic_failover_enabled = true
  availability_zones = ["ap-northeast-1d", "ap-northeast-1c", "ap-northeast-1a"]
  replication_group_id = "example-redis"
  replication_group_description = "This is a example for create redis by terraform."
  node_type = "cache.t2.small"
  snapshot_retention_limit = 5
  number_cache_clusters = 3
  port = 6379
  subnet_group_name = "${aws_elasticache_subnet_group.grp.name}" 
  security_group_ids = ["${var.default_security_group_id}"]
}
subnet_ids:作成されたサブネットのIDを入力します。プライベートサブネットにしましょう。
availability_zones :3つのゾーンを入力します。
snapshot_retention_limit:バックアップの保存期間になります

terraform環境毎に切り替える方法

terraformで環境毎に切り替えるにはterraform workspaceを使います。
今回はステージング環境と本番環境でそれぞれS3バケット一つの作成を例とします。具体的な操作手順は以下の通りです。

まず、ステージング環境と本番環境用workspaceを作成

  • ステージング環境のワークスペースを作成
$ terraform workspace new staging
Created and switched to workspace "staging"!
You're now on a new, empty workspace. Workspaces isolate their state,
so if you run "terraform plan" Terraform will not see any existing state
for this configuration.
  • 本番環境用ワークスペースを作成
$ terraform workspace new prod
Created and switched to workspace "prod"!
You're now on a new, empty workspace. Workspaces isolate their state,
so if you run "terraform plan" Terraform will not see any existing state
for this configuration.
  • ワークスペース一覧を確認
$ terraform workspace list
default
* prod
staging
  • ステージング環境を作業中にします。
$ terraform workspace select staging
Switched to workspace "staging".

ステージングと本番用awsアカウント情報を設定

  • aws認証情報ファイル(~/.aws/credentials)の中、以下のようにステージングと本番用アクセスキーを設定します。
$ vi ~/.aws/credentials
[stg]
aws_access_key_id = xxxxxx
aws_secret_access_key = xxxxxxxxxxxxxxxxxxx
region = ap-northeast-1
[prod]
aws_access_key_id = xxxx
aws_secret_access_key = xxxxxxxxxxxxxxxxxxx
region = ap-northeast-1
  • main.tfというファイルを作成し、以下のようにアカウントを切り替えします。
$ vi main.tf
provider "aws" {
  region = "ap-northeast-1"
  profile = "${terraform.workspace == "staging"? "stg" : "prod"}"
}
簡単に説明すると、選択さらたワークスペースによってステージングと本番のプロフィルを使い分けます。

S3バケットを作成します

  • ステージング環境と本番環境用変数を作成します。
$ vi staging.tfvars
bucket_name = "stg-workspace-test"

$ vi prod.tfvars
bucket_name = "workspace-test"
  • バケットを作成するため、s3.tfというファイルを作成します。
$ vi s3.tf
variable "bucket_name" {}
resource "aws_s3_bucket" "example" {
  bucket = "${var.bucket_name}"
  acl = "private"
}

まず、ステージング環境で作成します。

  • 初期化します。
$ terraform init
Initializing provider plugins...
  • 実行します
$ terraform workspace select staging && terraform apply -var-file=staging.tfvars
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
+ aws_s3_bucket.example
id: <computed>
acceleration_status: <computed>
acl: "private"
arn: <computed>
bucket: "stg-workspace-test"
bucket_domain_name: <computed>
bucket_regional_domain_name: <computed>
force_destroy: "false"
hosted_zone_id: <computed>
region: <computed>
request_payer: <computed>
versioning.#: <computed>
website_domain: <computed>
website_endpoint: <computed>

Plan: 1 to add, 0 to change, 0 to destroy.
Do you want to perform these actions in workspace "staging"?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
上記、簡単に説明すると、まずstaging環境を選んで、設定ファイルstaging.tfvarsを適用した上でterraformを実行します。

本番環境で実行します。

ステージング環境で似てようで、以下のコマンドを使って本番でも実行します。
$ terraform workspace select prod && terraform apply -var-file=prod.tfvars

2019年9月24日火曜日

terraformで特定のリソースだけを削除/作成する

terraformで特定なリソースを削除

terraformでウェブアプリケーションのインフラを構築しました。
検証中にとあるリソースの設定にミスがあることに気づきました。すべて削除して再構築するには時間が…
terraformで特定のリソースだけを削除することができます。

以下、terraformで特定のresourceを削除する方法を紹介します。

以下のバケットの削除を例とします。

resource "aws_s3_bucket" "s3-example" {
    bucket = "${local.name_prefix}-example"
    acl    = "private"
}

オフィシャルサイトのドキュメントを読んだところ、特定のリソースを削除する時にオプション-target RESOURCE_TYPE.NAMEを追加するだけです。
でしたら以下のコマンドを試してみました。

$ terraform destroy --target aws_s3_bucket.s3-example

見事に上記のバケットだけが削除されました。
おまけに、複数のリソースを指定して削除を行う場合は複数回-targetfsオプションをつけることで一回の操作で複数のリソースを削除することができます。

terraform destroy -target RESOURCE_TYPE.NAME -target RESOURCE_TYPE2.NAME

terraformで特定なリソースを作成

terraformで特定なリソースを作成したい場合は削除と同じく-targetをつけます。例:

$ terraform apply --target aws_s3_bucket.s3-example

2019年9月22日日曜日

terraform workspaceとは?

terraformのworkspaceとは?

簡単に言うと、terraformで行った操作や、状態のデータなどを保持する場所です。

terraform workspaceのコマンド一覧は以下の通りです。
$ terraform workspace -h
Usage: terraform workspace

  New, list, show, select and delete Terraform workspaces.

Subcommands:
    delete    Delete a workspace
    list      List Workspaces
    new       Create a new workspace
    select    Select a workspace
    show      Show the name of the current workspace
  • terraform workspace delete:ワークスペースを削除
  • terraform workspace list:ワークスペースの一覧を表示する
  • terraform workspace new:ワークスペースを新規作成
  • terraform workspace select:ワークスペースを選択する
  • terraform workspace show:現在作業中(選択された)ワークスペースの名前を表示

terraform initで最初にワークスペースを初期化した直後に、defaultという名前のワークスペースが作られます。

2019年9月20日金曜日

terraformでRoute53にレコードを追加しようとしたら、「but it already exist」のエラーが発生しました

terraformを使って、Route53にロードバランサーのレコードを追加しようとしたら、エラーが起きました。
使ったソースコードは以下の通りです。
resource "aws_route53_record" "www" {
  zone_id = "Z1234txxxxx"
  name    = "test.com"
  type    = "A"

  alias {
    name                   = "${aws_lb.elb.dns_name}"
    zone_id                = "${aws_lb.elb.zone_id}"
    evaluate_target_health = true
  }
}
調査したところ、タイプ「A」のレコードは一件しか存在できないです。追加ではなく、もし古いレコードが存在していればそれを削除しておく必要があります。
解決方法はとても簡単です。
引数allow_overwrite = trueを追加すれば、もしレコードが存在している場合は上書きしてくれます。
変更後のソースコードは以下になります。
resource "aws_route53_record" "www" {
  zone_id = "Z1234txxxxx"
  name    = "test.com"
  type    = "A"
  allow_overwrite = true

  alias {
    name                   = "${aws_lb.elb.dns_name}"
    zone_id                = "${aws_lb.elb.zone_id}"
    evaluate_target_health = true
  }
}

2019年9月4日水曜日

Terrafom入門編ー設定、及びEC2インスタンスを作成

作業用フォルダを作成

作成するフォルダ名はterraform_test1を例します。
$mkdir terraform_test1

AWSにアクセス用認証情報を設定

AWSコンソール画面でterraform用IAMユーザーを作成し、accessキーとsecretキーを控えておきます。

terraform.tfvars というファイルを作成、以下のようにAWSアクセスキーとシークレットキー情報を入れます。
PS:terraform.tfvars や、*.auto.fvars というファイル名にしておきば、自動的に変数を読み込んでくれます。
aws_access_key = "AKIXXXXXXXPNN6KXXXXXXX"
aws_secret_key = "6sGivXXXXXXXXXXXbyd1ssLXXXXXY"

EC2インスタンスを作ってみる

ec2.tfというファイルを作成します。中身は以下の通りです。
variable "aws_access_key" {}
variable "aws_secret_key" {}

provider "aws" {
    access_key = "${var.aws_access_key}"
    secret_key = "${var.aws_secret_key}"
    region = "ap-northeast-1"
}

resource "aws_instance" "example" {
  ami           = "ami-02757f631"
  instance_type = "t3.nano"
}
簡単に説明すると、AMIami-02757f631をベースにしてインスタンスタイプt3.nanoのEC2一台を作成します。アクセスキーとシークレットキーはterraform.tfvars に設定した値を使用します。

初期化

terraform init コマンドを使って初期化します。

$ terraform init
Initializing the backend...
Initializing provider plugins...
- Checking for available provider plugins...
- Downloading plugin for provider "aws" (terraform-providers/aws) 2.25.0...
The following providers do not have any version constraints in configuration,
so the latest version was installed.
To prevent automatic upgrades to new major versions that may contain breaking
changes, it is recommended to add version = "..." constraints to the
corresponding provider blocks in configuration, with the constraint strings
suggested below.
* provider.aws: version = "~> 2.25"
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

文法チェック

terraform plan コマンドを使って先程作成したec2.tfファイルの正しさをチェックします。
$ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.
------------------------------------------------------------------------
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create
Terraform will perform the following actions:
  # aws_instance.example will be created
  + resource "aws_instance" "example" {
      + ami                          = "ami-031b61f0c1afb3454"
      + arn                          = (known after apply)
      + associate_public_ip_address  = (known after apply)
      + availability_zone            = (known after apply)
      + cpu_core_count               = (known after apply)
      + cpu_threads_per_core         = (known after apply)
      + get_password_data            = false
      + host_id                      = (known after apply)
      + id                           = (known after apply)
      + instance_state               = (known after apply)
      + instance_type                = "t3.nano"
      + ipv6_address_count           = (known after apply)
      + ipv6_addresses               = (known after apply)
      + key_name                     = (known after apply)
      + network_interface_id         = (known after apply)
      + password_data                = (known after apply)
      + placement_group              = (known after apply)
      + primary_network_interface_id = (known after apply)
      + private_dns                  = (known after apply)
      + private_ip                   = (known after apply)
      + public_dns                   = (known after apply)
      + public_ip                    = (known after apply)
      + security_groups              = (known after apply)
      + source_dest_check            = true
      + subnet_id                    = (known after apply)
      + tenancy                      = (known after apply)
      + volume_tags                  = (known after apply)
      + vpc_security_group_ids       = (known after apply)
      + ebs_block_device {
          + delete_on_termination = (known after apply)
          + device_name           = (known after apply)
          + encrypted             = (known after apply)
          + iops                  = (known after apply)
          + kms_key_id            = (known after apply)
          + snapshot_id           = (known after apply)
          + volume_id             = (known after apply)
          + volume_size           = (known after apply)
          + volume_type           = (known after apply)
        }
      + ephemeral_block_device {
          + device_name  = (known after apply)
          + no_device    = (known after apply)
          + virtual_name = (known after apply)
        }
      + network_interface {
          + delete_on_termination = (known after apply)
          + device_index          = (known after apply)
          + network_interface_id  = (known after apply)
        }
      + root_block_device {
          + delete_on_termination = (known after apply)
          + encrypted             = (known after apply)
          + iops                  = (known after apply)
          + kms_key_id            = (known after apply)
          + volume_id             = (known after apply)
          + volume_size           = (known after apply)
          + volume_type           = (known after apply)
        }
    }
Plan: 1 to add, 0 to change, 0 to destroy.
------------------------------------------------------------------------
Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.

インスタンスを作成

terraform apply コマンドを使ってインスタンを作成します。
$ terraform apply
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create
Terraform will perform the following actions:
  # aws_instance.example will be created
  + resource "aws_instance" "example" {
      + ami                          = "ami-031b61f0c1afb3454"
      + arn                          = (known after apply)
      + associate_public_ip_address  = (known after apply)
      + availability_zone            = (known after apply)
      + cpu_core_count               = (known after apply)
      + cpu_threads_per_core         = (known after apply)
      + get_password_data            = false
      + host_id                      = (known after apply)
      + id                           = (known after apply)
      + instance_state               = (known after apply)
      + instance_type                = "t3.nano"
      + ipv6_address_count           = (known after apply)
      + ipv6_addresses               = (known after apply)
      + key_name                     = (known after apply)
      + network_interface_id         = (known after apply)
      + password_data                = (known after apply)
      + placement_group              = (known after apply)
      + primary_network_interface_id = (known after apply)
      + private_dns                  = (known after apply)
      + private_ip                   = (known after apply)
      + public_dns                   = (known after apply)
      + public_ip                    = (known after apply)
      + security_groups              = (known after apply)
      + source_dest_check            = true
      + subnet_id                    = (known after apply)
      + tenancy                      = (known after apply)
      + volume_tags                  = (known after apply)
      + vpc_security_group_ids       = (known after apply)
      + ebs_block_device {
          + delete_on_termination = (known after apply)
          + device_name           = (known after apply)
          + encrypted             = (known after apply)
          + iops                  = (known after apply)
          + kms_key_id            = (known after apply)
          + snapshot_id           = (known after apply)
          + volume_id             = (known after apply)
          + volume_size           = (known after apply)
          + volume_type           = (known after apply)
        }
      + ephemeral_block_device {
          + device_name  = (known after apply)
          + no_device    = (known after apply)
          + virtual_name = (known after apply)
        }
      + network_interface {
          + delete_on_termination = (known after apply)
          + device_index          = (known after apply)
          + network_interface_id  = (known after apply)
        }
      + root_block_device {
          + delete_on_termination = (known after apply)
          + encrypted             = (known after apply)
          + iops                  = (known after apply)
          + kms_key_id            = (known after apply)
          + volume_id             = (known after apply)
          + volume_size           = (known after apply)
          + volume_type           = (known after apply)
        }
    }
Plan: 1 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.
  Enter a value: yes
aws_instance.example: Creating...
aws_instance.example: Still creating... [10s elapsed]
aws_instance.example: Creation complete after 16s [id=i-054c4a5d5f65d7633]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

作成したインスタンを確認

terraform show コマンドを使ってインスタンを確認します。

$ terraform show
# aws_instance.example:
resource "aws_instance" "example" {
    ami                          = "ami-031b61f0c1afb3454"
    arn                          = "arn:aws:ec2:ap-northeast-1:994787028884:instance/i-054c4a5d5f65d7633"
    associate_public_ip_address  = true
    availability_zone            = "ap-northeast-1a"
    cpu_core_count               = 1
    cpu_threads_per_core         = 2
    disable_api_termination      = false
    ebs_optimized                = false
    get_password_data            = false
    id                           = "i-054c4a5d5f65d7633"
    instance_state               = "running"
    instance_type                = "t3.nano"
    ipv6_address_count           = 0
    ipv6_addresses               = []
    monitoring                   = false
    primary_network_interface_id = "eni-068a1099ebe134ed4"
    private_dns                  = "ip-172-31-45-252.ap-northeast-1.compute.internal"
    private_ip                   = "172.31.45.252"
    public_dns                   = "ec2-13-231-108-188.ap-northeast-1.compute.amazonaws.com"
    public_ip                    = "13.231.108.188"
    security_groups              = [
        "default",
    ]
    source_dest_check            = true
    subnet_id                    = "subnet-8a04efc2"
    tenancy                      = "default"
    volume_tags                  = {}
    vpc_security_group_ids       = [
        "sg-3b359644",
    ]
    credit_specification {
        cpu_credits = "unlimited"
    }
    root_block_device {
        delete_on_termination = true
        encrypted             = false
        iops                  = 300
        volume_id             = "vol-03eedb71c41a89002"
        volume_size           = 100
        volume_type           = "gp2"
    }
}

2019年8月28日水曜日

macにTerraformをインストールする方法

まず、Terraformの公式ダウンロードページから対応OSのパッケージをダウンロードします。

ファイルダウンロード後解凍します。そしたらterraformという名前のファイルが表示されます。

前のステップで獲得した「terraform」ファイルを自分のPATHディレクトリーにコピーあるいは移動します。

PATHディレクトリーを確認するには、echo $PATHコマンドを使います。


$ echo $PATH
 /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
上記のように、PATHディレクトリーが表示されました。
自分の場合はファイルを/usr/local/binにコピーしました。

最後動作確認


terraform --versionをうつとバージョン情報が表示されるはずです。


$ terraform --version
 Terraform v0.12.7