ラベル terraform の投稿を表示しています。 すべての投稿を表示
ラベル terraform の投稿を表示しています。 すべての投稿を表示

2024年10月19日土曜日

terraform の nifcloud provider を使って Gitlab Runner を構築してみた

terraform の nifcloud provider を使って Gitlab Runner を構築してみた

概要

こちらを使ってみました

環境

  • Ubuntu 24.04
  • terraform 1.9.7
    • nifcloud provider 1.16

インストール

sudo apt update && sudo apt install -y gnupg software-properties-common
wget -O- https://apt.releases.hashicorp.com/gpg | \

gpg --dearmor | \
sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg > /dev/null

gpg --no-default-keyring \
--keyring /usr/share/keyrings/hashicorp-archive-keyring.gpg \
--fingerprint

echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] \
https://apt.releases.hashicorp.com $(lsb_release -cs) main" | \
sudo tee /etc/apt/sources.list.d/hashicorp.list

sudo apt update
sudo apt install terraform

terraform -install-autocomplete

事前準備

Gitlab 側の任意のプロジェクトで Runner を登録する準備をしましょう
glrt- から始まるトークンが取得できれば OK です
このトークンは後述する variables.tf の token 変数として使われ環境変数から読み込みます

また今回は nifcloud を使うので nifcloud のアクセスキーとシークレットキーを準備しておいてください

main.tf

今回は3つのリソースを作成します

  • Runner 本体
  • Runner パラメータグループ
  • Runner と Gitlab の紐づけ

流れとして Runner 本体を作成後にパラメータグループを作成しそのパラメータグループを使って Runner と Gitlab を紐づけます

今回は紐づける Gitlab は https://gitlab.com をデフォルトの値にしています

resource "nifcloud_devops_runner" "test" {
  name              = var.runner_name
  instance_type     = var.instance_type
  availability_zone = var.az
  concurrent        = var.concurrent
  description       = var.description
}

resource "nifcloud_devops_runner_parameter_group" "test" {
  name = var.parameter_group_name
}

resource "nifcloud_devops_runner_registration" "group_runner" {
  runner_name          = var.runner_name
  gitlab_url           = var.gitlab_url
  parameter_group_name = var.parameter_group_name
  # 事前にgitlabからrunnerを登録するためのトークンを取得しておくこと
  token = var.token
}

variables.tf

変数を定義します
各種変数には default を用意していますが必要に応じて変更もしくは環境変数 TF_VAR_xxx から上書きしてもらって OK です

token は環境変数を使って挿入するので default はありません

variable "runner_name" {
  default = "test-runner"
  type    = string
}

variable "instance_type" {
  default = "c-small"
  type    = string
}

variable "az" {
  default = "east-11"
  type    = string
}

variable "concurrent" {
  default = 10
  type    = number
}

variable "description" {
  default = "memo"
  type    = string
}

variable "parameter_group_name" {
  default = "test-pg"
  type    = string
}

variable "gitlab_url" {
  default = "https://gitlab.com"
  type = string
}

variable "token" {
  type      = string
  sensitive = true
}

providers.tf

nifcloud プロバイダを使う定義を記載してるだけです
リージョンなど必要に応じて変更してください

terraform {
  required_providers {
    nifcloud = {
      source = "nifcloud/nifcloud"
    }
  }
}

provider "nifcloud" {
  region = "jp-east-1"
}

注意事項

自身 Gitlab と作成した Runner が疎通できていないといけないので一度実行して Runner を作成したあとに IP が払い出されるんのでその IP を Gitlab のファイアウォールに追加してあげてから再度 apply すれば Runner 登録も完了します

動作確認

  • terraform init
  • TF_VAR_token=glrt-xxx NIFCLOUD_ACCESS_KEY_ID=xxx NIFCLOUD_SECRET_ACCESS_KEY=xxx terraform plan
  • TF_VAR_token=glrt-xxx NIFCLOUD_ACCESS_KEY_ID=xxx NIFCLOUD_SECRET_ACCESS_KEY=xxx terraform apply

Gitlab 側から Runner が登録されていれば OK です

最後に

Runner トークンを払い出すのが面倒ですがそれもうまくいけば自動化できるかなと思います

現状は複数のトークンを指定することはできませんがうまくやれば count と組み合わせて一括登録的なこともできるかなと思います

参考サイト

2020年4月2日木曜日

terraform graph を使って tfstate からサーバ構成図を出力してみた

概要

terraform には graph というサブコマンドがありこれを使うとインフラの構成を図にすることができます
今回は AWS 上にインスタンスを作成してそれを terraform graph で構成図にしてみました

環境

  • macOS 10.15.4
  • terraform 0.12.9
  • aws provider 2.55.0

AWS に適当にインスタンスを作成

過去に紹介した記事と同様に aws に 1 台インスタンスを作成しましょう

graphviz のインストール

  • brew install graphviz

terraform graph で構成図を出力してみる

  • terraform graph | dot -Tpng > graph.png
  • open graph.png

でこんな感じの構成図が出力できました

meta.count-boundary なんちゃらみたいなやつは表示されてしまうようです
https://github.com/hashicorp/terraform/issues/20063

brast-radius も良さそう

更にビジュアライズできるツールとして blast-radius というツールもあるようです
こちらは色も付くので更に見やすくなりそうです
https://github.com/28mm/blast-radius

最後に

terraform graph を試してみました
tfstate があれば graphviz を使って簡単に構成図を出力できるのは嬉しい点かなと思います

2019年9月28日土曜日

Terraform vSphere 最速入門

概要

とりあえず動かしてみたい人向けです
クローン元の VM は事前に作成してあることが前提です

環境

  • vSphere 6.7.0.30000
  • terraform v0.12.1
  • CentOS 7.7.1908

事前準備

今回はクローンすることで VM を作成します
またストレージやネットワークなども事前に準備済みとします

tf ファイル

おそらくクローンで VM を作成する際の最低限の設定になります

  • vim resources.tf
variable "vsphere_user" {}
variable "vsphere_password" {}
variable "vsphere_server" {}

provider "vsphere" {
  user           = "${var.vsphere_user}"
  password       = "${var.vsphere_password}"
  vsphere_server = "${var.vsphere_server}"

  allow_unverified_ssl = true
}

data "vsphere_datacenter" "dc" {
  name = "dc1"
}

data "vsphere_datastore" "datastore" {
  name          = "datastore1"
  datacenter_id = "${data.vsphere_datacenter.dc.id}"
}

data "vsphere_compute_cluster" "cluster" {
  name          = "cluster1"
  datacenter_id = "${data.vsphere_datacenter.dc.id}"
}

data "vsphere_network" "network" {
  name          = "network1"
  datacenter_id = "${data.vsphere_datacenter.dc.id}"
}

data "vsphere_virtual_machine" "template" {
  name          = "seed_vm1"
  datacenter_id = "${data.vsphere_datacenter.dc.id}"
}

resource "vsphere_virtual_machine" "vm" {
  name             = "terraform-test"
  resource_pool_id = "${data.vsphere_compute_cluster.cluster.resource_pool_id}"
  datastore_id     = "${data.vsphere_datastore.datastore.id}"

  num_cpus = 2
  memory   = 1024
  guest_id = "${data.vsphere_virtual_machine.template.guest_id}"

  scsi_type = "${data.vsphere_virtual_machine.template.scsi_type}"

  network_interface {
    network_id   = "${data.vsphere_network.network.id}"
    adapter_type = "vmxnet3"
  }

  disk {
    label            = "disk0"
    size             = "${data.vsphere_virtual_machine.template.disks.0.size}"
    eagerly_scrub    = "${data.vsphere_virtual_machine.template.disks.0.eagerly_scrub}"
    thin_provisioned = "${data.vsphere_virtual_machine.template.disks.0.thin_provisioned}"
  }

  clone {
    template_uuid = "${data.vsphere_virtual_machine.template.id}"

    customize {
      linux_options {
        host_name = "terraform-test"
        domain    = "test.internal"
      }

      network_interface {
        ipv4_address = "192.168.100.11"
        ipv4_netmask = 24
      }

      ipv4_gateway = "192.168.100.1"
    }
  }
}

動作確認

  • terraform init
  • terraform plan -var 'vsphere_user=administrator@vsphere.local' -var 'vsphere_password=xxxxxxxxxx' -var 'vsphere_server=192.168.100.10'
  • terraform apply -var 'vsphere_user=administrator@vsphere.local' -var 'vsphere_password=xxxxxxxxxx' -var 'vsphere_server=192.168.100.10'

削除

  • terraform destroy -var 'vsphere_user=administrator@vsphere.local' -var 'vsphere_password=xxxxxxxxxx' -var 'vsphere_server=192.168.100.10'

軽く解説

使っている terraform の機能 (リソース) は variable, provider, data そして resource になります
実際に VM を作成しているのは resource になります

variable はその名の通り変数を定義しています
今回は vCenter の「ログインユーザ名」「パスワード」「アドレス」を変数にしています
.tf ファイル内に書いても問題ないですが今回は実行時に引数で実行するようにしました

providervSphere Provider を使う定義をしています
変数で設定した認証情報はここに設定します

data は vSphere 内の各リソース (データセンターやクラスタ、データストア、ネットワーク、テンプレートなど) を定義します
各リソース内で datacenter_id を指定しています
これは Moref で取得できる ID で名前ではありません
terraform では ${data.vsphere_datacenter.dc.id} という感じで事前に定義したデータセンターの data を使うことで自動的に Moref からデータセンターの ID を引っ張ってきて設定してくれます
ID を引っ張ってくるのは terraform plan 時に取得して確認します
Provider が提供する参照可能なデータはリファレンスを見ると良いです

resourece で VM の作成を行います
今回はクローンして VM を作成するので vsphere_virtual_machine.clone リソースを使います
ここでクローン元の VM を指定します
template_uuid には事前に data で定義した data "vsphere_virtual_machine" "template" から id を参照すれば OK です
あとはディスクの情報とネットワークの情報を指定すれば OK です
今回は作成する VM の IP アドレスは固定 IP を指定するので IP の情報も記載しました
DHCP 環境のネットワークであれば IP アドレスやゲートウェイの指定は不要です
それ以外の情報はクローン元の VM と同じにするので ${data.vsphere_virtual_machine.template.disks.0.size} みたいな感じでクローン元の VM の情報を参照しています

最後に

Terraform vSphere をとりあえず動かしてみました
今回は紹介しませんでしたが実はポイントはクローン元の VM でこっちがちゃんと設定できていないと apply に失敗します

例えば vmware-tools のインストール漏れやネットワークインタフェースの設定が漏れていると IP アドレスが取得できなくてエラーになることがあります
vSphere Provider で VM がうまく作成できない場合は大抵ネットワーク周りかなと思います

あとは今回はすべてのリソースを resources.tf 配下に作成しましたが terraform は *.tf ファイルを自動で読み込んでくれるので各リソースごとに設定などをまとめたりできます

参考サイト

2019年6月18日火曜日

terraform-inventory 最速入門

概要

terraform-inventory の挙動をとりあえず動かしてサクっと確認したい人向けの記事です
ただ執筆時点での結論から言うと terraform の最新バージョン 0.12 には対応していないため対応までは採用見送りかなと思っています

環境

  • macOS 10.14.5
  • ansible 2.5.5
  • terraform 0.12.1 -> 0.11.14

terraform インストール

  • brew install terraform@0.11

0.12 にはまだ対応していないので 0.11 をインストールする

example.tf

  • vim example.tf
provider "aws" {
  region = "us-east-2"
}

resource "aws_instance" "web1" {
  ami = "ami-0ebbf2179e615c338"
  instance_type = "t2.nano"
  key_name = "sshkey"
  tags = {
    Role = "web1"
  }
}

key_name = "sshkey" は事前に作成済みを想定しています

AWS にインスタンス作成

  • terraform init
  • terraform plan
  • terraform apply

ansible インストール

  • brew install ansible

terraform-inventory インストール

  • brew install terraform-inventory
  • terraform-inventory -inventory terraform.tfstate

Inventory ファイルの情報が出力されることを確認します

playbook 作成

  • vim example.yml
---
- hosts: role_web1
  tasks:
    - name: Install nginx
      shell: "amazon-linux-extras install nginx1.12"
      become: yes
    - name: Start nginx
      systemd:
        name: nginx.service
        state: started
      become: yes

playbook 適用

  • ansible-playbook -i $(which terraform-inventory) example.yml -u ec2-user --private-key /path/to/sshkey.pem

動作確認

  • curl ec2-3-14-84-102.us-east-2.compute.amazonaws.com

パブリック DNS の部分は適宜変更してください

解説

terraform

provider aws を使って AWS 上にインスタンスを作成します
ami = "ami-0ebbf2179e615c338" は Amazon Linux2 になります
ポイントは tags でこれを付与することで ansible の hosts としてインスタンスを指定することができます

ansible

terraform.tfstate というファイルを元に terraform-inventory というコマンドが自動的にインベントリ情報を生成してくれます
このようにプログラムが動的にインベントリ情報を生成する仕組みを Dynamic Inventory といいます
ec2 に生成したインスタンスに ssh ログインするには ec2-user ユーザの指定と鍵の指定が必要になります

また今回の動作確認は nginx をインストールして起動しています
ec2 に適用されるセキュリティブループは default を想定しているおり 80 でのアクセスができるようにしておいてください

最後に

terraform-inventory を試してみました
.tfstate ファイルを元にインベントリ情報を動的に生成してくれるツールです
最新版に対応するのは時間の問題かなと思いますが、今後も terraform のバージョンアップにより .tfstate のフォーマットが変更されることを考えると Dynamic Inventory 用のスクリプトを自作するほうが良いかもしれません

参考サイト

2017年10月26日木曜日

terraform に入門してみた (docker 編)

概要

terraform を試してみました
terraform はインフラ自動構築するためのツールでコード化することができます
terraform にはたくさんのプロバイダがあり今回は docker プロバイダを使って試してみました

環境

  • CentOS 7.3
  • terraform 0.10.7

terraform のインストール

まずはインストールです
hashicorp 製品はバイナリを一つ置いて終了です

  • wget 'https://releases.hashicorp.com/terraform/0.10.7/terraform_0.10.7_linux_amd64.zip?_ga=2.150895542.1898133342.1508819233-1686377386.1508819233' -O terraform_0.10.7_linux_amd64.zip
  • unzip terraform_0.10.7_linux_amd64.zip
  • mv terraform /usr/local/bin

とりあえず試してみる

公式の Getting Started にあるサンプルをとりあえず実行してみましょう

  • vim main.tf
provider "docker" {
  host = "tcp://127.0.0.1:2376/"
}

# Create a container
resource "docker_container" "foo" {
  image = "${docker_image.ubuntu.latest}"
  name  = "foo"
}

resource "docker_image" "ubuntu" {
  name = "ubuntu:latest"
}

dockerd の tcp 接続を有効にしている場合は上記で OK です
socket 接続の場合はコメントアウトすれば OK です
dockerd の tcp 接続の有効化に関してはこちら を参考にしてください

.tf ファイルが記載できたら初期化します

  • terraform init

これで docker プロバイダのインストールが始まります
完了すると .terraform というディレクトリが作成されています
terraform は実行する前に実行計画を確認することができます

  • terraform plan

実行すると作成されるリソースの一覧とその情報が表示されます
今回であれば pull されるイメージの情報や作成されるコンテナの情報が表示されます

では実行してみましょう

  • terraform apply

apply コマンドで実行できます
実際に .tf ファイルに記載した内容のコンテナとイメージが作成されます
確認は docker コマンドでもできますが terraform で作成したリソースだけを表示することもできます

  • terraform show

show コマンドを実行することで terraform 経由で pull したイメージやコンテナの情報だけを表示することができます

リソースを削除する

terraform 経由で作成されたリソースのみ削除したい場合は destroy コマンドを利用します

  • terraform destroy

基本的にはこれで削除したほうが良いと思います
もちろん docker rm などを使えばそれでも削除できますが面倒なので一気に削除したい場合は destroy を使うと良いと思います
デフォルトだとリソースの削除時に確認があるので確認が不要な場合は -force を付与してください
また、plan コマンドで-destroy オプションを付与すると削除時の計画を表示することも可能です

インフラ構成を変更する

terraform では一度構築した環境を変更することもできます
以下のように .tf ファイルを書き換えてみましょう

  • vim main.tf
provider "docker" {
  host = "tcp://127.0.0.1:2376/"
}

# Create a container
resource "docker_container" "foo" {
  image = "${docker_image.ubuntu.latest}"
  name  = "foo2"
}

resource "docker_image" "ubuntu" {
  name = "ubuntu:latest"
}

コンテナの名前を変更しただけです
これで再度 apply するとコンテナの名前が変わっていると思います
docker プロバイダの場合コンテナの名前が変更されたわけではなく実際は前のコンテナが削除されて別のコンテナが作成されています

プロビジョニングする

terraform ではインスタンスなどを構築時にスクリプトを実行してプロビジョニングすることも可能です
ただ、docker プロバイダではプロビジョンの機能は提供されていません (当然ですが)
AWS のリソースなどを扱える aws_instance などでは使うことができます

変数を利用する

場合によっては apply 時に毎回情報を書き換えたい場合があると思います
そんなときは変数を使うことができます
.tf ファイルを以下のように書き換えましょう

  • vim main.tf
variable "container_name" {
  default = "hoge"
}

provider "docker" {
  host = "tcp://127.0.0.1:2376/"
}

# Create a container
resource "docker_container" "foo" {
  image = "${docker_image.ubuntu.latest}"
  name  = "${var.container_name}"
}

resource "docker_image" "ubuntu" {
  name = "ubuntu:latest"
}

variable を使って変数を使用することができます
default を使えばデフォルト値を設定することもできます
参照するときは ${var.container_name} として参照することができます (なぜか var. なので注意)

  • terraform apply

で実行すると default の値が使用されます

  • terraform plan -var container_name="fuga"
  • terraform apply -var container_name="fuga"

とすると fuga というコンテナを作成することができます

また key = value 形式のファイルを作成して -var-file でファイルを参照することもできます
変数には list や map 形式で定義することもできます

特定の結果を表示する

apply で実行した結果を確認したいケースはあると思います
そんなときは output リソースを使用することで指定した結果を取得することができます

  • vim main.tf
variable "container_name" {
  default = "hoge"
}

provider "docker" {
  host = "tcp://127.0.0.1:2376/"
}

# Create a container
resource "docker_container" "foo" {
  image = "${docker_image.ubuntu.latest}"
  name  = "${var.container_name}"
}

resource "docker_image" "ubuntu" {
  name = "ubuntu:latest"
}

output "id" {
  value = "${docker_container.foo.id}"
}

最後の output リソースがそれに当たります
上記の場合は作成されたコンテナの id を取得します

  • terraform apply

で実行したあとに

  • terraform output id

とすることで id の情報を取得することができます

モジュール化する

terraform では .tf ファイルをモジュールにすることができます
モジュール化した .tf ファイルを参照することでモジュール内のリソースを使用することができるようになります

.tf ファイル内で modules の定義をして terraform get を実行するとモジュールの .tf ファイルを取得できます

今回は試さないので詳しくはこちらを試してみてください
サンプルは consul 用の module を使用しています

Remote Backends

それ以外には Remote Backends という機能があり terraform で実行した履歴や状態を保存しておくことができます
自分一人で使っている場合には不要なのですが、例えばプロダクションなどの環境でいろんなホストから実行される場合などにどこまで apply しているかを確認することができようになります

こちらも今回は試していないので興味があれば公式を見ながら試してみてださい

最後に

terraform を試してみました
公式の Getting Started は AWS 環境を使っていますが準備が大変だったのでさらっとできる docker プロバイダで試してみました

正直 docker-compose で足りるような気もしますが docker コマンドのオペレーションもこれを使えばコード化できるのが嬉しい点かなと思います
ただ docker build はできないっぽいので、それは terraform 以外の世界で事前に作成する必要があります

参考サイト