ウェブサイト検索

AWS S3バケットでTerraformの状態を管理する方法


AWS S3バケットでTerraformの状態を管理する方法

このページで

  1. 前提条件
  2. 私たちが何をするか
  3. S3バケットを作成し、それにポリシーを添付してください。
  4. Terraformを使用してDynamoDBテーブルを作成する
  5. 結論

この記事では、Terraformの状態とは何か、またそれをS3バケットでどのように管理するかを見ていきます。また、Terraformでの「ロック」が何であるか、そしてそれをどのように実装するかも見ていきます。これを実装するためには、AWS上でS3バケットとDynamoDBテーブルを作成する必要があります。

進む前に、Terraformの状態とロックの基本を理解しましょう。

  • Terraformの状態 (terraform.tstateファイル):
    状態ファイルには、Terraformの設定ファイルで定義されたリソースに関する情報が含まれています。例えば、Terraformの設定を使用してEC2インスタンスを作成した場合、状態ファイルにはAWSで作成された実際のリソースに関する情報が含まれています。
  • S3をバックエンドとして状態ファイルを保存する:
    チームで作業している場合、チームの人々がアクセスできるように、Terraformの状態ファイルをリモートで保存することが良いです。状態をリモートで保存するためには、状態ファイルを保存するS3バケットとTerraform S3バックエンドリソースの2つが必要です。
  • ロック:
    状態ファイルをリモートに保存して多くの人がアクセスできるようにすると、複数の人が同時に同じファイルに変更を加えようとするリスクがあります。したがって、他のユーザーによって現在使用中である場合に状態を「ロック」するメカニズムが必要です。これを達成するために、Terraformが使用するためのDynamoDBテーブルを作成できます。

ここでは、手動でS3バケットを作成し、必要なポリシーを追加し、Terraformを使用してDynamoDBテーブルを作成し、TerraformをS3をバックエンドとして使用するように構成し、DynamoDBをロックを保存するために使用するためのすべてのステップを見ていきます。

前提条件

  1. Terraformの基本的な理解。
  2. S3バケットの基本的な理解。
  3. Terraformがあなたのシステムにインストールされました。
  4. AWSアカウント(持っていない場合は作成してください)。
  5. AWS IAMユーザーの「アクセスキー」と「シークレットキー」。(AWSで「アクセスキー」と「シークレットキー」を持つIAMユーザーを作成する方法を学ぶには、ここをクリックしてください。)

私たちがすること

  1. S3バケットを作成し、それにポリシーを添付してください。
  2. Terraformを使用してDynamoDBテーブルを作成する
  3. Terraformの構成ファイルを使用してEC2を作成します。
  4. Terraformを使用して作成したEC2インスタンスを削除します。

S3バケットを作成し、それにポリシーを添付してください。

ここをクリックして、AWSアカウントでS3バケットを作成する方法を学びましょう。バケットを作成したら、以下のポリシーをそれに添付してください。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt1560164441598",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "s3:PutObject*",
                "s3:List*",
                "s3:Get*",
                "s3:Delete*"
            ],
            "Resource": [
                "arn:aws:s3:::state-lock-rahul",
                "arn:aws:s3:::state-lock-rahul/*"
            ]
        }
    ]
}

CLIからアカウントにアクセスできるように、「AWS_ACCESS_KEY_ID」と「AWS_SECRET_ACCESS_KEY」を設定してください。

以下のコマンドを使用して「AWS_ACCESS_KEY_ID」と「AWS_SECRET_ACCESS_KEY」の値をエクスポートします

export AWS_ACCESS_KEY_ID=AKIAQ6GAIA5XC2XMMM7W
export AWS_SECRET_ACCESS_KEY=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
echo $AWS_ACCESS_KEY_ID
echo $AWS_SECRET_ACCESS_KEY

資格情報を設定した後は、次のコマンドを使用してバケットを一覧表示することで簡単にテストできます。

aws s3 ls

Terraformを使用してDynamoDBテーブルを作成する

'variables.tf'を作成し、必要な変数の宣言を含めます。

vim variables.tf

variable "region" {
     description = "Region of AWS VPC"
}

'main.tf'を作成してください。これはDynamoDBテーブルを作成するためのものです。このmain.tfはvariables.tfから変数の値を読み込みます。このテーブルはロックを保存するために使用されます。

provider "aws" {
      region     = "${var.region}"
}
resource "aws_dynamodb_table" "terraform_locks" {
  name         = "rahul-test-dynamodb-table"
  billing_mode = "PAY_PER_REQUEST"
  hash_key     = "LockID"
  attribute {
    name = "LockID"
    type = "S"
  }
}

最初に使用するコマンドは「terraform init」です。このコマンドは、構成内で使用されるプロバイダーのプラグインをダウンロードしてインストールします。私たちの場合、これはAWSです。

terraform init

2番目のコマンドは「terraform plan」です。このコマンドは、インフラストラクチャにおいてどのような変更が行われるかを確認するために使用されます。

テラフォーム プラン

'terraform apply' コマンドは、main.tf ファイルに記載された AWS 上にリソースを作成します。リソースを作成するための入力を求められます。

terraform apply

今、コンソールのDynamoDBダッシュボードに行って、テーブルが作成されているかどうかを確認できます。

これまでのところ、私たちはS3コンソールから手動でS3バケットを作成し、Terraformを使ってDynamoDBテーブルを作成しました。S3バケットを状態を保存するためのバックエンドとして設定せず、DynamoDBテーブルをロックを保存するために設定していません。

私たちの目標を達成するためには、Terraformのmain.tfファイルを変更する必要があります。コードを変更して実行した後、既存のローカル状態がS3バックエンドにコピーされます。

以下のコードで既存のmain.tfを更新してください。

vim main.tf

provider "aws" {
      region     = "${var.region}"
}
 
 
terraform {
  backend "s3" {
    bucket         = "state-lock-rahul"
    key            = "test/terraform.tfstate"
    region         = "eu-west-3"
    dynamodb_table = "rahul-test-dynamodb-table"
  }
}
 
 
resource "aws_dynamodb_table" "terraform_locks" {
  name         = "rahul-test-dynamodb-table"
  billing_mode = "PAY_PER_REQUEST"
  hash_key     = "LockID"
  attribute {
    name = "LockID"
    type = "S"
  }
}

今、「terraform plan」コマンドを実行して新しいリソースがどのように作成されるかを確認すると、そのコマンドは次のエラーで失敗します。

バックエンドを再初期化するように求められます。

バックエンドを再初期化するには、「terraform init」コマンドを使用します。このステップでは、ローカルの状態ファイルがS3バケットにコピーされます。

terraform init

下のスクリーンショットに示されているように、「terraform init」コマンドを実行した後、出力を観察できます。Terraformはロックを取得するためにDynamoDbテーブルを使用できるようになりました。ロックが有効になると、同じリソースに対して同時に同じ操作を2つ実行することはできません。

AWS コンソールから S3 ダッシュボードにアクセスして、terraform.tfstate がコピーされているかどうかを確認できます。

さて、再び新しいリソースを作成することができ、その状態がS3バケットに保存されるのを確認できます。新しいDynamoDBのテストテーブルを作成するには、main.tfファイルを以下のコードで更新してください。

vim main.tf

variable "region" {
     description = "Region of AWS VPC"
}

Rahuls-MacBook-Pro:terraform rahul$ cat main.tf 
provider "aws" {
      region     = "${var.region}"
}


terraform {
  backend "s3" {
    bucket         = "state-lock-rahul"
    key            = "test/terraform.tfstate"
    region         = "eu-west-3"
    dynamodb_table = "rahul-test-dynamodb-table"
  }
}

resource "aws_dynamodb_table" "terraform_locks" {
  name         = "rahul-test-dynamodb-table"
  billing_mode = "PAY_PER_REQUEST"
  hash_key     = "LockID"
  attribute {
    name = "LockID"
    type = "S"
  }
}


resource "aws_dynamodb_table" "test-table" {
  name         = "rahul-test-table"
  billing_mode = "PAY_PER_REQUEST"
  hash_key     = "LockID"
  attribute {
    name = "LockID"
    type = "S"
  }
}

今回は、プロバイダーにバックエンドの変更がないため、「terraform init」を実行する必要はありません。

新しいリソースがどのように作成されるかを見るために、単に「terraform plan」コマンドを使用できます。

terraform プラン

次に、新しいDynamoDbテストテーブルを作成するために次のコマンドを実行してください。

テラフォームを適用する

上のスクリーンショットでは、ロッキングが有効になっていることがわかります。.tfstateファイルがS3にコピーされています。

さて、コンソールでは新しいテーブルが作成されたことが見えます。

Terraformを使用して作成したリソースがもはや必要でない場合は、次のコマンドを使用してリソースを削除します。

terraform destroy

リソースを削除すると、ロックに使用されていたテーブルも削除されていることがわかります。S3バケットも必要ない場合は、コンソールから削除できます。

結論

この記事では、Terraformでリモートステートとロッキングを使用する必要性について学びました。Terraformのステートを保存するためにS3バケットをバックエンドとして使用し、ロッキングを有効にするためにDynamoDbテーブルを使用する手順を見ました。

関連記事: