🧚‍♀️

ゆるりっとIaCをやってみよう #1 s3bucket

2022/02/19に公開

こんにちは。ゆるりっとIaCをやってみようの第1回ということで

https://zenn.dev/yururitto_ryuji/articles/66946119e1ceb2

にて記載したように、今回からAWSに環境を作っていこうと思います。
AnsibleやTerraform、その他ツール類のセットアップ方法については割愛させて頂きますので、
ご利用の環境に合わせて用意してください。

今回はTerraformを使ってAWSにリソースを作っていきます。

現在の状態(構成図)

はい、もちろん空っぽです

まずは今後のための準備

terraformで環境を作っていくにあたって大事なものを準備していきます。

「terraform.tfstate」というリソースの構成状態を記録しているファイルがあります

これはterraformを実行すると実行したディレクトリに生成・更新されていくのですが、
複数人で運用するとなるとどれが最新のリソース情報なのか分からなくなってしまう。
という事で、tfstateファイルをaws s3に保存していくようにします。
まず最初のステップはtfstate用の管理bucketを作ってみます。

terraform
├── .envrc # 環境変数にawsのプロフィール情報をセット
├── .terraform-version # terraformのバージョン固定ファイル
└── yururitto-aws # 今回作成する環境のディレクトリ
    └── common # ここにtfファイルを作っていきます

(フォルダやファイルの構成については学習しつつ模索中)
ここに3つのファイルを作ってみましょう。

1つ目:common/terraform.tf

ここにはterraformそのものの設定を書いていきます。
公式:プロバイダー一覧
今回はAWSを使うのでProviderはAWSを指定、terraformのバージョンは1.1系にしてますが
.terraform-versionで1.1.3に固定してます。

# terraform自体の情報
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.2.0"
    }
  }

  required_version = "~> 1.1.3"
}

2つ目:common/provider.tf

ここにはプロバイダーに関する情報を書き込んでいきます。
公式:Provider Configuration
ファイル名とかフォルダの構造は調べると色々なパターンがあって、これは自分が作りたいインフラの構成とか運用の事を考えて管理しやすい形を模索していくのがbestなのかなーと思いました(小並感)

# providerの設定
provider "aws" {
  region = "ap-northeast-1"
  default_tags { # terraformで作成されたリソースに共通して付けるタグを設定
    tags = {
      Managed = "terraform"
      Environments = "dev"
      Service = "Yururitto"
    }
  }
}

3つ目:common/resource_s3_bucket

最後に作成するリソース本体のファイルです。
公式:aws_s3_bucket

# (1) バケットの作成
resource "aws_s3_bucket" "common_bucket" {
  bucket = "yururitto-tfstate-backet"
    tags = {
      Name     = "yururitto-tfstate-backet"
      Category = "Ops"
  }
}
# (2) アクセス権限に関する設定
resource "aws_s3_bucket_acl" "common_bucket" {
  bucket = aws_s3_bucket.common_bucket.id
  acl    = "private"
}

# (3)バージョニングに関する設定
resource "aws_s3_bucket_versioning" "common_versioning" {
  bucket = aws_s3_bucket.common_bucket.id
  versioning_configuration {
    status = "Enabled"
  }
}

という感じで書いてみました。
公式ページを読むのが一番なのですが、個人的には実際のAWSコンソールを見て
ここに設定したいから対応するものってどれかな?という感じで見比べるとイメージ
し易いなと思っています。

実行準備:terraform init

まずは実行するディレクトリで terraform init を実行して初期化し、必要なファイルを生成します。

$ cd terraform/common/
$ terraform init

Initializing the backend...

Initializing provider plugins...
- Finding hashicorp/aws versions matching "~> 4.2.0"...
- Installing hashicorp/aws v4.2.0...
- Installed hashicorp/aws v4.2.0 (signed by HashiCorp)

Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.

Terraform has been successfully initialized!

確認してみます:terraform plan

ここまで準備できたら terraform plan という確認コマンドを実行してみます。

# terraformは実行するカレントディレクトリにあるtfファイルが全てが対象になります
$ terraform plan

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_s3_bucket.common_bucket will be created
  + resource "aws_s3_bucket" "common_bucket" {
      + acceleration_status                  = (known after apply)
      + acl                                  = (known after apply)
      + arn                                  = (known after apply)
      + bucket                               = "yururitto-tfstate-backet"
      + bucket_domain_name                   = (known after apply)
      + bucket_regional_domain_name          = (known after apply)
      + cors_rule                            = (known after apply)
      + force_destroy                        = false
      + grant                                = (known after apply)
      + hosted_zone_id                       = (known after apply)
      + id                                   = (known after apply)
      + lifecycle_rule                       = (known after apply)
      + logging                              = (known after apply)
      + policy                               = (known after apply)
      + region                               = (known after apply)
      + replication_configuration            = (known after apply)
      + request_payer                        = (known after apply)
      + server_side_encryption_configuration = (known after apply)
      + tags                                 = {
          + "Category" = "Ops"
          + "Name"     = "yururitto-tfstate-backet"
        }
      + tags_all                             = {
          + "Category"     = "Ops"
          + "Environments" = "dev"
          + "Managed"      = "terraform"
          + "Name"         = "yururitto-tfstate-backet"
          + "Service"      = "Yururitto"
        }
      + versioning                           = (known after apply)
      + website                              = (known after apply)
      + website_domain                       = (known after apply)
      + website_endpoint                     = (known after apply)

      + object_lock_configuration {
          + object_lock_enabled = (known after apply)
          + rule                = (known after apply)
        }
    }

  # aws_s3_bucket_acl.common_bucket will be created
  + resource "aws_s3_bucket_acl" "common_bucket" {
      + acl    = "private"
      + bucket = (known after apply)
      + id     = (known after apply)

      + access_control_policy {
          + grant {
              + permission = (known after apply)

              + grantee {
                  + display_name  = (known after apply)
                  + email_address = (known after apply)
                  + id            = (known after apply)
                  + type          = (known after apply)
                  + uri           = (known after apply)
                }
            }

          + owner {
              + display_name = (known after apply)
              + id           = (known after apply)
            }
        }
    }

  # aws_s3_bucket_versioning.common_versioning will be created
  + resource "aws_s3_bucket_versioning" "common_versioning" {
      + bucket = (known after apply)
      + id     = (known after apply)

      + versioning_configuration {
          + mfa_delete = (known after apply)
          + status     = "Enabled"
        }
    }

Plan: 3 to add, 0 to change, 0 to destroy.

resource_s3_bucket.tfで設定した内容が反映されているようです。

Plan: 3 to add, 0 to change, 0 to destroy.

確認の結果、3つのリソースが追加されて、変更0、削除0という結果になりました。

IaCの第1歩!:terraform apply

さて、planも無事通過したので、いよいよs3 bucketを作成です!!
planと同じように、実行の内容が出力されたあとに yes を入力して実行してみます。

$ terraform apply

(中略)

Plan: 3 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:

どきどき・・・

  Enter a value: yes

aws_s3_bucket.common_bucket: Creating...
aws_s3_bucket.common_bucket: Creation complete after 2s [id=yururitto-tfstate-backet]
aws_s3_bucket_versioning.common_versioning: Creating...
aws_s3_bucket_acl.common_bucket: Creating...
aws_s3_bucket_acl.common_bucket: Creation complete after 1s [id=yururitto-tfstate-backet,private]
aws_s3_bucket_versioning.common_versioning: Creation complete after 2s [id=yururitto-tfstate-backet]

Apply complete! Resources: 3 added, 0 changed, 0 destroyed.

complate!! なんて甘美な響きでしょう
コンソールの方も確認してみましょう

でっ・・・できらぁ!

という事で、バケットが作られてバージョニングも有効、タグも入っていて完璧です。

最終的なディレクトリの中身はこんな感じです。

./
├── .terraform
│   └── providers
├── .terraform.lock.hcl
├── provider.tf
├── resource_s3_bucket.tf
├── terraform.tf
└── terraform.tfstate # これが冒頭のtfstateファイルです

今回の結果

今回はs3バケットを作成してtfstateファイルを共有できるようにしました。
次回はVPCを作成していこうと思いますので、ゆるりっとお付き合いくださいませ

ありがとうございました。

Discussion