AWS

Cloud9にTerraform環境を作ってみる

Cloud9でTerraform

どこでも同じ環境が使えるAWS Cloud9は便利です。
しかし、Cloud9そのものの設定は必要です。

この記事では、Cloud9でTerraformを使えるように設定する方法を紹介します。
ただ単にTerraformを利用するだけではなく、TFLintやtfsecの導入まで行います。

対象読者
  • AWS Cloud9環境でTerraformを使いたい!
  • TFLintとtfsecの導入方法と使い方を知りたい!
  • Terraformを実行するのに必要な設定を知りたい!
  • でもTerraformもTFLintもtfsecもなんもわからん……

この記事でやること
  • AWS Cloud9でTerraform実行環境作成
  • tfenvインストール
  • TFLintとtfsecのインストールと設定
  • Terraformの一連の使い方理解

Cloud9環境作成

まずはCloud9でベースとなる作業環境構築を行います。
Cloud9はクラウドの統合開発環境のようなものです。

  • Cloud9を利用する理由は、この記事を読んでいる皆さんでも再現可能とするためです
  • クラウド環境なので各環境に関わらず同じ設定にできます
  • どこでも同じ環境が使えるようになるというメリットもあります
  • サービス一覧からCloud9を選択
  • Create environmentを選択して、環境を新規作成
  • NameとDescriptionはお好みで設定
    ここでは、Tarraformとしておきます
  • 設定できたらNext stepを選択
  • Environment settingsの設定はデフォルトのままでOKです
    詳細が知りたい方は参考サイト参照
  • そのままNext stepを選択
  • 設定に問題がなければCreate environmentを選択
  • 作成完了までちょっと待ちます
    完了後、以下のようなWelcome画面が表示されます

これでベースとなる環境ができました!
次はTerraformを利用する環境を作っていきます

Terraformのインストール

まずは、Cloud9のAMTC(AWS Managed Temporary Credentials)を無効化し、AWS CLIでフルアクセス権限を設定します。

その後、tfenvを利用してTerraformをインストールします。

Cloud9のAMTC無効化

一応AMTCを無効化します。

  • Cloud9の画面のPreferenceを選択して、設定画面を開きます
  • AWS Settingsを選択し、CredentialsのAWS managed temporary credentialsをOFFにします

Cloud9のEC2用のIAMロール作成

続いて、Cloud9のEC2用にIAMロールを作成します。
Cloud9はEC2上で動作しているため、Cloud9が利用しているEC2インスタンス用のロールを作成すればよいです。
今回はAdministratorAccessポリシーを割り当てます。

  • Terraformの動作に影響がないようにフルアクセス可能なAdministratorAccessポリシーを使用します

まずはCloud9のEC2インスタンス用のIAM Roleを作成します。

  • サービス一覧からIAMを選択
  • アクセス管理からロールを選択して、ロールを作成を選択
  • EC2のロールなので、AWSサービスEC2を選択します。
  • 次のステップ:アクセス権限を選択
  • ポリシーのフィルタAdministratorAccessと入力してAdministratorAccessポリシーを検索します
  • AdministratorAccessを選択して、次のステップ:タグを選択
  • タグはなしで、そのまま次のステップ:確認を選択。
  • 最後にロール名を付けます
    今回はCloud9ForTerraformとしますが、お好きな名前でも構いません
  • ロール名を設定したらロールの作成
  • ロール一覧画面に戻るので、検索バーCloud9ForTerraformと入力してロールが作成できていることを確認します。

Cloud9のEC2にIAMロールアタッチ

続いて、作成したIAMロールをEC2に割り当てます。

  • サービス一覧からEC2を選択
  • インスタンスを選択し、検索バーにaws-cloud9-Terraformと入力して、今回作成したCloud9のEC2インスタンスを特定します
  • EC2インスタンスをチェックし、アクションセキュリティIAMロールを変更を選択していきます
  • IAMロールを変更画面になるので、先ほど作成したCloud9用のIAMロール(Cloud9ForTerraform)を選択し、保存を選択します

これでロールが変更できました。

Cloud9のbash

今後、コマンドを実行する際はCloud9のBashで行います。
赤枠で囲んだ場所です。

tfenvインストール

続いて、tfenvを利用して任意のTerrafomをインストールしていきます。

  • tfenvとはTerraformのバージョン管理を行うためのツールです
  • チーム開発などを考慮して、バージョンはいつでも変更可能にしてくため導入します

tfenvのGitHubの手順を参考にしてインストールを行います。
コマンドはCloud9のIDEのbashから実行してください。

  • まずは必要なファイルをGitHubから取得してホームディレクトリ配下(~/.tfenv)に配置
$ git clone https://github.com/tfutils/tfenv.git ~/.tfenv
Cloning into '/home/ec2-user/.tfenv'...
remote: Enumerating objects: 1559, done.
remote: Counting objects: 100% (374/374), done.
remote: Compressing objects: 100% (147/147), done.
remote: Total 1559 (delta 233), reused 334 (delta 213), pack-reused 1185
Receiving objects: 100% (1559/1559), 336.28 KiB | 6.34 MiB/s, done.
Resolving deltas: 100% (996/996), done.
  • 実行配置したファイルのシンボリックリンクを/usr/local/binに配置し、コマンドが実行できるようにします
    2,4行目のコマンドで作成結果を確認しています
$ sudo ln -s ~/.tfenv/bin/* /usr/local/bin
$ ll /usr/local/bin/terraform 
lrwxrwxrwx 1 root root 35 Jan  8 13:44 /usr/local/bin/terraform -> /home/ec2-user/.tfenv/bin/terraform
$ ll /usr/local/bin/tfenv
lrwxrwxrwx 1 root root 31 Jan  8 13:44 /usr/local/bin/tfenv -> /home/ec2-user/.tfenv/bin/tfenv

/usr/loca/binに配置するとコマンドとしてすぐに呼び出すことが可能になります

  • これでtfenvコマンドが実行可能になったので、tfenv list-remoteでインストール可能なterraformのバージョンを確認します
$ tfenv list-remote
1.1.3
1.1.2
1.1.1
1.1.0
1.1.0-rc1
(長いので途中省略)
0.2.2
0.2.1
0.2.0
0.1.1
0.1.0
  • TerraformのGitHubを確認したところ、記事執筆時点(2020/01/08)での最新のバージョンまでちゃんとインストール可能でした

$ tfenv install 1.1.0
Installing Terraform v1.1.0
Downloading release tarball from https://releases.hashicorp.com/terraform/1.1.0/terraform_1.1.0_linux_amd64.zip
################################################################################################################################################################################ 100.0%
Downloading SHA hash file from https://releases.hashicorp.com/terraform/1.1.0/terraform_1.1.0_SHA256SUMS
No keybase install found, skipping OpenPGP signature verification
terraform_1.1.0_linux_amd64.zip: OK
Archive:  /tmp/tfenv_download.nksXj7/terraform_1.1.0_linux_amd64.zip
  inflating: /home/ec2-user/.tfenv/versions/1.1.0/terraform  
Installation of terraform v1.1.0 successful. To make this your default version, run 'tfenv use 1.1.0'
  • tfenv useを実行して、インストールしたterraformの最新バージョンをデフォルトのバージョンとしてに設定します
    設定しないとterraformは使えません!
$ tfenv use 1.1.0
Switching default version to v1.1.0
Switching completed
  • そして、現在設定されているTerraformのバージョンを確認します
    使用したいバージョンの前に*(アスタリスク)が付いていればOKです!
$ tfenv list
* 1.1.0 (set by /home/ec2-user/.tfenv/version)
  • 最後に、terraformコマンドからTerraform自体のバージョンを確認します
    最新のバージョンの案内が出ますが無視してくださいー
$ terraform --version
Terraform v1.1.0
on linux_amd64

Your version of Terraform is out of date! The latest version
is 1.1.3. You can update by downloading from https://www.terraform.io/downloads.html

これでTerraformのインストールが完了しました。
Terraformの別のバージョンを利用したい場合は、tfenvを利用していつでも可能になっています!

TFLintのインストール

今度はLinterであるTFLintをインストールしていきます。

  • TFLintとはTerraformのためのLinterです
  • Linterとは静的解析ツールで、ソースコードを解析して問題点を指摘してくれます
  • 構文的には問題ないけど、値としてはおかしいものの検知に役立ちます

tflintのGitHubの手順を参考にしてインストールを行います。
tflintとTerraformは対応バージョンがあるので、対応したものをインストールしてあげます

コマンドはCloud9のIDEのbashから実行してください。

  • TFLintをインストールします
    インストールコマンドを実行すると自動で記事執筆時点の最新バージョンである0.34.1をインストールしてくれます
$ curl -s https://raw.githubusercontent.com/terraform-linters/tflint/master/install_linux.sh | bash
os=linux_amd64


====================================================
Looking up the latest version ...
Downloading TFLint v0.34.1
Downloaded successfully


====================================================
Unpacking /tmp/tflint.zip ...
Archive:  /tmp/tflint.zip
  inflating: /tmp/tflint             
Installing /tmp/tflint to /usr/local/bin/...
‘/tmp/tflint’ -> ‘/usr/local/bin/tflint’
tflint installed at /usr/local/bin/ successfully
Cleaning /tmp/tflint.zip and /tmp/tflint ...


====================================================
Current tflint version
TFLint version 0.34.1
  • インストールされたTFLintのバージョンを確認します
    インストールした0.34.1が出ればOKです!
$ tflint --version
TFLint version 0.34.1

これでTFLintも利用可能な状態になりました!

tfsecのインストール

最後のツールとしてtfsecをインストールしていきます。
セキュリティ的な問題を指摘してくれるので、導入したほうがいいです!

  • tfsecではTerraformのソースコードを静的解析し、潜在的なセキュリティ的な問題を検知してくれます
  • 構文的には問題がなくてもセキュリティの問題を見つけてくれます

tfsecのGitHubにてLinux用のバイナリが提供されているので、これを利用します。
Cloud9環境の実態はAmazon Linuxなのでtfsec-linux-amd64を利用します。

  • 最新バージョンのtfsecバイナリをダウンロードします
    ダウンロードしたらファイルがあることを確認しましょう
  • 記事執筆時点での最新であるv0.63.1を使用します
$ curl -L https://github.com/aquasecurity/tfsec/releases/download/v0.63.1/tfsec-linux-amd64 --output tfsec
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   656  100   656    0     0   2703      0 --:--:-- --:--:-- --:--:--  2710
100 12.4M  100 12.4M    0     0  9134k      0  0:00:01  0:00:01 --:--:-- 13.2M
$ ll tfsec 
-rw-rw-r-- 1 ec2-user ec2-user 13033472 Jan 11 13:55 tfsec
  • ダウンロードしたtfsecのバイナリに実行権限を付けます
    その後、/usr/local/bin/配下に移します
$ chmod +x tfsec
$ sudo mv tfsec /usr/local/bin/
$ ll /usr/local/bin/tfsec 
-rwxrwxr-x 1 ec2-user ec2-user 13033472 Jan 11 13:55 /usr/local/bin/tfsec
  • tfsecコマンドが実行できて、バージョンが出力されればインストール完了です!
$ tfsec -v
0.63.1

これで必要なツールが揃いました!!!

Terraformの初期設定

必要なツールが揃ったため、Terrformを実行できるように設定していきます。

Terrafom用のIAMユーザー作成

Terraform専用のユーザーを作成します。

基本的には必要な最小の権限を与えたユーザーを作成すべきなのですが、今回は様々なAWSサービスを利用する検証用ユーザーを想定してAdministratorの権限を利用します

  • AWSのサービス一覧からIAMを選択
  • アクセス管理からユーザーを選択して、ユーザーを追加を選択
  • ユーザー名は任意よいので、ここではTerraformForCloud9とします
  • AWS CLIにユーザー情報を設定するため、AWS認証情報タイプアクセスキー – プログラムによるアクセスにチェックを入れます
  • アクセス権限設定では、既存のポリシーを直接アタッチを選択します
  • 検索バーにAdministratorAccessを入力して、AdministratorAccessにチェックを付けます
  • タグは何も設定しません
  • 確認画面で、作成するユーザーに管理ポリシーのAdministratorAccessがアタッチされていればOKです!
  • ユーザーの作成を選択します
  • 作成したユーザーのアクセスキーIDシークレットアクセスキーが表示されます
    次のAWS CLIセットアップで使用するため画面はそのままにしておきます

AWS CLIのセットアップ

ユーザーが作成できたので、続いてAWS CLIをセットアップします。

公式ドキュメントを参考にインストールしていきます。

  • AWS CLI2のインストーラをダウンロードして解凍します
    解凍後、awsというディレクトリができています
$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 43.4M  100 43.4M    0     0  29.6M      0  0:00:01  0:00:01 --:--:-- 29.6M
$ ll awscliv2.zip 
-rw-rw-r-- 1 ec2-user ec2-user 45601923 Jan 15 03:09 awscliv2.zip

$ unzip awscliv2.zip
(長いので途中省略)
  inflating: aws/dist/cryptography-3.3.2-py3.8.egg-info/WHEEL  
   creating: aws/dist/cryptography/hazmat/
   creating: aws/dist/cryptography/hazmat/bindings/
  inflating: aws/dist/cryptography/hazmat/bindings/_openssl.abi3.so  

$ ls -ld aws                                                                                                                                                     
drwxr-xr-x 3 ec2-user ec2-user 78 Jan 13 22:04 aws
  • AWS CLI2をインストールします
  • aws –versionでバージョンが2.X.XXになっていればOKです!
$ sudo ./aws/install
You can now run: /usr/local/bin/aws --version
$ aws --version
aws-cli/2.4.11 Python/3.8.8 Linux/4.14.256-197.484.amzn2.x86_64 exe/x86_64.amzn.2 prompt/off

Terraform用のユーザー設定

AWS CLIに先ほど作成したユーザーのアクセスキーなどを設定していきます。

公式ドキュメントを参考にインストールします。

  • aws configureを実行し、表示される順番に設定してください
  • リージョンは東京(ap-northeast-1)、アウトプットはデフォルト設定であるjsonで問題ないです
 $ aws configure
AWS Access Key ID [None]: [作成したユーザーのアクセスキーID]
AWS Secret Access Key [None]: [作成したユーザーのシークレットアクセスキー]
Default region name [None]: ap-northeast-1
Default output format [None]: json
  • 正しく設定できているかの確認をします
  • TerraformForCloud9のユーザー情報が返ってくれば、正しく設定できています!
$ aws sts get-caller-identity 
{
    "UserId": "[ユーザーID]",
    "Account": "[アカウント番号]",
    "Arn": "arn:aws:iam::[ユーザー番号]:user/TerraformForCloud9"
}

Terraform実行の流れ

ついにTerraformを実行するときが来ました!
Cloud9のIDEから作業をしていきます

基本となる定義ファイル作成

まずは、基本となる定義ファイルを作成し、初期化を行います

  • Terraform用にディレクトリを作成し、その中にmain.tfファイルを作成して開きます。
  • main.tfに以下を書き込みます
  • providersのawsのバージョンはhashicorp/terraform-provider-awsのGitHubを参考に最新のものにしています
  • default_tagsを設定してTerraformで作成したリソースであることがわかるようにしておくと便利です
terraform {
  # 使用するAWSプロバイダーのバージョン指定(結構更新が速い)
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~>3.72"
    }
  }
}

# 明示的にAWSプロバイダを定義(暗黙的に理解してくれるけど)
provider "aws" {
  profile = "default"
  region  = "ap-northeast-1"

  # 作成する全リソースに自動的に付与するタグ設定
  default_tags {
    tags = {
      env = "terraform_test"
    }
  }
}
  • 暗黙的にデフォルトで設定されるものもわざと記載するようにしています!
  • ファイルに記載している以上のものがないようにする方針を取っています

  • initを実行して、Terraformが実行できるようにします
  • Cloud9のbashでワークディレクトリに移動し、initを実行します
    v3.72以上を指定したので、v3.72のawsプロバイダーがインストールされました
$ pwd
/home/ec2-user/environment/terraform_test
 $ ll
total 4
-rw-r--r-- 1 ec2-user ec2-user 501 Jan 15 04:03 main.tf

 $ terraform init

Initializing the backend...

Initializing provider plugins...
- Finding hashicorp/aws versions matching "~> 3.72"...
- Installing hashicorp/aws v3.72.0...
- Installed hashicorp/aws v3.72.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!

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.
  • awsプロバイダーがインストールされ、awsプロバイダーのバージョン情報がロックファイルとして生成されました
$ ll .terraform/providers/registry.terraform.io/hashicorp/aws/3.72.0/linux_amd64/
total 241552
-rwxr-xr-x 1 ec2-user ec2-user 247349248 Jan 15 04:15 terraform-provider-aws_v3.72.0_x5

$ cat .terraform.lock.hcl | grep version
  version     = "3.72.0"

プロバイダを変更することで、AWSだけでなくGCPやAzureにも対応することができます

S3を作成するリソース定義ファイル作成

テストとして、S3のバケットを作成するリソース定義ファイルを作成してみます。

  • S3リソース作成用にs3.tfファイルを作成して開きます
  • s3.tfに以下を書き込みます
    バケット名(bucket)はグローバルでユニークな名前にする必要があるので、test-bucket-20220122-wasdから適当に書き換えてください
# -----------------------------------
# S3の作成
# -----------------------------------
### バケット作成 ###
resource "aws_s3_bucket" "terraform_test" {
  # S3のバケット名
  bucket = "test-bucket-20220122-wasd" ###要変更###
  # アクセス管理
  acl = "private"
  # バージョニングの有効化
  versioning {
    enabled = true
  }

  server_side_encryption_configuration {
    rule {
      apply_server_side_encryption_by_default {
        sse_algorithm = "AES256"
      }
    }
  }
}

resource "aws_s3_bucket_public_access_block" "terraform_test" {
  # 対象のバケット
  bucket = aws_s3_bucket.terraform_test.id
  # パブリックのアクセスをブロック
  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

今回はS3が作成できることを確認するだけなので、詳細は書きません
バケット名だけ換えて実施してみてください

確認してTerraform実行

リソースを定義するファイルを用意したので、バリデーションチェックから実行まで順番に実施していきます。

  • まずはコードフォーマットを実施して、インデントなどを統一します
  • チーム開発ではインデントなどのフォーマットを統一します
  • 個人の趣味に任せるとバラバラでソースコードが読みにくくなるため、自動で実施してくれる仕組みを作るべきです

 $ terraform fmt -recursive
s3.tf (←フォーマットされたファイル名)
$ terraform fmt -recursive -check
(何も出力なし) 
オプション名内容
-recursiveサブディレクトリ内も見てくれる
-checkフォーマットの修正ができていないファイルがあるか確認
  • 次はバリデーションチェックを実施し、事前に構文エラーを確認します
    問題なければSuccess!と出力されます
$ terraform validate
Success! The configuration is valid.
  • エラーがある場合は以下のようにで出力してくれます
  • 次はtflintを実施し、静的解析をして問題がないか確認します
  • tflint実行のために設定ファイルを作成します
    .tflint.hclファイルを作成して開きます
  • tflintでAWSに関するルールを適用するために、awsのプラグインを有効化する設定を書き込みます
plugin "aws" {
    enabled = true
    version = "0.11.0"
    source  = "github.com/terraform-linters/tflint-ruleset-aws"
}
  • tflintのinitコマンドを実行してプラグインをダウンロードします
    プラグインはホームディレクトリにダウンロードされています
  • tflintを実行し、何も出力されなければOKです!
$ tflint --init
Installing `aws` plugin...
Installed `aws` (source: github.com/terraform-linters/tflint-ruleset-aws, version: 0.11.0)
$ ls -la ~/.tflint.d/plugins/github.com/terraform-linters/tflint-ruleset-aws/0.11.0/tflint-ruleset-aws 
-rwxr-xr-x 1 ec2-user ec2-user 40673280 Jan 22 01:37 /home/ec2-user/.tflint.d/plugins/github.com/terraform-linters/tflint-ruleset-aws/0.11.0/tflint-ruleset-aws

$ tflint --config .tflint.hcl 
(エラーがない場合は出力なし)
  • もしtflintでエラーとなった場合は以下のような感じにで出力されます
  • 次はtfsecを実施して、セキュリティ的な問題がないか確認します
  • 今回はS3のサーバアクセスログを有効にしなさい!と怒られます
    アクセスログはセキュリティやアクセス監査の参考になるため重要ですが、今回はすぐにバケットを削除してしまうので無視します
$ tfsec 

  Result 1

  [aws-s3-enable-bucket-logging][MEDIUM] Resource 'aws_s3_bucket.terraform_test' does not have logging enabled.
  /home/ec2-user/environment/terraform_test/s3.tf:5-22


       2 | # S3の作成
       3 | # -----------------------------------
       4 | ### バケット作成 ###
       5 | resource "aws_s3_bucket" "terraform_test" {
       6 |   # S3のバケット名
       7 |   bucket = "test-bucket-20220122-wasd" ###要変更###
       8 |   # アクセス管理
       9 |   acl = "private"
      10 |   # バージョニングの有効化
      11 |   versioning {
      12 |     enabled = true
      13 |   }
      14 | 
      15 |   server_side_encryption_configuration {
      16 |     rule {
      17 |       apply_server_side_encryption_by_default {
      18 |         sse_algorithm = "AES256"
      19 |       }
      20 |     }
      21 |   }
      22 | }
      23 | 
      24 | resource "aws_s3_bucket_public_access_block" "terraform_test" {
      25 |   # 対象のバケット

  Legacy ID:  AWS002
  Impact:     There is no way to determine the access to this bucket
  Resolution: Add a logging block to the resource to enable access logging

  More Info:
  - https://aquasecurity.github.io/tfsec/latest/checks/aws/s3/enable-bucket-logging 
  - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket 
  - https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerLogs.html 

  times
  ------------------------------------------
  disk i/o             565.501µs
  parsing HCL          11.498µs
  evaluating values    286.382µs
  running checks       5.441751ms

  counts
  ------------------------------------------
  files loaded         2
  blocks               4
  modules              0

  results
  ------------------------------------------
  critical             0
  high                 0
  medium               1
  low                  0
  ignored              0

  1 potential problems detected.
  • 実行前の最後の確認としてTerraformの実行計画を確認します
$ 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.terraform_test will be created
  + resource "aws_s3_bucket" "terraform_test" {
      + acceleration_status         = (known after apply)
      + acl                         = "private"
      + arn                         = (known after apply)
      + bucket                      = "test-bucket-20220122-wasd"
      + bucket_domain_name          = (known after apply)
      + bucket_regional_domain_name = (known after apply)
      + force_destroy               = false
      + hosted_zone_id              = (known after apply)
      + id                          = (known after apply)
      + region                      = (known after apply)
      + request_payer               = (known after apply)
      + tags_all                    = {
          + "env" = "terraform_test"
        }
      + website_domain              = (known after apply)
      + website_endpoint            = (known after apply)

      + server_side_encryption_configuration {
          + rule {
              + apply_server_side_encryption_by_default {
                  + sse_algorithm = "AES256"
                }
            }
        }

      + versioning {
          + enabled    = true
          + mfa_delete = false
        }
    }

  # aws_s3_bucket_public_access_block.terraform_test will be created
  + resource "aws_s3_bucket_public_access_block" "terraform_test" {
      + block_public_acls       = true
      + block_public_policy     = true
      + bucket                  = (known after apply)
      + id                      = (known after apply)
      + ignore_public_acls      = true
      + restrict_public_buckets = true
    }

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

───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.
  • 設定した内容が設定され、想定外の設定がなくて問題がなければ実行してリソースを作成します!
$ terraform apply

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.terraform_test will be created
  + resource "aws_s3_bucket" "terraform_test" {
      + acceleration_status         = (known after apply)
      + acl                         = "private"
      + arn                         = (known after apply)
      + bucket                      = "test-bucket-20220122-wasd"
      + bucket_domain_name          = (known after apply)
      + bucket_regional_domain_name = (known after apply)
      + force_destroy               = false
      + hosted_zone_id              = (known after apply)
      + id                          = (known after apply)
      + region                      = (known after apply)
      + request_payer               = (known after apply)
      + tags_all                    = {
          + "env" = "terraform_test"
        }
      + website_domain              = (known after apply)
      + website_endpoint            = (known after apply)

      + server_side_encryption_configuration {
          + rule {
              + apply_server_side_encryption_by_default {
                  + sse_algorithm = "AES256"
                }
            }
        }

      + versioning {
          + enabled    = true
          + mfa_delete = false
        }
    }

  # aws_s3_bucket_public_access_block.terraform_test will be created
  + resource "aws_s3_bucket_public_access_block" "terraform_test" {
      + block_public_acls       = true
      + block_public_policy     = true
      + bucket                  = (known after apply)
      + id                      = (known after apply)
      + ignore_public_acls      = true
      + restrict_public_buckets = true
    }

Plan: 2 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_s3_bucket.terraform_test: Creating...
aws_s3_bucket.terraform_test: Creation complete after 2s [id=test-bucket-20220122-wasd]
aws_s3_bucket_public_access_block.terraform_test: Creating...
aws_s3_bucket_public_access_block.terraform_test: Creation complete after 1s [id=test-bucket-20220122-wasd]

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

S3のバケットが作成されました!!!
最後に作成されたかを確認してみます

作成したS3バケットを確認

一応、マネジメントコンソールから作成したS3のバケットを確認してみます。

  • AWSのサービス一覧からS3を選択
  • バケットにてバケット名(今回はtest-bucket-20220122-wasd)を検索します
  • 設定した通りのバケット名でバケットが作成されていればOKです!!!!!

作成したS3バケットの削除

今回作成したS3バケットはテスト用で不要なものなので削除しておきます。

  • destroyで削除します
$ terraform destroy
aws_s3_bucket.terraform_test: Refreshing state... [id=test-bucket-20220122-wasd]
aws_s3_bucket_public_access_block.terraform_test: Refreshing state... [id=test-bucket-20220122-wasd]

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

Terraform will perform the following actions:

  # aws_s3_bucket.terraform_test will be destroyed
  - resource "aws_s3_bucket" "terraform_test" {
      - acl                         = "private" -> null
      - arn                         = "arn:aws:s3:::test-bucket-20220122-wasd" -> null
      - bucket                      = "test-bucket-20220122-wasd" -> null
      - bucket_domain_name          = "test-bucket-20220122-wasd.s3.amazonaws.com" -> null
      - bucket_regional_domain_name = "test-bucket-20220122-wasd.s3.ap-northeast-1.amazonaws.com" -> null
      - force_destroy               = false -> null
      - hosted_zone_id              = "Z2M4EHUR26P7ZW" -> null
      - id                          = "test-bucket-20220122-wasd" -> null
      - region                      = "ap-northeast-1" -> null
      - request_payer               = "BucketOwner" -> null
      - tags                        = {} -> null
      - tags_all                    = {
          - "env" = "terraform_test"
        } -> null

      - server_side_encryption_configuration {
          - rule {
              - bucket_key_enabled = false -> null

              - apply_server_side_encryption_by_default {
                  - sse_algorithm = "AES256" -> null
                }
            }
        }

      - versioning {
          - enabled    = true -> null
          - mfa_delete = false -> null
        }
    }

  # aws_s3_bucket_public_access_block.terraform_test will be destroyed
  - resource "aws_s3_bucket_public_access_block" "terraform_test" {
      - block_public_acls       = true -> null
      - block_public_policy     = true -> null
      - bucket                  = "test-bucket-20220122-wasd" -> null
      - id                      = "test-bucket-20220122-wasd" -> null
      - ignore_public_acls      = true -> null
      - restrict_public_buckets = true -> null
    }

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

Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: yes

aws_s3_bucket_public_access_block.terraform_test: Destroying... [id=test-bucket-20220122-wasd]
aws_s3_bucket_public_access_block.terraform_test: Destruction complete after 0s
aws_s3_bucket.terraform_test: Destroying... [id=test-bucket-20220122-wasd]
aws_s3_bucket.terraform_test: Destruction complete after 1s

Destroy complete! Resources: 2 destroyed.
  • 削除後、マネジメントコンソールでも確認します
  • 検索で作成したバケットの名前で検索して、何も出てこなければ削除できています!!!

これでリソースの作成から削除まで実施できあことになります!

まとめ

この記事ではCloud9でTerraformと便利なツールのインストールから最低限の設定を行い、実際にTarraformを実行してリソースを作成してみました。

Terraform実行までの一連の流れがわかったと思いますので、ここからは要望に応じて必要なことを追加すればよいです

もし「設定できない!」や「うまくいかない!」などがありましたら著者のTwitterまでご連絡ください。

次はGitHub Actionsで自動実行できるようにしたいなぁ…

参考サイト・書籍

Cloud9環境作成

AWSドキュメント AWS Cloud9 ユーザーガイド ステップ 1: 環境を作成する

Terraformのインストール

DevelopersIO Cloud9からIAM Roleの権限でAWS CLIを実行する
AWSドキュメント AWS Cloud9 の環境から AWS のサービスを呼び出す
GitHub tfenv README.md
Qiita Cloud9でtfenvを使ってみる
Qiita EC2でtfenvを使ってみる

TFLintのインストール

DevelopersIO Version固定でTFLintをインストールする
GitHub tflint README.md
GitHub TFLint Compatibility with Terraform

★オススメ
Zenn Terraform開発時のDeveloper Experienceを爆上げする

tfsecのインストール

GitHub tfsec README.md
Terraformのセキュリティ静的解析 tfsec の導入から始めるAWSセキュリティプラクティス

★オススメ
Zenn GitHubActionsとTerraformerを利用して既存のAWS環境をTerraformで管理する tfsecのインストール

Terraformの初期設定

Terraform Build Infrastructure

AWSドキュメント Linux での AWS CLI バージョン 2 のインストール、更新、アンインストール
AWSドキュメント AWS CLI 設定の基本
AWSドキュメント get-caller-identity

Terraform実行の流れ

たったこれだけ!チーム開発でコードフォーマット忘れを防ぐ方法
Terraform のコマンド、オプションを出来るだけ使ってみる

Terraform Command: validate

GitLab CI/CD で terraform ファイルに tflint をかける

GitHub TFLint Ruleset for terraform-provider-aws
awslabs Serverless Rules tflint plugin
GitHub Configuring TFLint

AWSドキュメント Amazon S3 サーバーアクセスログを有効にする
AWSドキュメント Amazon S3 バケットの命名要件

書籍

実践Terraform AWSにおけるシステム設計とベストプラクティス (技術の泉シリーズ(NextPublishing)) Kindle版