gokigenmaruのブログ

40から始めるクラウドエンジニア

GoogleCloudでネットワークを作成する

Google CloudのVPC

VPC (Virtual Private Cloud)とは

Google CloudのVirtual Private Cloud(VPC)は、クラウドベースのリソースとサービスに対してスケーラブルで柔軟性に優れたグローバルなネットワーキングを提供するサービスです。VPCは、Compute Engine仮想マシンVMインスタンスGoogle Kubernetes Engine(GKE)クラスタ、サーバーレスワークロードなどにネットワーキング機能を提供します。

VPCネットワークは、Google Cloud内で仮想化されている点を除き、物理ネットワークと同じように考えることができます。VPCネットワークは、データセンター内のリージョン仮想サブネットワーク(サブネット)のリストで構成されるグローバルリソースであり、すべてグローバルな広域ネットワークで接続されています。

VPCネットワークの主な機能には以下が含まれます

ネットワーク接続: Compute Engine VMインスタンス、GKEクラスタ、サーバーレスワークロードなどに向けた接続を提供します。
ファイアウォールルール: 各VPCネットワークには、構成可能な分散仮想ファイアウォールが実装されています。ファイアウォールルールを使用すると、どのパケットをどの宛先に送信できるようにするかを制御できます。
ルート: VMインスタンスVPCネットワークに対して、インスタンスから宛先(ネットワーク内部またはGoogle Cloudの外部)にトラフィックを送信する方法を通知します。
転送ルール: IPアドレスプロトコル、ポートに基づいてVPCネットワーク内のGoogle Cloudリソースにトラフィックを転送します。
インターフェースとIPアドレス: VPCネットワークは、IPアドレスVMネットワークインターフェース用の構成を提供します。
また、VPCネットワークはGoogle Cloud内で互いに論理的に隔離されており、他のGoogle Cloud利用者からは完全に独立したプライベートネットワークとなります。


とCopilot先生がおっしゃっています。

AWS/Azure/GoogleCloudのVPCの違い

AWS/Azureとの大きな違いは2点あると思っています。

  1. GoogleCloudのVPCIPアドレスのCIDRを持ちません
  2. VPCはグローバルサービス(リージョン固定ではない)として利用

AWS/AzureではVPCにCIDRを持たせその範囲内からサブネットに切り出していきますが、GoogleCloudではVPC側でCIDRを持たずサブネット単位でCIDRを持つ形になります。
また、VPCはグローバルのサービスでリージョンはサブネット毎になります。

ということでこんな感じで理解しました。

VPCネットワークを作ってみる

VPCの作成

ということで、VPCを作成してみます。
プロジェクトのトップページからVPCネットワークをクリック

こんなエラーが出るので、続行をクリック

Compute Engine APIを有効にする

どうやらGoogleCloudではAPIをプロジェクトごとに管理しているので、APIはプロジェクトごとに有効にするようです。

すでにdefaultのVPCがありますが、こちらは利用せず、新たにVPCの作成をします。
画面上部のVPCネットワークを作成をクリック

VPCとサブネット、VPC周りの設定を行っていきます。

まずはVPC名と説明などの設定。
MTUはデフォルトの1460のまま。ネットワークプロファイルは作成せずにサブネットは手動で作成したいのでカスタムにし、IPv6は設定しないこととします。

サブネットの作成、東京リージョンにtest-tokyoという名前のサブネットを作っています。
IPv4のみで、10.0.0.0/24、その他はすべてデフォルトのままです。

ファイアウォール ルールはデフォルトのまま。
ファイアウォールルールはAWSでいうセキュリティグループ、Azureでいうネットワークセキュリティグループと理解しています。これを細かく追うとそれだけでブログ1つかけそう。
設定としては、VPC内の通信許可、icmp/ssh/rdpの許可、自身からの送信の許可、Internetからの拒否が入っています。

高度庵設定はデフォルトのままにしました。
今回はCloudRouterは作らないので動的ルーティングは使わない…はず。

作成をクリック
作成したVPCが表示されます。


作成は簡単にできました。
どのクラウドもそうですが、細かい設定をせずにデフォルトで作成するのであれば簡単にできますし、デフォルト通りに作ってあげれば動くようになっているので助かります。

Google Cloudを学ぶ

今までAWS、Azure、さくらのクラウドとやってきましたが、メジャーどころで手を出していなかったGoogle Cloud。最近、お仕事でGoogle Cloudを触る機会が出来ましたのでちょっとずつ学んでいこうと思います。

Google Cloudとは

Google Cloudは、Googleが提供するクラウドコンピューティングサービスです。これにより、企業や個人がインターネットを通じてさまざまなITリソースを利用できるようになります。

主な特徴

高速ネットワーク: Googleが独自に開発した高速で安定したネットワークを提供しています。
ビッグデータとAI: Googleの強みであるビッグデータ分析とAI技術を活用できます。
フルマネージドサービス: サーバーの管理やメンテナンスをGoogleに任せることができるため、運用の手間が省けます。
セキュリティ: 高度なセキュリティ対策が施されており、安心して利用できます。

代表的なサービス

Google Compute Engine (GCE): 仮想サーバーの構築2。
Google Cloud Storage (GCS): データの保管2。
Google Cloud SQL: リレーショナルデータベースサービス2。
Google Cloud AI Platform: AI開発2。

GoogleCloud

Google Cloudは、特にビッグデータとAIに強みがあり、高速なネットワークとフルマネージドサービスが魅力です。
日本市場ではAWSは豊富なサービス、AzureはMS製品との親和性が特徴であり、ともに30%近い利用率になっています。
かたやGoogleCloudは15%くらいですが、一時期に比べれば他の2社に追いついてきていると思います。

ただ、使用率の低さがあるからか勉強をするにはちょっと不便で、この間参考書を買いに秋葉原書泉ブックタワーに行きましたが、AWS/Azureは数十冊と参考書があるなか、GoogleCloudはたったの2冊しかなく…。会社とかですでにバックボーンがあればいいのでしょうが、個人が1から勉強しようと思うとちょっとハードルが高い気がする。

リージョンとゾーン

GoogleCloudもAWSやAzureと同様にリージョンとゾーンというものがあります。
リージョンはデータセンター群を地域で纏めた呼称、日本だと東京・大阪、欧州だとフランクフルトやロンドン・パリなど、北米だとロサンゼルスやバージニア北部などですね。
ゾーンは各リージョン内にあるデータセンターといった感じ。
リージョンの定義は3つ以上のゾーン(物理的なデータセンター)があるものということで、この辺もAWS/Azureと同じようです。

GoogleCloudの組織階層

GoogleCloudは組織を階層の頂点とし、その下にフォルダがあり、フォルダの中でプロジェクトを作成してGoogleCloudのリソースをプロジェクト内に作成する形になります。
フォルダは複数階層を持つことが出来て、Aフォルダの下にBフォルダとCフォルダを作成するみたいな感じで分けることも可能です。

GoogleCloudの検証用プロジェクトの作成

検証用プロジェクト作成

ということで、参考書も買い実際にGoogleCloudのアカウントを作成しました。
まずはProjectを作れということで、テスト用のProjectを作成し、そこでいろいろと試すことにしました。
GoogleCloudにログインし、画面左上のところをクリック

新しいプロジェクトをクリック

プロジェクト名を入れて作成をクリック

プロジェクトを作成したら画面左上のところをクリック

作成したプロジェクトを選択

これでプロジェクトに入りました

ダッシュボードの表示

プロジェクトの作成が出来たら、まずはダッシュボードを見ようと思います。
画面左上の三本線からリソースを選んでもいいのですが、ダッシュボードは全体が見れるので最初はダッシュボードから見ていくのがいいのかなと思います。
トップ画面の真ん中くらいにあるダッシュボードをクリック

ダッシュボードが表示されました。
ここからいろいろといじっていこうと思います。

まとめ

まずは検証が出来る環境を作成しました。
ざっと調べた感じだと、リージョンやゾーンなどはAWSやAzureと同じ考え方のようでした。
プロジェクトというのは、GoogleCloudは組織(会社)単位で1つのアカウントを作成し、その中でフォルダ(例えば部署ごと)を分けてそこにプロジェクトを作成するツリー型になっていて、この辺はAzureなんかと感覚が似ている気がします。※個人の感想です。

AWSでSite to Site VPNを使う

会社で検証で使えるL3 Switchを手に入れたので、かねてからやってみたかったAWSとのVPN接続をやってみようと思います。

Site to Site VPN

Site-to-Site VPN (Virtual Private Network) は、異なる物理的な場所にある複数のネットワークを安全に接続するための技術です。
これにより、異なるオフィスやデータセンター間でデータを安全にやり取りすることができます。

主な特徴

セキュリティ: データは暗号化されて送信されるため、インターネット上での盗聴や改ざんを防ぎます。
コスト効率: 専用回線を使用するよりもコストが低く、インターネットを介して接続できます。
スケーラビリティ: 新しい拠点を追加するのが比較的簡単です。

利用例

企業の拠点間接続: 本社と支社、または異なる国にあるオフィス間の安全な通信。
データセンターの統合: 複数のデータセンターを一つのネットワークとして運用。

AWSでSite to Site VPNを使う

AWSだと、よく構成例として出るのはコストを削減するためにDirectConnectの副系をVPNにするやり方です。
実際に設定をしてみたかったのですが、物理的なL3機器が必要なので今まで手が出せませんでした。
今回は実際に機器を手に入れたのでやってみます。

仮想プライベートゲートウェイの作成

まずは仮想プライベートゲートウェイの作成です。
VPC」→「仮想プライベートゲートウェイ」で画面右上の「仮想プライベートゲートウェイを作成」を選択。
設定自体は2つを設定すればよく、名前(オプション)と自律システム番号(ASN)を入れるだけ。
名前は適当に、ASNはAmazonデフォルトASNにしました。ASNはVPNをはるときに動的にルーティングをやり取りするときにBGPで使われる番号です。
BGP周りは別途ネットワークの勉強が必要ですが、オンプレとは異なる"プライベート"のAS番号を入れる必要があります。

作成後、使いたいVPCにアタッチする必要があるので注意です。

カスタマーゲートウェイの作成

今度はオンプレ側のL3の設定を入れます。
VPC」→「カスタマーゲートウェイ」で画面右上の「カスタマーゲートウェイを作成」を選択。
こちらはオンプレで使っているL3の設定を入れていきます。
名前はAWSで識別するものなので、わかりやすいもの。
BGP ASNは動的にルーティングをやり取りする際に使うBGPのAS番号。今回は静的にルーティングを書くのでBGPは使いません。デフォルトで入っている番号を使います。
IPアドレスVPNをはるオンプレ側のインターフェースに割り当てられているIPアドレス(通常はパブリックのIPになるはず)
バイスAWS上でオンプレ側のL3を識別するための名前なので、わかりやすいもの。

Site-to-Site VPNの作成

VPC」→「Site-to-Site VPN接続」で画面右上の「VPN接続を作成する」を選択。
ターゲットゲートウェイは先ほど作成した仮想プライベートゲートウェイを選択。
カスタマーゲートウェイも先ほど作成したカスタマーゲートウェイを選択。
ルーティングオプションは今回は静的にして、オンプレ側で使っているIPアドレスを入れます。
ローカル IPv4 ネットワーク CIDRとリモート IPv4 ネットワーク CIDRは特に入力はせず。

これで作成をしました。

トンネルの設定を細かくしたい場合はトンネルオプションで設定をしていきます。
トンネルの内部IP(/30)や事前共有キー(Pre shared key)、暗号化のアルゴリズムとかIKEのバージョンとかをオプションで設定できます。

オンプレL3設定

Site-to-Site VPNの作成した後にオンプレ側の設定のダウンロードが出来ます。
VPC」→「Site-to-Site VPN接続」で画面右上の「設定をダウンロードする」を選択。
いろんなベンダーの機器の設定サンプルをダウンロードすることが出来るので、この中から該当するものを選びます。
ちなみに自分はこのリストにはなかったベンダーの機器だったので、一旦Ciscoの設定をダウンロードしてカスタマイズして入れました。

VPNつながる

これで設定は終わりで後は状態が利用可能にあり、トンネルの詳細でステータスがアップしていることを確認すればOKです。
AWS上でEC2を作成、ルートテーブルでオンプレのルーティングを書いてあげてセキュリティグループでオンプレからの接続を許可し、オンプレ側からSSHとかが出来ることを確認出来れば完了です。

終わりに

L3を用意するのがちょっと大変ですがVPN自体は簡単に設定が出来ました。
AWS側がオンプレ機器の設定サンプルを用意してくれているのもあり、ハードルはかなり低くなっていると思います。

ansibleでyamlファイルなどを編集するときにインデントを入れる方法

Ansibleでyamlファイルを編集する際、インデントを入れるのに苦戦しました。
忘れないように書いておきます。

ansible

ファイル編集

ファイル編集ですが、以下ような編集を行いたいと考えました。

編集前

111:
  aaa:
    bbb:
      ccc:
      ddd:

編集後

111:
  aaa:
    eee:
      fff:
      ggg:
    bbb:
      ccc:
      ddd:

上記の通り、eee~gggまでをaaaの次に入れるようにしたいと思いましたが、やってみると意外とうまくいきませんでした。

インデント込みの内容をファイルに反映出来ない

まずは単純に以下の方針でやろうとしました。

  • ansible.builtin.lineinfileのsearch_stringで"aaa:"を検索する
  • 検索にヒットした文字列の後にlineで複数行の文字列をインデント込みで挿入する

実際にはこういった感じです。

- name: Add eee-ggg
  ansible.builtin.lineinfile:
    path: /etc/xxx/xxx.yaml
    state: present
    firstmatch: yes
    search_string: "aaa: "
    line: |
        aaa:
          eee:
            fff:
            ggg:
実行結果

実行した結果、ファイルは以下の通りになります。

111:
aaa:
  eee:
    fff:
    ggg:
    bbb:
      ccc:
      ddd:

aaa:の前に入れている空白2つが認識されない結果になりました。

調査

ぱっと見、最初の2つのインデントが認識されていないが、次の行からは空白が認識されているので、単純にもう2つ空白を入れればいけるかと思いましたが、結果は失敗でした。

- name: Add eee-ggg
  ansible.builtin.lineinfile:
    path: /etc/xxx/xxx.yaml
    state: present
    firstmatch: yes
    search_string: "aaa: "
    line: |
          aaa:
            eee:
              fff:
              ggg:

実行結果

111:
aaa:
  eee:
    fff:
    ggg:
    bbb:
      ccc:
      ddd:

つまり、lineで複数行を指定するとき、文字列が始まるところまでの空白は認識してくれない(次の行以降は前の行で先頭から何個空白があったかは無視されるがそれ以降の空白は認識される)ことがわかりました。

ansibleの調査

ansibleでこれが回避できないか調べてみたところ、line:の後ろに数字を指定できることが判明。
line: | n
こんな感じ。
このnの意味ですが、先頭からn文字以降は文字列として認識してくれると理解しています。
なので、

- name: Add eee-ggg
  ansible.builtin.lineinfile:
    path: /etc/xxx/xxx.yaml
    state: present
    firstmatch: yes
    search_string: "aaa: "
    line: |4
          aaa:
            eee:
              fff:
              ggg:

とやると、

111:
    aaa:
      eee:
        fff:
        ggg:
    bbb:
      ccc:
      ddd:

こんな感じで編集されます。
これでyamlファイルのインデントが入れられそうです。

希望のインデントを挿入する

yamlでインデントを合わせるために、以下の通りplaybookを編集。

- name: Add eee-ggg
  ansible.builtin.lineinfile:
    path: /etc/xxx/xxx.yaml
    state: present
    firstmatch: yes
    search_string: "aaa: "
    line: |2
          aaa:
            eee:
              fff:
              ggg:

実行結果

111:
  aaa:
    eee:
      fff:
      ggg:
    bbb:
      ccc:
      ddd:

となりました。

ansibleのsearch_stringでエラーになる

ansibleでファイルを操作しようとしたところ、search_stringでエラーが発生しファイル操作が出来ませんでした。
今回はその対応について。

ansible

ansibleはIaCの1つで、Redhat社が提供するオープンソース(課金版もあります)のIaCツールです。
クラウドのほかにLinux系のサーバOSやCisco系のNWOSに対応しています。

今回のエラー

エラー内容

エラーは以下の構文の実行時に発生しました。

- name: test
  ansible.builtin.lineinfile:
    path: xxxxxxxx
    state: present
    search_string: "xxxx"
    line: "xxxx"

エラー内容は以下の通りです。

fatal: [vpctestserver]: FAILED! => {"changed": false, "msg": "Unsupported parameters for (ansible.builtin.lineinfile) module: search_string Supported parameters include: attributes, backrefs, backup, create, firstmatch, group, insertafter, insertbefore, line, mode, owner, path, regexp, selevel, serole, setype, seuser, state, unsafe_writes, validate"}

調査

エラーメッセージ

エラーメッセージに「"Unsupported parameters for (ansible.builtin.lineinfile) module: search_string」とあるので、search_stringがansible.builtin.lineinfileでは対応していないと読み取れます。
対応しているは「attributes, backrefs, backup, create, firstmatch, group, insertafter, insertbefore, line, mode, owner, path, regexp, selevel, serole, setype, seuser, state, unsafe_writes, validate」であると。
しかしながら、ansibleのホームページ上はsearch_stringについて記載があるので、ansibleとして対応していないわけではなさそうです。

docs.ansible.com

調べてみると

調べてみると、どうやらsearch_stringはansible2.11から追加されたようです。
自端末(WSL2のUbuntu22.04)のansibleのバージョンを確認すると、ansible 2.10.8でした…。
このansibleはubuntuリポジトリから持ってきたもので、2024/9/17時点での最新版は2.10.8、これだとsearch_string使えない…。

調べてみると、ubuntuリポジトリにppa:ansible/ansibleを追加することで最新版を手に入れられそう。

対応

ということで、既存のansibleをアンインストールし、PPAから最新のansibleを持ってくることにします。

docs.ansible.com

$ sudo apt remove ansible
$ sudo apt update
$ sudo apt install software-properties-common
$ sudo apt-add-repository --yes --update ppa:ansible/ansible
$ sudo apt install ansible
$ ansible --version
ansible [core 2.16.11]
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/xxxx/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3/dist-packages/ansible
  ansible collection location = /home/xxxx/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.10.12 (main, Jul 29 2024, 16:56:48) [GCC 11.4.0] (/usr/bin/python3)
  jinja version = 3.0.3
  libyaml = True

無事、ansible 2.16が手に入りました。
この状態で実行するとsearch_stringのエラーは出なくなりました。


さくらのクラウドのロードバランサー構築をTerraform化する

DBの作成も出来たので、さくらのクラウドでオートスケールの検証をしようと考えています。
オートスケールの検証で考えているのは、ロードバランサー配下にWebサーバを立ててスケールさせられるかどうかテストしようと考えています。

んで、いつも通りですが、何度も検証環境を構築するのが面倒なので、まずは標準構成を考えてその構成をTerraformで作れるようにしようと思います。

Terraform

構成

構成ですが、DB構築時の構成をベースにDB用セグメントではないセグメントにロードバランサーとWebサーバを作ろうと思います。
ということで、以下のような構成にしました。

Terraformコード

gokigenmaru.hatenablog.com
変更がないものについては本ブログの上にリンクを貼ってある以前のブログのコードを参考にしてください

loadbalancer.tf

resource "sakuracloud_load_balancer" "asgtestlb01" {
  name              = "asgtestlb01"
  network_interface {
    switch_id    = sakuracloud_switch.testswitch.id
    vrid         = 200
    ip_addresses = ["192.168.0.110"]
    gateway      = "192.168.0.254"
    netmask      = 24
  }
  vip {
    vip    = "192.168.0.200"
    port   = 80
    server {
      ip_address = "192.168.0.2"
      protocol   = "tcp"
      path       = "/index.html"
      status     = "200"
    }
  }
}

server.tf

#############################################
# server
#############################################


data "sakuracloud_archive" "ubuntu" {
  os_type = "ubuntu2004"
}

resource "sakuracloud_disk" "vpctestdisk" {
  name                 = "vpctestdisk"
  plan                 = "ssd"
  connector            = "virtio"
  size                 = 20
  source_archive_id    = data.sakuracloud_archive.ubuntu.id
  encryption_algorithm = "aes256_xts"
}

resource "sakuracloud_server" "vpctestserver" {
  name   = "vpctestserver01"
  disks  = [sakuracloud_disk.vpctestdisk.id]
  core   = 1
  memory = 2
  network_interface {
    upstream        = sakuracloud_switch.testswitch.id
    user_ip_address = "192.168.0.2"
  }
  disk_edit_parameter {
    hostname   = "vpctestserver01"
    password   = "xxxxxxxxxxxx"
    ip_address = "192.168.0.2"
    netmask    = 24
    gateway    = "192.168.0.254"
  }
}

resource "sakuracloud_disk" "vpctestdisk2" {
  name                 = "vpctestdisk02"
  plan                 = "ssd"
  connector            = "virtio"
  size                 = 20
  source_archive_id    = data.sakuracloud_archive.ubuntu.id
  encryption_algorithm = "aes256_xts"
}

resource "sakuracloud_server" "vpctestserver02" {
  name   = "vpctestserver02"
  disks  = [sakuracloud_disk.vpctestdisk2.id]
  core   = 1
  memory = 2
  network_interface {
    upstream        = sakuracloud_switch.testswitch.id
    user_ip_address = "192.168.0.103"
  }
  disk_edit_parameter {
    hostname   = "vpctestserver02"
    password   = "xxxxxxxxxxxx"
    ip_address = "192.168.0.103"
    netmask    = 24
    gateway    = "192.168.0.254"
  }
}

vpcrouter.tf

#############################################
# VPCRouter
#############################################

resource "sakuracloud_vpc_router" "vpcrouter" {
  name = "vpctestrouter01"
  private_network_interface {
    index        = 1
    switch_id    = sakuracloud_switch.testswitch.id
    ip_addresses = ["192.168.0.254"]
    netmask      = 24
  }
  private_network_interface {
    index        = 2
    switch_id    = sakuracloud_switch.testswitch2.id
    ip_addresses = ["192.168.1.254"]
    netmask      = 24
  }

  port_forwarding {
    protocol     = "tcp"
    public_port  = 22
    private_ip   = "192.168.0.103"
    private_port = 22
  }
  depends_on = [
    sakuracloud_switch.testswitch
  ]
}


192.168.0.103のサーバは踏み台として利用し、103からロードバランサーとオートスケールの検証(curlとか)を行おうと思います。

おわり

次からはオートスケールの検証を行っていこうと思います。
が、ロードバランサーにサーバをぶら下げる場合はsysctl.confとInterface系の設定(Ubuntuだと/etc/netplan/01-netcfg.yaml)が必要で、その設定を都度手動でやるのが面倒なので、こっそりansible作っています。。。


さくらのクラウドのデータベース構築をTerraform化する

gokigenmaru.hatenablog.com
こちらの記事で構築した構成をTerraform化しようと思います。

Terraform

構成

昨日構築した環境の構成図です。

以前Terraform化したものとの違いは以下の通りです。

  1. VPCルータに構成図左側のサーバに対するSSHのポートフォワーディングの設定の追加
  2. Switch2の構築
  3. VPCルータにSwitch2との接続用セグメントの追加
  4. (思い付きで)DBのBackup取得設定の追加

Terraformコード

変更がないものについては本ブログの上にリンクを貼ってある以前のブログのコードを参考にしてください
※provider.tf、server.tfは変更なしです

database.tf

#############################################
# Database
#############################################

resource "sakuracloud_database" "vpctestdb01" {
  name = "vpctestdb01"
  plan          = "10g"
  database_type = "mariadb"
  username = "mariadb"
  password = "xxxxxxxxxxxx"
  network_interface {
    switch_id     = sakuracloud_switch.testswitch2.id
    ip_address    = "192.168.1.2"
    netmask       = 24
    gateway       = "192.168.1.254"
    port          = 3306
    source_ranges = ["192.168.0.0/24", "192.168.1.0/24"]
  }

  backup {
    time     = "03:00"
    weekdays = ["sun"]
  }
}

switch.tf

#############################################
# switch
#############################################

resource "sakuracloud_switch" "testswitch" {
  name = "vpctestswitch01"
}

resource "sakuracloud_switch" "testswitch2" {
  name = "vpctestswitch02"
}

vpcrouter.tf

#############################################
# VPCRouter
#############################################

resource "sakuracloud_vpc_router" "vpcrouter" {
  name = "vpctestrouter01"
  private_network_interface {
    index        = 1
    switch_id    = sakuracloud_switch.testswitch.id
    ip_addresses = ["192.168.0.254"]
    netmask      = 24
  }
  private_network_interface {
    index        = 2
    switch_id    = sakuracloud_switch.testswitch2.id
    ip_addresses = ["192.168.1.254"]
    netmask      = 24
  }

  port_forwarding {
    protocol     = "tcp"
    public_port  = 22
    private_ip   = "192.168.0.2"
    private_port = 22
  }
  depends_on = [
    sakuracloud_switch.testswitch
  ]
}

おわり

何度も作るものについては自動化してしまうのが一番いいですね。
でもデータベース内でテーブル作ったりするのはTerraformだと難しいですね、local-execとかを使えば出来るかもしれませんが、それをするにはInternet越しでDBにログインできるようにしないといけないし。