この記事では、Terraformの状態とは何か、S3バケットでそれを管理する方法について説明します。また、Terraformの「ロック」とは何か、およびそれを実装する方法についても説明します。これを実装するには、AWSでS3バケットとDynamoDBテーブルを作成する必要があります。
先に進む前に、Terraformの状態とロックの基本を理解しましょう。
- Terraform State (terraform.tstateファイル):
状態ファイルには、terraform構成ファイルで定義されている存在するリソースに関する情報が含まれています。たとえば、terraform configを使用してEC2インスタンスを作成した場合、状態ファイルにはAWSで作成された実際のリソースに関する情報が含まれます。 - 状態ファイルを保存するためのバックエンドとしてのS3 :
チームで作業している場合は、チームのメンバーがアクセスできるように、テラフォーム状態ファイルをリモートで保存することをお勧めします。状態をリモートで保存するには、状態ファイルを保存するためのs3バケットとterraforms3バックエンドリソースの2つが必要です。 - ロック :
多くの人がアクセスできるように状態ファイルをリモートに保存すると、複数の人がまったく同時に同じファイルに変更を加えようとするリスクがあります。そのため、現在他のユーザーが使用している場合に状態を「ロック」するメカニズムが必要です。これは、テラフォームで使用するdynamoDBテーブルを作成することで実現できます。
ここでは、S3バケットを手動で作成し、必要なポリシーを追加し、Terraformを使用してDynamoDBテーブルを作成し、S3をバックエンドとして使用するようにTerraformを構成するすべての手順を説明します。ロックを保存するためのDynamoDB。
前提条件
- Terraformの基本的な理解。
- S3バケットの基本的な理解。
- システムにインストールされているTerraform。
- AWSアカウント(アカウントがない場合は作成します)。
- AWSIAMユーザーの「access_key」と「secret_key」。 (AWSで「access_key」と「secret_key」を使用してIAMユーザーを作成する方法については、ここをクリックしてください)
何をするか
- S3バケットを作成し、それにポリシーを添付します。
- Terraformを使用してDynamoDBテーブルを作成する
- Terraform構成ファイルを使用してEC2を作成します。
- 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変数.tf
variable "region" { description = "Region of AWS VPC" }
DynamoDBテーブルの作成を担当する「main.tf」を作成します。この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"
}
}
最初に使用するコマンドは「terraforminit」です。このコマンドは、構成内で使用されるプロバイダーのプラグインをダウンロードしてインストールします。私たちの場合はAWSです。
terraform init
使用する2番目のコマンドは「terraformplan」です。このコマンドは、インフラストラクチャで行われる変更を確認するために使用されます。
テラフォームプラン
'terraform apply'コマンドは、main.tfファイルに記載されているAWSにリソースを作成します。リソースを作成するための入力を入力するように求められます。
テラフォーム適用
これで、コンソールのDynamoDBダッシュボードに移動して、テーブルが作成されているかどうかを確認できます。
この時点まで、Terraformを使用してS3コンソールとDynamoDBテーブルから手動でS3バケットを作成しました。状態を保存するためのバックエンドとしてのS3バケットと、ロックを保存するためのDynamoDBテーブルを構成していません。
目標を達成するには、Terraformmain.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」コマンドを試して、作成される新しいリソースを確認すると、コマンドは次のエラーで失敗します。
バックエンドを再初期化するように求められます。
バックエンドを再初期化するには、「terraforminit」コマンドを使用します。このステップで、ローカル状態ファイルがS3バケットにコピーされます。
terraform init
「terraforminit」コマンドを実行すると、以下のスクリーンショットに示すような出力を確認できます。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" } }
今回は、プロバイダーへのバックエンドに変更がないため、「terraforminit」を実行する必要はありません。
「terraformplan」コマンドを使用するだけで、作成される新しいリソースを確認できます。
テラフォームプラン
次に、次のコマンドを実行して、新しいDynamoDbテストテーブルを作成します。
テラフォーム適用
上のスクリーンショットでは、ロックが有効になっていて、.tfstateファイルがS3にコピーされていることがわかります。
これで、コンソールで新しいテーブルが作成されたことがわかります
これで、Terraformを使用して作成したリソースが不要になった場合は、次のコマンドを使用してリソースを削除します。
テラフォーム破壊
リソースを削除するとすぐに、ロックに使用されていたテーブルも削除されていることがわかります。 S3バケットも必要ない場合は、コンソールから削除できます。
結論
この記事では、リモート状態を使用してTerraformでロックする必要性について学びました。 S3バケットをバックエンドとして使用してTerraformStateとDynamoDbテーブルを保存し、ロックを有効にする手順を確認しました。