3大クラウドの仮想ネットワークをTerraformで作ってみた

かなり昔からあるんですが、Terraformとかいうツール、いわゆるInfrastructure As Codeとかいうやつでインフラの構成をソースコードにして保存し、アプリケーションみたいにGitなどでバージョン管理することでインフラも簡単にいじくれるようにしよう。という考え方に沿ったツールみたいです。少し興味があったので触ってみました。

3大クラウドには以下の様にInfrastructure As  Code(IaC)な仕組みがありますが
共通とは言え3社それぞれでバラバラです。
・AWSでいうところのCloudFormation
→YAMLで書く
・AzureでいうところのAzure Resource Manager テンプレート
→JSONで書く
・GCPでいうところのCloudDeploymentManager
→YAMLで書く

これを1つのツールでバシッと1つの記述法で管理できるようにしたのがTerraformらしいです。記述言語としてはHCL (HashiCorp Configuration Language)というJSON
似た独自のものです。まぁ、ほぼほぼJSONまんまです。

まず動かす前提としてそれぞれ以下の準備が必要です。
AWS→AWS-CLIを入れている
GCP→GoogleCloudSDKを入れている
AWSとGCPの環境はひとまず最新化
Azure→Azure-CLIを入れている

ちなみにUbuntuで環境作っているのでCentOSとかWindowsとかmacな人は
別のサイトを調べてみてください。

◆TeraFormインストール手順


#Terraformインストール
$ sudo apt install -y unzip
$ sudo snap install terraform
#tfenv
$ git clone https://github.com/tfutils/tfenv.git ~/.tfenv
$ echo 'export PATH="$HOME/.tfenv/bin:$PATH"' >> ~/.bashrc
$ source ~/.bashrc
$ tfenv install latest
$ tfenv use latest
Switching default version to v0.12.24
Switching completed
$ terraform --version
Terraform v0.12.24
$ mkdir terraform
$ cd terraform

◆各サービスでの仮想ネットワークの作成実験

1.AWSの場合

事前にIAMでプログラムアクセス用ユーザを作成する。
そのユーザについてはアクセスキーとシークレットを発行する
#環境変数設定
$ export TF_VAR_access_key="ACCESS-KEY"
$ export TF_VAR_secret_key="ACCESS-SECRET-KEY"
# ファイル群作成
$ mkdir network
$ cd network
$ mkdir vpc
$ cd ../..
$ vi provider.tf
---------------------
provider "aws" {
  access_key = var.access_key
  secret_key = var.secret_key
  region     = var.region

  assume_role {
    role_arn = var.role_arn
  }
}
----------------------
$ vi variables.tf
----------------------
variable "access_key" {
  description = "AWS Access Key"
}
variable "secret_key" {
  description = "AWS Secret Key"
}
variable "role_arn" {
  description = "AWS Role ARN for Assume Role"
}
variable "region" {
  description = "AWS Region"
  default     = "ap-northeast-1"
}
----------------------
$ vi network.tf
----------------------
module "vpc" {
  source = "./network/vpc"

  vpc_config = {
    name                 = "tf_sample"
    cidr_block           = "10.0.0.0/16"
    enable_dns_support   = true
    enable_dns_hostnames = true
  }
}
----------------------
$ cd network/vpc
$ vi variables.tf
----------------------
variable "vpc_config" {
  type = object({
    name                 = string
    cidr_block           = string
    enable_dns_support   = bool
    enable_dns_hostnames = bool
  })
}
----------------------
$ vi main.tf
----------------------
resource "aws_vpc" "this" {
  cidr_block           = var.vpc_config.cidr_block
  enable_dns_support   = var.vpc_config.enable_dns_support
  enable_dns_hostnames = var.vpc_config.enable_dns_hostnames

  tags = {
    Name = var.vpc_config.name
  }
}
----------------------
$ vi outputs.tf
----------------------
output "vpc" {
  value = aws_vpc.this
}
----------------------
#初期化
$ terraform init
#ドライラン
$ terraform plan
#デプロイ
$ terraform apply
#破棄
$ terraform destroy

2.Azureの場合

特に事前作業は不要
#設定情報取得
$ az account list --query "[].{name:name, subscriptionId:id, tenantId:tenantId}"
[
  {
    "name": "従量課金",
    "subscriptionId": "subscription",
    "tenantId": "tenantid"
  }
]
#アクセスキーなど取得
$ az account set --subscription="subscription"
$ az ad sp create-for-rbac --role="Contributor" --scopes="/subscriptions/subscription"
~中略~
{
  "appId": "APPID",
  "displayName": "DISPNAME",
  "name": "NAME",
  "password": "PASSWORD",
  "tenant": "tenant"
}
#環境変数設定
$ export ARM_SUBSCRIPTION_ID=subscription
$ export ARM_CLIENT_ID=APPID
$ export ARM_CLIENT_SECRET=PASSWORD
$ export ARM_TENANT_ID=tenant
$ export ARM_ENVIRONMENT=public
# ファイル群作成
$ vi variables.tf
----------
variable "resource_group_name" {
  default = "testResourceGroup"
}
variable "location" {
  default = "japaneast"
}
variable "Vnet_name" {
  default = "test-Vnet"
}
variable "Vnet_address_space" {
  default = "10.0.0.0/16"
}
----------
$ vi main.tf
----------------------------
provider "azurerm" {
  # The "feature" block is required for AzureRM provider 2.x.
  # If you are using version 1.x, the "features" block is not allowed.
  version = "~>2.0"
  features {}
}
resource "azurerm_resource_group" "testResourceGroup"{
        name = "${var.resource_group_name}"
        location = "${var.location}"
}
resource "azurerm_virtual_network" "vn" {
  name = "${var.Vnet_name}"
  address_space = ["${var.Vnet_address_space}"]
  location = "${azurerm_resource_group.testResourceGroup.location}"
  resource_group_name = "${azurerm_resource_group.testResourceGroup.name}"
}
---------------------------
#terraformコマンド実行
$ terraform init
$ terraform plan
$ terraform apply
$ terraform destroy

3.GCPの場合

GCPコンソールでプロジェクトを新規作成する。
プロジェクトで各種APIを有効にする
#クレデンシャル用ディレクトリ作成
$ cd
$ mkdir credentials
$ cd terraform
#gcloud更新確認
$ gcloud components update
pyenv: python2: command not found
~中略~
Do you want to continue (Y/n)?  Y
~中略~
Update done!
#サービスアカウント作成
$ gcloud config set project XXXXX
$ gcloud services enable cloudresourcemanager.googleapis.com
$ gcloud services enable iam.googleapis.com
$ gcloud services enable compute.googleapis.com
$ gcloud iam service-accounts create terraform-serviceaccount --display-name "Account for Terraform"
$ gcloud projects add-iam-policy-binding XXXXX \
  --member serviceAccount:terraform-serviceaccount@XXXXX.iam.gserviceaccount.com \
  --role roles/editor
#クレデンシャル発行
$ gcloud iam service-accounts keys create /home/users/credentials/account.json \
--iam-account terraform-serviceaccount@XXXXX.iam.gserviceaccount.com
# ファイル群作成
$ vi main.tf
-------------------------
provider "google" {
  credentials = "${var.credential}"
  project     = "${var.project_name}"
  region      = "${var.region}"
}

resource "google_compute_network" "test-vpc" {
  name = "test-vpc"
  auto_create_subnetworks = "false"
}

resource "google_compute_subnetwork" "test-subnet1a" {
  name          = "test-subnet1a"
  ip_cidr_range = "10.0.0.0/24"
  network       = "${google_compute_network.test-vpc.name}"
  description   = "test-subnet-a"
  region        = "${var.region}"
}
-------------------------
$ vi variable.tf
-------------------------
variable "project_name" {
  default = "XXXXX"
}
variable "credentials" {
  default = "/home/users/credentials/account.json"
}
variable "region" {
  default = "asia-northeast1"
}
-------------------------
#terraformコマンド実行
$ terraform init
$ terraform plan
$ terraform apply
$ terraform destroy

GCPが認証系のところで少し嵌りました。他と少し考え方違うところがあるから
プロジェクトに編集権限をきっちり割り当てておかないといけないです。
大体、サブネット切ってVM立てるところまで書いたほうがいいんでしょうけど
低スキルなためそこまで行けませんでした。(課金が発生すると恐ろしいので、、
いずれお金持ちになったらVM立てるところも書ければと思います。

3社の個別のサービス名とかあるものの3社の構成を1つのツールでIaCできるのは非常に
ありがたいと思いました。たくさんネットワーク切ってサーバをたくさん立てないといけないときにはAnsibleとかと組み合わせれば一気に大量のマシンが作れるという寸法ですね。とはいえ、そういう仮想マシン立てるくらいならアプリ込みでコンテナとか使った方が可搬性がいいので仮想マシン立てる場合は手動でやったほうが早いのかもしれませんが

今後はもう少し勉強してマルチクラウドマネージドServeless構成をTerraformでバシッと書けるようになりたいと思うのですが、まだまだ先は長そうです。

それでは今回はこの辺で。

◆参考サイト

・Teraform全般

https://www.terraform.io/docs/providers/index.html
https://kazuhira-r.hatenablog.com/entry/2019/04/09/231234
https://future-architect.github.io/articles/20190816/
https://qiita.com/sasshi_i/items/f4f65e18923d856be256
https://y-ohgi.com/introduction-terraform/handson/vpc/
https://qiita.com/takafumi_takizawa/items/0ca99cf8c26800ccce06
https://qiita.com/andromeda/items/18be19d44e0921090b5f
https://qiita.com/CkReal/items/1dbbc78888e157a80668
https://blog.adachin.me/archives/4693
https://blog.mzumi.com/post/2016/09/01/terraform-private-subnet/
https://qiita.com/okubot55/items/0f6fb71524b4eafd5c08
https://blog.dshimizu.jp/article/1345
https://tech.enechange.co.jp/entry/2018/05/30/181031
https://qiita.com/minamijoyo/items/1f57c62bed781ab8f4d7

・Azure

https://docs.microsoft.com/ja-jp/azure/terraform/terraform-install-configure
https://eventmarketing.blob.core.windows.net/decode2019-after/decode19_PDF_CD91.pdf

・AWS

https://y-ohgi.com/introduction-terraform/first/handson/
https://infraya.work/posts/terraform_create_vpc1-multiaz/
https://nezumisannn.io/blog/terraform-module-vpc/

・GCP

https://blog.adachin.me/archives/6854
https://qiita.com/devs_hd/items/1d9d6c2f0d5a6dbd9fa0

コメント

このブログの人気の投稿

証券外務員1種勉強(計算式暗記用メモ)

GASでGoogleDriveのサブフォルダとファイル一覧を出力する

マクロ経済学(IS-LM分析)