コードを使用してインフラストラクチャのトポロジを定義するHashicorp社のTerraformを使ってOracle Cloud InfrastructureでInfrastructure as Code(IaC)を実現することができます。
この記事では、Terraformを使ってOCI Block Volumeのバックアップをリストアし、にLinuxインスタンスからマウントしてみたことを紹介します。
今回構築する構成
事前に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を取得
・VMインスタンスを作成するサブネットのOCIDを取得
インスタンス の作成
変数の追加(Linux VM/VM.Standard2.1 シェイプ を作成)
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
」で作成するインスタンスの数を指定します。
そのほか作成するインスタンスのシェイプ、イメージを指定します。
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を指定します。
variable "volume_backup_ocid" {
default = "ocid1.volumebackup.oc1.iad.abuwcljtdmtyzcgzeu3pvhhch3sqvsxpqvuomul2fw5hoscqivhbaie5mera"
}
リストアしてBlock Volume の作成
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の作成
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
# Gets a list of Availability Domains
data "oci_identity_availability_domains" "ADs" {
compartment_id = "${var.tenancy_ocid}"
}
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 "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}"
}
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"
}
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"
}
}
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}",
]
}
}