LoginSignup
3
1

More than 5 years have passed since last update.

[OCI] Terraform を 使って Block Volume バックアップのリストアとマウント (2018/12/25)

Last updated at Posted at 2018-12-25

コードを使用してインフラストラクチャのトポロジを定義するHashicorp社のTerraformを使ってOracle Cloud InfrastructureでInfrastructure as Code(IaC)を実現することができます。

この記事では、Terraformを使ってOCI Block Volumeのバックアップをリストアし、にLinuxインスタンスからマウントしてみたことを紹介します。

今回構築する構成

image02.jpg

事前にOracle LinuxのVMインスタンスにマウントされているBlock Volumeのバックアップを取得しておき、準備していたVCN/Subnetに新規にOracle LinuxのVMインスタンスを作成し、バックアップしていたBlock Volumeをリストアし、マウントする構成を以下のファイルから作成します。

ファイル名 内容
data_sources.tf 作成したリソース情報の取得
instance.tf Computeインスタンスの作成
provider.tf Terraform OCI Provider設定
variables.tf 変数・値の定義
volume.tf バックアップから新規Block Volumeの作成
volume_attach.tf Block Volumeのアタッチ・iSCSI接続・ファイスシステムのマウント

(すべてのファイルは本ページの最下部にまとめて記載/env-vars.ps1を除く)

準備作業

環境を構築をする上で、使用する環境の情報および作成するインスタンスへの接続に必要な情報を準備します。
準備に必要な情報は
Oracle Cloud Advent Calendar 2018」の12月10日の記事
Terraform を 使って Oracle Cloud環境構築 (2018/12/10)」などを参照してください。

以下のOCIDを取得して、variables.tfに記入
・Block Volume バックアップのOCIDを取得
image03.jpg

・VMインスタンスを作成するサブネットのOCIDを取得

インスタンス の作成

変数の追加(Linux VM/VM.Standard2.1 シェイプ を作成)

variables.tf
variable "NumInstances" {
  default = "2"
}
variable "instance_image_ocid" {
  type = "map"

  default = {
    // See https://docs.us-phoenix-1.oraclecloud.com/images/
    // Oracle-provided image "Oracle-Linux-7.5-2018.05.09-1"
    us-ashburn-1 = "ocid1.image.oc1.iad.aaaaaaaa6ybn2lkqp2ejhijhehf5i65spqh3igt53iyvncyjmo7uhm5235ca"
  }
}

variable "instance_shape" {
  default = "VM.Standard2.1"
}

NumInstances」で作成するインスタンスの数を指定します。
そのほか作成するインスタンスのシェイプ、イメージを指定します。

instance.tf
resource "oci_core_instance" "TF_instance" {
  count               = "${var.NumInstances}"
  availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[var.availability_domain - 1],"name")}"
  compartment_id      = "${var.compartment_ocid}"
  display_name        = "TF instances${count.index}"
  hostname_label      = "TFinstance${count.index}"
  shape               = "${var.instance_shape}"
  subnet_id           = "${var.TF_SubnetOCID}"

  metadata {
    ssh_authorized_keys = "${var.ssh_public_key}"
  }

  source_details {
    source_type = "image"
    source_id   = "${var.instance_image_ocid[var.region]}"
  }

  timeouts {
    create = "60m"
  }

}

Blcok Volumeのリストア

変数の追加

リストアするBlock Volume BackupのOCIDを指定します。

variables.tf
variable "volume_backup_ocid" {
  default = "ocid1.volumebackup.oc1.iad.abuwcljtdmtyzcgzeu3pvhhch3sqvsxpqvuomul2fw5hoscqivhbaie5mera"
}
リストアしてBlock Volume の作成
volume.tf
resource "oci_core_volume" "datavolume" {
  count               = "${var.NumInstances}"
  availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[var.availability_domain - 1],"name")}"
  compartment_id      = "${var.compartment_ocid}"
  display_name        = "attact-tf-volume${count.index}"
  source_details {
    #Required
#    id = "${data.oci_core_volume_backups.test_volume_backups.id}"
    id = "${var.volume_backup_ocid}"
    type                   = "volumeBackup"
  }
}

Blcok Volumeのアタッチ、iSCSI接続、ファイルシステムのマウント

Mount Targetの作成
volume_attach.tf
resource "oci_core_volume_attachment" "backup_volume_attachments" {
  depends_on = ["oci_core_instance.TF_instance",
  "oci_core_volume.datavolume",
  ]
  count           = "${var.NumInstances}"
  attachment_type = "iscsi"
  compartment_id  = "${var.compartment_ocid}"
  instance_id     = "${oci_core_instance.TF_instance.*.id[count.index]}"
  volume_id       = "${oci_core_volume.datavolume.*.id[count.index]}"

    connection {
      agent       = false
      timeout     = "15m"
      host        = "${oci_core_instance.TF_instance.*.public_ip[count.index % var.NumInstances]}"
      user        = "opc"
      private_key = "${var.ssh_private_key}"
    }

  # register and connect the iSCSI block volume
  provisioner "remote-exec" {
    inline = [
      "sudo iscsiadm -m node -o new -T ${self.iqn} -p ${self.ipv4}:${self.port}",
      "sudo iscsiadm -m node -o update -T ${self.iqn} -n node.startup -v automatic",
      "sudo iscsiadm -m node -T ${self.iqn} -p ${self.ipv4}:${self.port} -l",
    ]
  }

  # initialize partition and file system
  provisioner "remote-exec" {
    inline = [
      "sudo systemctl start ocid.service",
      "set -x",
      "export DEVICE_ID=ip-${self.ipv4}:${self.port}-iscsi-${self.iqn}-lun-1",
      "sudo mkdir -p /mnt/vol01",
      "export UUID=$(sudo /usr/sbin/blkid -s UUID -o value /dev/sdb1)",
      "echo 'UUID='$${UUID}' /mnt/vol01 xfs defaults,_netdev,nofail 0 2' | sudo tee -a /etc/fstab",
      "sudo mount -a",
    ]
  }
}

環境構築の実行

すべてのファイルが用意できたら以下のコマンドを実行し環境を作成します。

  • terraform init
  • terraform plan -out plan01
  • terraform apply "plan01"

作成されたインスタンスの確認

instance0 への接続

/dev/sdb1 が /mnt/vol01 にマウントされていることを確認

[root@tfinstance0 ~]# df -h
Filesystem      Size  Used Avail Use% Mounted on
devtmpfs        7.2G     0  7.2G   0% /dev
tmpfs           7.3G     0  7.3G   0% /dev/shm
tmpfs           7.3G  8.6M  7.3G   1% /run
tmpfs           7.3G     0  7.3G   0% /sys/fs/cgroup
/dev/sda3        39G  1.8G   37G   5% /
/dev/sda1       512M  9.8M  502M   2% /boot/efi
tmpfs           1.5G     0  1.5G   0% /run/user/1000
/dev/sdb1        50G   33M   50G   1% /mnt/vol01```

おわりに

terraform を使って OCI Block Volumeのバックアップをリストアし、にLinuxインスタンスからマウントできることを確認しました。

以下のファイルはgithubからも確認できます。
https://github.com/kenwatan/terraform_BlockVolumeRestoreMount

data_sources.tf
# Gets a list of Availability Domains
data "oci_identity_availability_domains" "ADs" {
  compartment_id = "${var.tenancy_ocid}"
}

instance.tf
resource "oci_core_instance" "TF_instance" {
  count               = "${var.NumInstances}"
  availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[var.availability_domain - 1],"name")}"
  compartment_id      = "${var.compartment_ocid}"
  display_name        = "TF instances${count.index}"
  hostname_label      = "TFinstance${count.index}"
  shape               = "${var.instance_shape}"
  subnet_id           = "${var.TF_SubnetOCID}"

  metadata {
    ssh_authorized_keys = "${var.ssh_public_key}"
  }

  source_details {
    source_type = "image"
    source_id   = "${var.instance_image_ocid[var.region]}"
  }

  timeouts {
    create = "60m"
  }

}
provider.tf
provider "oci" {
  version          = ">= 3.0.0"
  tenancy_ocid     = "${var.tenancy_ocid}"
  user_ocid        = "${var.user_ocid}"
  fingerprint      = "${var.fingerprint}"
  private_key_path = "${var.private_key_path}"
  region           = "${var.region}"
}
variables.tf
variable "tenancy_ocid" {}
variable "user_ocid" {}
variable "fingerprint" {}
variable "private_key_path" {}
variable "region" {}

variable "compartment_ocid" {}

# Refer https://docs.us-phoenix-1.oraclecloud.com/Content/Compute/Tasks/managingkeypairs.htm on how to setup SSH key pairs for compute instances
variable "ssh_public_key" {}

variable "ssh_private_key" {}

variable "api_public_key" {
  default = "-----BEGIN PUBLIC KEY-----aaaaaaaaXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX+1qg64wel39kHkppz4Fv2vaLXF9qIeDjeo3G4sHQIDAQAB-----END PUBLIC KEY-----"
}

variable "NumInstances" {
  default = "1"
}

variable "instance_shape" {
  default = "VM.Standard2.1"
}
# Choose an Availability Domain
variable "availability_domain" {
  default = "2"
}

variable "TF_SubnetOCID" {
  default = "ocid1.subnet.oc1.iad.aaaaaaaaXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}

variable "instance_image_ocid" {
  type = "map"

  default = {
    // See https://docs.us-phoenix-1.oraclecloud.com/images/
    // Oracle-provided image "Oracle-Linux-7.5-2018.05.09-1"
    eu-frankfurt-1 = "ocid1.image.oc1.eu-frankfurt-1.aaaaaaaazregkysspxnktw35k4r5vzwurxk6myu44umqthjeakbkvxvxdlkq"

    us-ashburn-1 = "ocid1.image.oc1.iad.aaaaaaaa6ybn2lkqp2ejhijhehf5i65spqh3igt53iyvncyjmo7uhm5235ca"
    uk-london-1  = "ocid1.image.oc1.uk-london-1.aaaaaaaayodsld656eh5stds5mo4hrmwuhk2ugin4eyfpgoiiskqfxll6a4a"
    us-phoenix-1 = "ocid1.image.oc1.phx.aaaaaaaaozjbzisykoybkppaiwviyfzusjzokq7jzwxi7nvwdiopk7ligoia"
  }
}

variable "volume_backup_ocid" {
  default = "ocid1.volumebackup.oc1.iad.aaaaaaaaXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
volume.tf
resource "oci_core_volume" "datavolume" {
  count               = "${var.NumInstances}"
  availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[var.availability_domain - 1],"name")}"
  compartment_id      = "${var.compartment_ocid}"
  display_name        = "attact-tf-volume${count.index}"
  source_details {
    #Required
#    id = "${data.oci_core_volume_backups.test_volume_backups.id}"
    id = "${var.volume_backup_ocid}"
    type                   = "volumeBackup"
  }
}
volume_attach.tf
resource "oci_core_volume_attachment" "backup_volume_attachments" {
  depends_on = ["oci_core_instance.TF_instance",
  "oci_core_volume.datavolume",
  ]
  count           = "${var.NumInstances}"
  attachment_type = "iscsi"
  compartment_id  = "${var.compartment_ocid}"
  instance_id     = "${oci_core_instance.TF_instance.*.id[count.index]}"
  volume_id       = "${oci_core_volume.datavolume.*.id[count.index]}"

    connection {
      agent       = false
      timeout     = "15m"
      host        = "${oci_core_instance.TF_instance.*.public_ip[count.index % var.NumInstances]}"
      user        = "opc"
      private_key = "${var.ssh_private_key}"
    }

  # register and connect the iSCSI block volume
  provisioner "remote-exec" {
    inline = [
      "sudo iscsiadm -m node -o new -T ${self.iqn} -p ${self.ipv4}:${self.port}",
      "sudo iscsiadm -m node -o update -T ${self.iqn} -n node.startup -v automatic",
      "sudo iscsiadm -m node -T ${self.iqn} -p ${self.ipv4}:${self.port} -l",
    ]
  }

  # initialize partition and file system
  provisioner "remote-exec" {
    inline = [
      "sudo systemctl start ocid.service",
      "set -x",
      "export DEVICE_ID=ip-${self.ipv4}:${self.port}-iscsi-${self.iqn}-lun-1",
      "sudo mkdir -p /mnt/vol01",
      "export UUID=$(sudo /usr/sbin/blkid -s UUID -o value /dev/sdb1)",
      "echo 'UUID='$${UUID}' /mnt/vol01 xfs defaults,_netdev,nofail 0 2' | sudo tee -a /etc/fstab",
      "sudo mount -a",
    ]
  }

  # unmount and disconnect on destroy
  provisioner "remote-exec" {
    when       = "destroy"
    on_failure = "continue"

    inline = [
      "set -x",
      "export DEVICE_ID=ip-${self.ipv4}:${self.port}-iscsi-${self.iqn}-lun-1",
      "export UUID=$(sudo /usr/sbin/blkid -s UUID -o value /dev/sdb1)",
      "sudo umount /mnt/vol01",
      "if [[ $UUID ]] ; then",
      "  sudo sed -i.bak '\\@^UUID='$${UUID}'@d' /etc/fstab",
      "fi",
      "sudo iscsiadm -m node -T ${self.iqn} -p ${self.ipv4}:${self.port} -u",
      "sudo iscsiadm -m node -o delete -T ${self.iqn} -p ${self.ipv4}:${self.port}",
    ]
  }

}
3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1