「Terraformを使えばインフラをコードで管理できると聞いたが、何から始めればいいのかわからない」
「コンソールで手動作成した既存リソース、どうやってTerraformに取り込めばいいんだ…」
こういった悩みを持つインフラエンジニアは多いでしょう。AWSコンソールでの手作業は、チームで運用するほどに属人化・設定漏れ・環境間の差異という問題を引き起こします。
この記事では、Infrastructure as Code(IaC)の代表格であるTerraformの概念から、HCL構文・状態管理・既存リソースの取り込み(terraform import)・モジュール設計、そしてAWSでVPCとEC2をコード化するハンズオンまでを体系的に解説します。「なぜTerraformを使うのか」「どう設計するか」「既存リソースをどう管理下に置くか」「よくあるトラブルをどう乗り越えるか」という4つの軸で、実務で使えるレベルまで踏み込んで説明します。
この記事のポイント
・TerraformはHCLでAWSインフラを宣言的にコード化できるIaCツール
・tfstateで状態を管理し、S3+DynamoDBでチーム共有するのが実務の基本
・terraform importで既存リソースをTerraformのstate管理に取り込める
・plan/apply失敗の多くは依存関係・権限・tfstate不整合が原因
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
Terraformとは何か — IaCの概念とインフラ自動化の必要性
Terraform(テラフォーム)は、HashiCorp社が開発したオープンソースのInfrastructure as Code(IaC)ツールです。AWSやAzure、GCPといったクラウドプロバイダーのリソースを、HCL(HashiCorp Configuration Language)というコードで定義・管理できます。
「インフラをコードで管理する」とはどういうことか、まず従来の手作業との違いを整理します。
1. 手作業管理の問題点
AWSコンソールでの手動構築には、次のような問題が繰り返し発生します。
・再現性がない:「先月と同じ設定で作った」はずが細部が違う・属人化:担当者しか設定内容を把握していない
・環境間の差異:開発環境と本番環境で設定がいつの間にかズレる
・変更履歴がない:「いつ誰がどの設定を変えたか」が追えない
10台、20台規模になると、これらの問題は致命的になります。本番障害の調査で「手動変更の痕跡が見つからない」という事態は、インフラ管理者にとって最も避けたいシナリオです。
2. IaCで何が変わるか
Terraformでインフラを管理すると、次のことが実現します。
・宣言的定義:「あるべき状態」をコードに書けば、Terraformが現在との差分を計算して適用する・バージョン管理:Gitでインフラ変更をコミット・レビューできる
・冪等性(べきとうせい):何度実行しても同じ結果になる(2回目は「変更なし」と判断される)
・マルチクラウド対応:AWSだけでなくAzure、GCP、Cloudflareなど300以上のプロバイダーに対応
特に「宣言的定義」と「冪等性」の組み合わせは強力です。Ansible(手続き的)と比較しながら、次のセクションで詳しく見ていきます。
Terraform vs Ansible — 役割の違いと使い分け
「TerraformとAnsible、どちらを使えばいいか」という質問は、IaCを学び始めた方が必ずぶつかる疑問です。結論から言うと、これは「どちらか一方」ではなく「組み合わせて使う」ものです。
| 観点 | Terraform | Ansible |
|---|---|---|
| 主な用途 | インフラのプロビジョニング(作成・変更・削除) | OSレベルの設定・ソフトウェアインストール |
| 記述スタイル | 宣言的(あるべき状態を書く) | 手続き的(実行する手順を書く) |
| 状態管理 | tfstateファイルで管理(差分計算が可能) | 状態を持たない(毎回フルスキャンまたは条件分岐) |
| 得意領域 | VPC・EC2・RDS・S3などAWSリソースの構築 | Webサーバー設定・パッケージ管理・ファイル配置 |
| エージェント | 不要(APIベース) | 不要(SSHベース) |
3. 実務での使い分け方
実際の現場では、次の役割分担が定着しています。
・Terraform:EC2インスタンスを作成し、セキュリティグループ・VPC・IAMロールを設定する(インフラ層)・Ansible:作成されたEC2の中にNginxをインストールし、設定ファイルを配置して起動する(OS・ミドルウェア層)
「箱を用意するのがTerraform、箱の中身を整えるのがAnsible」というイメージが最も直感的です。
なお、EC2のプロビジョニング後の初期設定はTerraformの user_data を使う方法もありますが、設定が複雑になるほどAnsibleに任せた方がコードの見通しが良くなります。
HCLの基本構文 — リソース/変数/outputsを理解する
TerraformはHCL(HashiCorp Configuration Language)で記述します。JSONとも互換性がありますが、可読性が高いHCLを使うのが基本です。
4. プロバイダーの定義
最初に、どのクラウドに対して操作するかを provider ブロックで宣言します。
# main.tf terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 5.0" } } } provider "aws" { region = "ap-northeast-1" # 東京リージョン }
5. resourceブロック — AWSリソースの定義
resource ブロックがTerraformの基本単位です。「何を(リソースタイプ)」「どんな名前で(ローカル名)」作るかを宣言します。
# EC2インスタンスを定義する例 resource "aws_instance" "web_server" { ami = "ami-0d52744d6551d851e" # Amazon Linux 2023 (ap-northeast-1) instance_type = "t3.micro" tags = { Name = "web-server" Env = "dev" } }
リソースタイプは aws_instance(EC2)、aws_vpc(VPC)、aws_s3_bucket(S3)のように プロバイダー名_リソース名 の形式になっています。
6. variablesブロック — 変数で柔軟性を持たせる
ハードコーディングを避けるために variable ブロックを使います。
# variables.tf variable "env" { description = "環境名 (dev/stg/prd)" type = string default = "dev" } variable "instance_type" { description = "EC2インスタンスタイプ" type = string default = "t3.micro" } # main.tfでの参照 resource "aws_instance" "web_server" { instance_type = var.instance_type tags = { Env = var.env } }
7. outputsブロック — 作成後の値を取り出す
output ブロックを使うと、作成したリソースの属性(IPアドレスなど)を terraform output コマンドで確認したり、他のモジュールに渡したりできます。
# outputs.tf output "instance_public_ip" { description = "EC2インスタンスのパブリックIP" value = aws_instance.web_server.public_ip } # 実行後に確認する # $ terraform output instance_public_ip # "54.xxx.xxx.xxx"
tfstateとbackend — 状態管理の仕組みと共有設計
Terraformの核心的な概念が terraform.tfstate(以下、tfstate)です。「現在のインフラの状態」を記録するJSONファイルで、Terraformはこのtfstateと実際のAWSリソースの差分を計算して、何を変更すべきかを判断します。
8. tfstateがなぜ重要か
例えば terraform plan を実行すると、次の比較が行われます。
・tfstate(前回の適用状態) vs 実際のAWSリソース(現在の状態)
この2段階の比較により、「HCLに書いてあるが作成されていない」「tfstateにあるがAWSから削除された」「手動で変更されてtfstateと乖離している」といったケースを検知します。
9. ローカルtfstateの問題とbackendの必要性
デフォルトではtfstateはローカルの terraform.tfstate ファイルに保存されます。個人での学習には問題ありませんが、チームで運用するには致命的な問題があります。
terraform apply を実行するとtfstateが壊れる・消失リスク:開発者のPCにtfstateが存在し、PCの故障で失われる
・機密情報:tfstateにはパスワードやキーが平文で含まれることがある
これを解決するのが backend の設定です。チームでの実務では、S3をbackendにしてDynamoDBでロック(排他制御)するパターンが標準です。
# backend.tf terraform { backend "s3" { bucket = "my-terraform-state-bucket" key = "dev/terraform.tfstate" region = "ap-northeast-1" dynamodb_table = "terraform-state-lock" # ロック用テーブル encrypt = true # 暗号化を必ず有効化 } }
10. backendの初期設定
backendを変更した後、または初めてbackendを設定した後は必ず terraform init を再実行します。
# backend設定後は必ずinitを実行 $ terraform init # ローカルtfstateをS3へ移行するか確認される # "Do you want to copy existing state to the new backend?" → yes
既存リソースをTerraformに取り込む — terraform importの実践
「コンソールで手動作成したEC2やS3バケット、どうやってTerraformに取り込めばいいんだ…」——IaCへの移行を始めた現場でよく聞く声です。最初からTerraformで構築できていれば理想的ですが、現実には「とにかく動かしてから後でコード化」という順序になりがちです。
terraform importは、「tfstateに存在しない既存リソース」を正しくTerraformの管理下に取り込むためのコマンドです。AWSのマネジメントコンソールで作成したリソースはTerraformのtfstateに登録されていないため、そのままmain.tfに同じリソースのHCLを書いて terraform apply を実行すると重複作成やエラーが発生します。importはこの問題を解決します。
11. importの基本的な仕組み
terraform importが行うことは1つだけです。指定した既存リソースの現在の属性値をAWSから読み取り、tfstateファイルに書き込むこと。これだけです。
よく誤解されますが、terraform importはHCLのコードを自動生成しません(Terraform 1.5以降の -generate-config-out オプションを使う場合は別です。後述します)。importの前後でファイルに何が起きるかを整理すると:
・import実行:AWSからリソース属性を取得 → tfstateに書き込み
・import後:tfstateにリソース記録あり。ただしHCLのresourceブロックは自分で書く必要がある
12. importの3ステップ手順(EC2を例に)
AWSコンソールで手動作成したEC2インスタンス(インスタンスID: i-0a1b2c3d4e5f67890)をTerraformのstate管理に取り込む流れを順に追います。
Step 1:main.tfにresourceブロックを先に書く
importを実行する前に、対象リソースに対応するHCLのresourceブロックを作成します。この時点では属性値の詳細が分からなくても構いません。最低限、リソースタイプとリソース名だけの空定義から始めます。
# main.tf(初期状態。属性は後でplanを見ながら埋める) resource "aws_instance" "web" { # importを実行するためにブロックは必要。中身は後から補完する }
Step 2:terraform importコマンドを実行する
書式は terraform import <リソースアドレス> <リソースID> です。リソースIDはAWSコンソールまたはAWS CLIで確認します。
# EC2インスタンスのIDをCLIで確認 $ aws ec2 describe-instances --filters "Name=tag:Name,Values=web-server" --query "Reservations[*].Instances[*].InstanceId" --output text i-0a1b2c3d4e5f67890 # importを実行 $ terraform import aws_instance.web i-0a1b2c3d4e5f67890 aws_instance.web: Importing from ID "i-0a1b2c3d4e5f67890"... aws_instance.web: Import prepared! Prepared aws_instance for import aws_instance.web: Refreshing state... [id=i-0a1b2c3d4e5f67890] Import successful!
「Import successful!」と表示されればtfstateへの書き込みは完了です。ただし、作業の本番はここからです。
Step 3:terraform planで差分をゼロにする
importが成功した直後に terraform plan を実行すると、HCLのresourceブロックが空のままなので大量の差分が表示されます。planの出力を読みながら、HCLにAWS上の実際の値を記述していきます。目標は「Plan: 0 to add, 0 to change, 0 to destroy.」です。
# main.tf(差分を埋めた後の状態) resource "aws_instance" "web" { ami = "ami-0c3fd0f5d33134a76" instance_type = "t3.micro" tags = { Name = "web-server" } root_block_device { volume_type = "gp3" volume_size = 20 encrypted = false } } # 差分がゼロになった状態 # $ terraform plan # No changes. Your infrastructure matches the configuration.
「No changes.」が表示されれば完成です。このEC2インスタンスはTerraformの完全な管理下に入りました。
すべての属性を完全に一致させるのに時間がかかる場合は、lifecycle.ignore_changes で特定の属性への変更検知を無視できます。
resource "aws_instance" "web" { ami = "ami-0c3fd0f5d33134a76" instance_type = "t3.micro" lifecycle { # AMIは手動での変更を許容し、Terraformによる変更検知を無視する ignore_changes = [ami, user_data] } }
ただし ignore_changes を多用すると「コードが実態を表さなくなる」というIaCの本末転倒になります。一時的な回避策として使い、最終的にはすべての属性をHCLで管理できる状態を目指してください。
13. Terraform 1.5以降のimportブロック(複数リソースを宣言的に取り込む)
Terraform 1.5からimportをHCLのブロックとして記述する方法が追加されました。コマンドラインで1件ずつ実行する従来の方法に比べて、複数リソースをコードとして宣言できる点が利点です。
# import.tf(Terraform 1.5以降の記法) import { to = aws_instance.web id = "i-0a1b2c3d4e5f67890" } import { to = aws_s3_bucket.assets id = "my-assets-bucket-20240501" } import { to = aws_security_group.web_sg id = "sg-0abc123def456789a" }
このファイルを用意して terraform plan を実行すると、import処理と差分確認が同時に行われます。さらにTerraform 1.5では -generate-config-out オプションが追加されており、HCLの雛形を自動生成できます。
# HCLの雛形を自動生成する(生成したコードは必ず見直すこと) $ terraform plan -generate-config-out=generated.tf
generated.tf に実際の属性値を元にしたHCLが生成されます。1から手動で書くよりはるかに効率的で、Terraform 1.5以降の推奨アプローチです。生成されたコードをベースに terraform plan の差分を解消していく方法が、現場ではスタンダードになりつつあります。
モジュール設計 — 再利用可能なインフラコードの作り方
本番レベルのTerraformプロジェクトでは、コードをそのままベタ書きにはしません。「モジュール」という仕組みを使って、再利用可能なコンポーネントに分割します。
14. モジュールとは何か
モジュールは「関連するTerraformファイルをまとめたディレクトリ」です。例えばVPCの設定をモジュール化しておけば、開発環境・ステージング環境・本番環境それぞれで同じモジュールを呼び出し、変数だけを変えてインフラを展開できます。
15. 推奨ディレクトリ構成
実務でよく使われる構成は次の通りです。
terraform-project/ ├── modules/ # 再利用可能なモジュール群 │ ├── vpc/ │ │ ├── main.tf │ │ ├── variables.tf │ │ └── outputs.tf │ └── ec2/ │ ├── main.tf │ ├── variables.tf │ └── outputs.tf ├── environments/ # 環境ごとの設定 │ ├── dev/ │ │ ├── main.tf # モジュールの呼び出しと変数の注入 │ │ └── backend.tf │ └── prd/ │ ├── main.tf │ └── backend.tf
16. モジュールの呼び出し方
環境ディレクトリから module ブロックでモジュールを呼び出します。
# environments/dev/main.tf module "vpc" { source = "../../modules/vpc" env = "dev" cidr_block = "10.0.0.0/16" } module "ec2" { source = "../../modules/ec2" env = "dev" vpc_id = module.vpc.vpc_id # VPCモジュールのoutputを参照 instance_type = "t3.micro" }
本番環境の environments/prd/main.tf では instance_type = "t3.large" などと変数を変えるだけで、同じインフラ構成を安全に展開できます。
>> Terraform実践セミナーの詳細はこちら
AWSでのハンズオン — VPC・EC2を実際にコード化する
ここからは実際にAWSリソースをTerraformでコード化する手順を見ていきます。前提として、AWS CLIの設定(aws configure)が完了していることを確認してください。
17. 環境確認とinitの実行
# Terraformのバージョン確認 $ terraform version Terraform v1.8.5 on linux_amd64 # AWS CLIの認証確認 $ aws sts get-caller-identity { "UserId": "AIDAXXXXXXXXXXXXXXXXX", "Account": "123456789012", "Arn": "arn:aws:iam::123456789012:user/terraform-user" } # プロジェクトディレクトリで初期化 $ terraform init Initializing the backend... Initializing provider plugins... - Finding hashicorp/aws versions matching "~> 5.0"... - Installing hashicorp/aws v5.54.1... Terraform has been successfully initialized!
18. VPCとサブネットの定義
実務で最小限必要なVPC構成(VPC本体・パブリックサブネット・インターネットゲートウェイ)をコード化します。
# vpc.tf # VPC本体 resource "aws_vpc" "main" { cidr_block = "10.0.0.0/16" enable_dns_support = true enable_dns_hostnames = true tags = { Name = "main-vpc" Env = var.env } } # パブリックサブネット(ap-northeast-1a) resource "aws_subnet" "public_1a" { vpc_id = aws_vpc.main.id cidr_block = "10.0.1.0/24" availability_zone = "ap-northeast-1a" map_public_ip_on_launch = true tags = { Name = "public-subnet-1a" Env = var.env } } # インターネットゲートウェイ resource "aws_internet_gateway" "main" { vpc_id = aws_vpc.main.id tags = { Name = "main-igw" Env = var.env } } # ルートテーブル(パブリックサブネット用) resource "aws_route_table" "public" { vpc_id = aws_vpc.main.id route { cidr_block = "0.0.0.0/0" gateway_id = aws_internet_gateway.main.id } tags = { Name = "public-rt" Env = var.env } } # サブネットとルートテーブルの関連付け resource "aws_route_table_association" "public_1a" { subnet_id = aws_subnet.public_1a.id route_table_id = aws_route_table.public.id }
19. セキュリティグループとEC2の定義
# ec2.tf # セキュリティグループ resource "aws_security_group" "web" { name = "web-sg" description = "Allow HTTP and SSH" vpc_id = aws_vpc.main.id ingress { from_port = 22 to_port = 22 protocol = "tcp" cidr_blocks = ["xxx.xxx.xxx.xxx/32"] # 自分のIPのみ許可 } ingress { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "web-sg" Env = var.env } } # EC2インスタンス resource "aws_instance" "web" { ami = "ami-0d52744d6551d851e" # Amazon Linux 2023 instance_type = var.instance_type subnet_id = aws_subnet.public_1a.id vpc_security_group_ids = [aws_security_group.web.id] key_name = "my-key-pair" # 事前にAWSで作成したキーペア名 tags = { Name = "web-server" Env = var.env } }
20. planで差分確認 → applyで適用
# 差分の確認(AWSへの変更は行われない) $ terraform plan Terraform will perform the following actions: # aws_instance.web will be created + resource "aws_instance" "web" { + ami = "ami-0d52744d6551d851e" + instance_type = "t3.micro" ... } Plan: 6 to add, 0 to change, 0 to destroy. # 問題なければ適用 $ terraform apply 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_vpc.main: Creating... aws_vpc.main: Creation complete after 2s [id=vpc-0a1b2c3d4e5f6789] ... Apply complete! Resources: 6 added, 0 changed, 0 destroyed. Outputs: instance_public_ip = "54.xxx.xxx.xxx"
EC2が作成されたら、SSH接続でリモートから操作できる状態になります。Linux ポート確認の全コマンドを参照して、EC2上でポートが正しく開いているか確認するとよいでしょう。
21. リソースの削除
学習環境で作成したリソースは忘れずに削除します。料金が発生し続けるためです。
# 全リソースの削除(本番環境では絶対に間違えないこと) $ terraform destroy Plan: 0 to add, 0 to change, 6 to destroy. Do you really want to destroy all resources? Enter a value: yes Destroy complete! Resources: 6 destroyed.
よくあるトラブルと対処 — plan/apply失敗パターン
Terraformを使い始めて必ずぶつかるエラーとその対処法を整理します。エラーメッセージを冷静に読めば、ほとんどのケースで原因は特定できます。
22. 「Error: No valid credential sources found」— 認証エラー
AWSの認証情報が見つからない場合に発生します。
# 対処: AWS CLIの認証設定を確認 $ aws configure list Name Value Type Location ---- ----- ---- -------- profile
None None access_key ****************XXXX shared-credentials-file secret_key ****************XXXX shared-credentials-file region ap-northeast-1 config-file ~/.aws/config # 認証情報が未設定の場合 $ aws configure AWS Access Key ID [None]: AKIAXXXXXXXXXXXXXXXXX AWS Secret Access Key [None]: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Default region name [None]: ap-northeast-1
23. 「Error: Error creating VPC: VpcLimitExceeded」— リソース上限エラー
AWSアカウントのデフォルトVPC上限(5個)に達している場合に発生します。
・対処1:使っていないVPCをAWSコンソールで削除する・対処2:AWSサポートにVPC上限の引き上げをリクエストする
24. 「Error: Terraform state is locked」— tfstateロックエラー
S3 backendを使用中に、前の terraform apply が異常終了してDynamoDBのロックが残ってしまった場合に発生します。
# エラーメッセージ例 Error: Error locking state: Error acquiring the state lock # 対処: ロックを強制解除(前のapplyが本当に完了または失敗したことを確認してから実行) $ terraform force-unlock LOCK_ID # LOCK_IDはエラーメッセージ中に表示される # 例: "ID: 12345678-1234-1234-1234-123456789012"
25. 「Error: Reference to undeclared resource」— 参照エラー
他のリソースを参照する際に、リソース名をタイプミスした場合に発生します。
# NG例: リソース名が一致していない resource "aws_instance" "web_server" { subnet_id = aws_subnet.public.id # "public"というサブネットは存在しない } # OK例: 定義したリソース名と一致させる resource "aws_subnet" "public_1a" { ... } resource "aws_instance" "web_server" { subnet_id = aws_subnet.public_1a.id # 正しく参照 }
26. 「Error: Resource already managed by Terraform」— import重複エラー
同じリソースアドレスに対してimportを2回実行しようとした場合に発生します。
Error: Resource already managed by Terraform Terraform is already managing a remote object for aws_instance.web. To import to this address you must first remove the existing object from the state. # 対処: stateの状態を確認し、誤ったimportであればstateから削除してやり直す $ terraform state list aws_instance.web $ terraform state rm aws_instance.web Removed aws_instance.web Successfully removed 1 resource instance(s). # 削除後に正しいリソースIDで再import $ terraform import aws_instance.web i-0XXXXXXXXXXXXXXXX
27. tfstateと実リソースの乖離(ドリフト)
誰かがコンソールから手動でリソースを変更した場合、tfstateと実際のAWSリソースに差異(ドリフト)が生じます。
# 実リソースの現状をtfstateに取り込む(plan前に状態を同期) $ terraform refresh # または planで差分を確認(refreshが自動で行われる) $ terraform plan # stateの実際の属性値を確認したい場合 $ terraform state show aws_instance.web
実務では「コンソールからの手動変更禁止」をルール化することが、このトラブルの最大の予防策です。Linux DNS 設定の基本のように、サーバー設定も可能な限りコードで管理する習慣が重要です。
まとめ — 学習ロードマップと次のステップ
この記事で解説した内容を整理します。
| テーマ | ポイント |
|---|---|
| Terraformとは | HCLでAWSリソースを宣言的に定義するIaCツール。冪等性と差分管理が強み |
| Terraform vs Ansible | Terraformはインフラ層(VPC/EC2作成)、AnsibleはOS層(設定/ソフトウェア)で役割分担 |
| HCL基本構文 | resource/variable/outputsの3ブロックが中心。変数で環境差異を吸収する |
| tfstateとbackend | チーム開発ではS3+DynamoDBをbackendに設定してtfstateを共有・ロック管理する |
| terraform import | HCLを先に書く → import実行 → plan差分ゼロ の3ステップ。1.5以降はimportブロックで複数一括対応 |
| モジュール設計 | modules/に再利用コンポーネントを置き、environments/から呼び出す構成が標準 |
| AWSハンズオン | VPC・サブネット・IGW・SG・EC2の順で定義し、terraform plan→applyで適用 |
| よくあるトラブル | 認証エラー・リソース上限・stateロック・import重複・ドリフトの5パターンを押さえる |
Terraformを習得するロードマップとして、次の順番で学習を進めることをお勧めします。
・Step 1:公式ドキュメントのGet Startedでローカルに慣れる(tfstateがどこに作られるか確認)・Step 2:この記事のハンズオンをそのまま試す(VPC+EC2を実際に作って、destroyする)
・Step 3:S3 backendとDynamoDBロックを設定し、チーム共有できる状態を作る
・Step 4:既存の手動リソースをterraform importでTerraform管理に移行する
・Step 5:モジュール分割を試す(dev/prd環境の同時管理)
・Step 6:GitHub ActionsでCI/CDパイプラインに組み込む(plan結果をPRコメントに出す)
Linuxの基本操作が不安な方は、Linux 基本コマンドの解説で土台を固めてから取り組むと、Terraform学習がスムーズになります。
Terraformをより深く体系的に学びたい方には、リナックスマスターのTerraform実践講座がおすすめです。ハンズオン形式でAWSインフラのコード化を一から習得できます。
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
登録10秒/合わなければ解除3秒 / 詳細はこちら
- 次のページへ:TerraformでAWS VPCとEC2を構築する方法|HCL記法とterraformコマンドの実践
- この記事の属するカテゴリ:Terraformへ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。
登録無料・いつでも解除できます