概要
-
2022年8月1日にインフラ状態管理ツールTerraformのCDK(Cloud Development Kit)のプレビュー版が公開された。
-
Terraformはマルチプロバイダーとして、AWSやVMware、OpenStackのインフラ状態をJSON互換のHCL(HashiCorp Configuration Language)という独自の記法によって管理する事ができる。HCLのテストツールには、Go言語のライブラリであるTerratestがある。
-
CDKを用いることで、PythonやGo、TypeScriptといった一般的なプログラミング言語でTerraformを操作できる。
-
Terraformコードに対して、条件分岐処理や繰り返し処理などの複雑な処理による操作、既存のテストツールの利用ができる。
-
現在のCDKはクラウドサービスごとに該当サービスのモジュールを適宜追加する必要がある。
準備
1. 開発用プログラミング言語のコンパイラのインストール
2. npm(Node.js)のインストール
3. yarnのインストール。
4. 対象クラウドのクライアントCLIのインストール
5. Terraformのインストール
6. CDK for Terraformのインストール
動作確認バージョン
ソフトウェア名 | バージョン |
---|---|
python | 3.10.6 |
pipenv | 2022.9.4 |
npm | 8.19.1 |
yarn | 1.22.19 |
aws(aws cli) | 2.7.29 |
terraform | 1.2.8 |
terraform provider aws | 4.29.0 |
cdktf(CDK for Terraform) | 0.13.0-pre.34 |
cdk provider aws | 4.0 |
ハンズオン
Terraform
1. AWSアカウントの登録
2. AWSログインユーザ(IAM)の作成
3. 作業PCに各種ソフトウェアのインストール
4. 作業PCにインスタンスマシンにアクセスするための鍵の生成
$ ~/.ssh/ssh-keygen
※ 鍵名やパスフレームは無記名でも問題ありません。
5 . Terraformプロジェクトの作成
$ mkdir -p ~/workspace/learn-terraform-aws-instance
$ cd ~/workspace/learn-terraform-aws-instance
$ terraform init
※ Cloud版Terraformの利用はNo、その他は無記名で問題ありません。
6 . Terraformコードの作成
$ touch ~/workspace/learn-terraform-aws-instance/terraform.tfvars
$ touch ~/workspace/learn-terraform-aws-instance/main.tf
- terraform.tfvars
具体的な鍵情報は省略する。ご自身の情報を記載する。- クラウド情報の変数定義
- インスタンスマシンの鍵情報の変数定義
# Provider
aws_access_key = "XXXXXXXXXXXXXXXXXXXX"
aws_secret_key = "YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY"
# EC2 Key
key_name = "ZZZZZZ"
public_key_path = "~/.ssh/ZZZZZZ.pub"
- main.tf
- ネットワークの作成
- セキュリティグループの作成
- インスタンスマシンの作成
variable "aws_access_key" {}
variable "aws_secret_key" {}
variable "region" {
default = "ap-northeast-1"
}
provider "aws" {
access_key = "${var.aws_access_key}"
secret_key = "${var.aws_secret_key}"
region = "${var.region}"
}
# VPC作成
resource "aws_vpc" "aws-tf-vpc" {
cidr_block = "10.1.0.0/16"
instance_tenancy = "default"
enable_dns_support = "true"
enable_dns_hostnames = "true"
tags = {
Name = "tf-example-vpc"
}
}
# サブネット2つ作成(publicとprivate)
resource "aws_subnet" "aws-tf-public-subnet-1a" {
vpc_id = aws_vpc.aws-tf-vpc.id
cidr_block = "10.1.1.0/24"
availability_zone = "ap-northeast-1a"
tags = {
Name = "aws-tf-public-subnet-1a"
}
}
resource "aws_subnet" "aws-tf-private-subnet-1a" {
vpc_id = aws_vpc.aws-tf-vpc.id
cidr_block = "10.1.20.0/24"
availability_zone = "ap-northeast-1a"
tags = {
Name = "aws-tf-private-subnet-1a"
}
}
# インターネットゲートウェイの作成
resource "aws_internet_gateway" "aws-tf-igw" {
vpc_id = aws_vpc.aws-tf-vpc.id
tags = {
Name = "aws-tf-igw"
}
}
# ルートテーブルの作成
resource "aws_route_table" "aws-tf-public-route" {
vpc_id = aws_vpc.aws-tf-vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.aws-tf-igw.id
}
tags = {
Name = "aws-tf-public-route"
}
}
# サブネットの関連付けでルートテーブルをパブリックサブネットに紐付け
resource "aws_route_table_association" "aws-tf-public-subnet-association" {
subnet_id = aws_subnet.aws-tf-public-subnet-1a.id
route_table_id = aws_route_table.aws-tf-public-route.id
}
# EC2作成(public側)
resource "aws_instance" "aws-tf-web" {
ami = "ami-011facbea5ec0363b"
instance_type = "t2.micro"
disable_api_termination = false
key_name = aws_key_pair.auth.key_name
vpc_security_group_ids = [aws_security_group.aws-tf-web.id]
subnet_id = aws_subnet.aws-tf-public-subnet-1a.id
tags = {
Name = "aws-tf-web"
}
}
# Security Group
resource "aws_security_group" "aws-tf-web" {
name = "aws-tf-web"
description = "aws-tf-web_sg"
vpc_id = aws_vpc.aws-tf-vpc.id
tags = {
Name = "aws-tf-web"
}
}
# 80番ポート許可のインバウンドルール
resource "aws_security_group_rule" "inbound_http" {
type = "ingress"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = [
"0.0.0.0/0",
]
# ここでweb_serverセキュリティグループに紐付け
security_group_id = aws_security_group.aws-tf-web.id
}
# 22番ポート許可のインバウンドルール
resource "aws_security_group_rule" "inbound_ssh" {
type = "ingress"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = [
"0.0.0.0/0",
]
# ここでweb_serverセキュリティグループに紐付け
security_group_id = aws_security_group.aws-tf-web.id
}
# アウトバウンドルール
resource "aws_security_group_rule" "outbound_all" {
type = "egress"
from_port = 0
to_port = 0
protocol = -1
cidr_blocks = [
"0.0.0.0/0",
]
# ここでweb_serverセキュリティグループに紐付け
security_group_id = aws_security_group.aws-tf-web.id
}
# ElasticIP
resource "aws_eip" "aws-tf-eip" {
instance = aws_instance.aws-tf-web.id
vpc = true
}
# EC2 Key
variable "key_name" {}
variable "public_key_path" {}
resource "aws_key_pair" "auth" {
key_name = var.key_name
public_key = file(var.public_key_path)
}
7. Terraformコードの文法確認
$ terraform plan
8. Terraformによるインフラの構築(状態管理)
$ terraform apply
※ 内容に問題がなければ、「yes」と記入し、エンターキーを押す。
9. 構築したインスタンスマシンにSSHアクセス
$ ssh -i ~/.ssh/ZZZZZZ.pub ec2-user@<ElasticIP>
10. 環境削除の確認
$ terraform plan -destroy
11. 環境削除
$ tarraform destroy
※ 内容に問題がなければ、「yes」と記入し、エンターキーを押す。
CDK for Terraform(CDKTF)
Python
1. CDKTFプロジェクトの作成
$ mkdir -p ~/workspace/learn-cdktf-aws-instance
$ cd ~/workspace/learn-cdktf-aws-instance
$ cdktf init --template="python"
※ Cloud版Terraformの利用はNo、その他は無記名で問題ありません。
2. 対象クラウドのプラグインの追加
$ pipenv install cdktf-cdktf-provider-aws
3. CDKTFコードの作成
$ vi ~/workspace/learn-cdktf-aws-instance/main.py
- main.py
- インスタンスマシンの作成
#!/usr/bin/env python
from constructs import Construct
from cdktf import App, NamedRemoteWorkspace, TerraformStack, TerraformOutput
from cdktf_cdktf_provider_aws import AwsProvider, ec2
class MyStack(TerraformStack):
def __init__(self, scope: Construct, ns: str):
super().__init__(scope, ns)
AwsProvider(self, "AWS", region="us-west-1")
instance = ec2.Instance(
self, "compute",
ami="ami-01456a894f71116f2",
instance_type="t2.micro",
tags={"Name": "aws-cdktf-web"},
)
TerraformOutput(
self, "public_ip",
value=instance.public_ip,
)
app = App()
stack = MyStack(app, "aws_instance")
app.synth()
4. CDKTFによるインフラの構築(状態管理)
$ cdktf deploy
※ 内容に問題がなければ、「Approve」と選択し、エンターキーを押す。
5. 構築確認
6. 環境削除
$ cdktf destroy
※ 内容に問題がなければ、「Approve」と記入し、エンターキーを押す。
所感
- ふんわりとTerraformやCDKの良さが見えてきた。
- CDKの本格的な活用はまだプレビュー版であり、対応機能が少なさや、記事外の機能は別途モジュール導入が必要などがあり先になりそう。
- 今回の記事は備忘録相当のコマンドメモになっているので、もう少しTerraformの理解が深まってから、追加投稿したい。