0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

terraformをゼロ知識から使ってみた

Last updated at Posted at 2025-03-28

terraformを使ってみた

terraformって名前しか聞いたことない人やそもそも何かわからない人向けに、自分の備忘録を兼ねて書いていきます。
参考にした記事などを、各章ごとに載せているので、環境が異なる人などはそちらを参考にしてください。

今回使用したコードはgithubに載せているので、そちらを参考にしてください。

terraformとは

terraformは、インフラストラクチャをコードとして管理するためのツールです。これにより、インフラストラクチャの構成をコードとして定義し、バージョン管理や自動化が可能になります。
terraformを使用すると、インフラストラクチャの変更を簡単に追跡し、再現可能な環境を作成できます。
terraformは、AWS、Azure、Google Cloud Platformなどのクラウドプロバイダーや、VMware、OpenStackなどのオンプレミス環境に対応しています。

簡単にいうと、インフラをコードで管理するためのツールです。

terraformのインストール

今回はmacOSでのインストールを行います。

記事はこちらを参考にしました。
ただし、terraformnをダウンロードするのに、バージョン管理してくれるtfenvを使います。

tfenvはpyenvのようなものです。
tfenvを使うことで、terraformのバージョンを簡単に切り替えることができます。

# brewでtfenvをインストール
brew install tfenv

# tfenvでterraformをインストール
tfenv install latest

# tfenvでterraformのバージョンを指定
tfenv use latest

# terafomのバージョンを確認
terraform -v

terraformを使ってみる

早速terraformを使ってみます。

はじめにterraform initを実行する必要があるのですが、その前にtfstateという設定ファイルを作成する必要があります。
tfstateは、terraformが管理するインフラストラクチャの状態を保存するファイルです。

そのために、tfstateを保存するためのS3バケットを作成します。

S3バケットの作成

まず、AWSのコンソールにログインします。

AWSのコンソールからS3を開き、バケットを作成します。
バケット名はterraform-practice-tfstate-soranjiroとします。
バケットのリージョンはap-northeast-1を選択します。

これでtfstateを保存するためのS3バケットが作成されました。

次に、このバケットにtfstateを保存するように、terraformの設定を行います。

aws cliを使ってS3バケットを作成することもできます。

aws s3api create-bucket --bucket terraform-practice-tfstate-soranjiro --region ap-northeast-1 --create-bucket-configuration LocationConstraint=ap-northeast-1

S3バケットの名前はグローバルで一意である必要があります。
同じ名前のバケットが存在する場合は、別の名前を指定してください。
ユーザ名やプロジェクト名を入れると良いでしょう。

terraformの設定

terraformの設定ファイルを作成します。
ファイル名はなんでも良いです。
直下に置かれた.tfファイルを全て読み込むので、main.tfterraform.tfなどの名前をつけることが多いです。

terraform {
  required_version = ">= 0.12"
  backend "s3" {
    bucket = "terraform-practice-tfstate"
    key    = "terraform.tfstate"
    region = "ap-northeast-1"
  }
}

provider "aws" {
  region = "ap-northeast-1"
}

これで、terraformの設定が完了しました。

terraformの初期化

次に、terraformを初期化します。

terraform init

これで、terraformの初期化が完了しました。

awsの認証情報がないと以下のようなエラーが出ます。

╷
│ Error: No valid credential sources found
│
│ Please see https://www.terraform.io/docs/language/settings/backends/s3.html
│ for more information about providing credentials.
│
│ Error: failed to refresh cached credentials, no EC2 IMDS role found, operation error ec2imds: GetMetadata, exceeded maximum number of attempts, 3, request send failed, Get
│ "http://169.254.169.254/latest/meta-data/iam/security-credentials/": dial tcp 169.254.169.254:80: connect: no route to host
│
╵

この場合は、aws cliの認証情報を設定する必要があります。

brew install awscli
aws configure

.terraformという隠しフォルダが作成されてterraform.tfstateというファイルたちが作成されていたら成功です。

lambdaの作成

せっかくなので、lambda関数を作成してみます。
lambda関数は、AWSのサーバーレスコンピューティングサービスです。
簡単にいうと、コードを書くだけで環境とかはAWSが用意してくれるサービスです。

ディレクトリ構成は以下のようにします。

sample
├── lambda		    # Lambda関数をまとめたディレクトリ
│   └── hello-world         # TerraformのLambdaモジュール
│       ├── sample
│       │   ├── go.mod
│       │   ├── go.sum
│       │   └── main.go
│       └── main.tf
├── main.tf
└── provider.tf

最終的には、以下のようにしたいですが、一回でterraform applyができなくなってしまうので一旦上に書いたようにします。

├─ env
│  ├─ dev
│  ├─ prod
│  │  └─ lambda
│  └─ stg
└─ modules
    └─ lambda
main.tf
# main.tf
module "hello_world" {
  source = "./lambda/hello-world"
}
provider.tf
# provider.tf
terraform {
  required_version = ">= 0.12"
  backend "s3" {
    bucket = "terraform-practice-tfstate-soranjiro"
    key    = "terraform.tfstate"
    region = "ap-northeast-1"
  }
}

provider "aws" {
  region = "ap-northeast-1"
}
hello-world/main.tf
# lambda/hello-world/main.tf
##################################
# Lambdaに付与するロール            #
##################################
data "aws_iam_policy_document" "assume_role" {
  statement {
    effect = "Allow"

    principals {
      type        = "Service"
      identifiers = ["lambda.amazonaws.com"]
    }

    actions = ["sts:AssumeRole"]
  }
}

resource "aws_iam_role" "iam_for_lambda" {
  name               = "iam_for_lambda"
  assume_role_policy = data.aws_iam_policy_document.assume_role.json
}


##################################
# Lambda                         #
##################################

resource "terraform_data" "default" {
  triggers_replace = {
    always_run = timestamp()
  }

  provisioner "local-exec" {
    command = "cd ${path.module}/sample/ && GOOS=linux GOARCH=amd64 go build -o ./build/bootstrap main.go"
  }
}

data "archive_file" "lambda" {
  type        = "zip"
  source_file = "${path.module}/sample/build/bootstrap"
  output_path = "${path.module}/sample/go.zip"

  depends_on = [ terraform_data.default ]
}

resource "aws_lambda_function" "hellow_world" {
  filename      = "${path.module}/sample/go.zip"
  function_name = "hello-world"
  role          = aws_iam_role.iam_for_lambda.arn
  handler       = "sample"

  source_code_hash = data.archive_file.lambda.output_base64sha256

  runtime = "provided.al2023"
}
hello-world/sample/main.go
// lambda/hello-world/sample/main.go
package main

import (
    "context"
    "fmt"

    "github.com/aws/aws-lambda-go/lambda"
)

type MyEvent struct {
    Name string `json:"name"`
}

func HandleRequest(ctx context.Context, name MyEvent) (string, error) {
    return fmt.Sprintf("Hello %s!", name.Name), nil
}

func main() {
    lambda.Start(HandleRequest)
}
cd lambda/hello-world
go mod init lambda/hello-world
go mod tidy

これで、lambda関数の準備ができました。

lambda関数のデプロイ

次に、lambda関数をデプロイします。

terraform init
terraform apply
# yesと入力

**Apply complete!**とでたら成功です。
もし、権限エラーで失敗している場合は、IAMロールの権限を確認してください。
PowerUserAccessIAMFullAccessを付与したら(ほぼできないことないので当たり前ですが)できると思います。
自分に必要な権限だけを付与するように不必要な権限は削除していきましょう!

lambda関数の確認

実際に作成されたかを確認してみましょう。

AWSコンソールから確認

AWSのコンソールから作成されたことが確認できると思います。
lambdaのコンソールから、関数を選択して、テストを実行してみましょう。

{
  "name": "soranjiro"
}

実行結果は以下のようになります。

{
  "statusCode": 200,
  "body": "\"Hello soranjiro!\""
}

aws cliから確認

ついでに、aws cliで確認してみましょう。

# 実行可能なlambda関数の一覧を取得
aws lambda list-functions --region ap-northeast-1

これで、hello-worldという関数が作成されていることが確認できると思います。
次に、lambda関数を実行してみましょう。

# lambda関数を実行
aws lambda invoke \
  --function-name hello-world \
  --cli-binary-format raw-in-base64-out \
  --payload '{"name": "World"}' \
  response.json

このコマンドの内容は、

  • --function-name: 実行するlambda関数の名前
  • --cli-binary-format: aws cliのバージョン2以降で必要なオプション
  • --payload: lambda関数に渡す引数
    • json形式で、nameというキーにWorldという値を渡しています。
    • キーを変更することで、別のレスポンスを得ることができます。
  • response.json: 実行結果を保存するファイル名

実行結果は、ターミナルに出力され、bodyの部分(lambdaからのレスポンス)はresponse.jsonに保存されます。

{
    "StatusCode": 200,
    "ExecutedVersion": "$LATEST"
}

response.jsonの中身は以下のようになります。

"Hello World!"

lambda関数の削除

terraformで作成したリソースは、terraform destroyコマンドで削除することができます。

terraform destroy
# yesと入力

Destroy complete! Resources: 3 destroyed.と表示されれば成功です。

以下のように、lambda関数が削除されていることを確認できます。

% aws lambda list-functions --region ap-northeast-1
{
    "Functions": []
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?