Corredor

ウェブ、プログラミングの勉強メモ。

OCI の Resource Manager を使って Terraform を実行する

Oracle Cloud Infrastructure (OCI) の中にある Oracle Resource Manager (ORM) というサービスを使うと、OCI 上で Terraform 定義ファイルを実行でき、状態管理ファイルを一元管理できる。

Terraform で OCI の操作をしたことがある人なら始めるのは簡単なので、紹介する。

Resource Manager はどこにある?

リソースマネージャは、

  • OCI コンソール → ハンバーガーメニュー → 「Solutions, Platform and Edge」セクション → 「Resource Manager」リンク

と進む。

Stack と Job

最初に表示されるのは「Stacks」というリソースで、その他に「Jobs」というリソースがあるのが分かる。

これらは何かというと、1つの Terraform ファイル群を Stack と呼んでおり、その Stack 定義を元に terraform コマンドが実行される1回の履歴を Job として管理するのだ。つまり、Stack : Job = 1 : n という関係。

Stack が Terraform 定義ファイルを置いているディレクトリで、Job がコマンドの実行履歴、といったところで良いだろう。

Terraform 定義ファイルの注意点

Resource Manager という名前だが、実態は単なる Terraform 実行基盤だ。使用する Terraform 定義ファイルは、ローカル開発マシンで terraform コマンドを使って実行した時のファイルがほぼそのまま使える。

ただ、Resource Manager 特有の特徴として、provider.oci には region プロパティ以外の指定が要らない、というところが特徴だ。region だけは、対象のリージョンを特定するために必要だが、Tenancy OCID だったり、Terraform を実行するユーザの情報、といったものは必要ない。Resource Manager 自身が manage all-resources in tenancy な特権を持っている状態だ。

この仕様による弊害は、OCI の場合は oci_containerengine_cluster_kube_config Data Source を使った KubeConfig ファイルの生成が出来なくなることぐらいだろうか。local_file を使ったファイル出力もできないので、KubeConfig ファイルの生成は Resource Manager を使わず別の手段をとろう。

Stack を作る

それでは、まずは Stack を作ってみよう。先程書いたとおり、Resource Manager はテナンシー内のどこにあるリソースでも作成・更新できるので、当該 Stack が所属するコンパートメントと、作れるリソースの範囲は関係ない。

Stack 作成画面で、Terraform 定義ファイル群をまとめた Zip ファイルをアップロードする。すると、ファイル内の variable 宣言と default 値を読み取って、変数のフォームをある程度自動入力してくれる。

公式ドキュメントを読むと、terraform.tfvars*.auto.tfvars というファイルが Zip 内にあれば、その値を勝手に代入してくれるっぽいのだが、自分が試した限りでは変数値の代入はしてくれなかった。.tfvars ファイルから手作業で値をコピペしよう。

なお、配列の変数に関しては、テキストボックスに [ "hoge" ] といった形で書いていけば良い。

Job を実行する

Stack が作れたら、その Stack 定義を元に Terraform を実行する。選択できる Action は Plan、Apply、Destroy の3つで、terraform planterraform applyterraform destroy コマンドと同じだ。

実際に Plan なり Apply なりを実行してみると、ステータスが「Accepted」になると思う。そこから数分待つと「In Progress」ステータスに移行し、実際に Terraform が実行されている様子が「Logs」画面で分かる。サラッと書いたが、1回のコマンド (Job) 実行に5〜10分くらいかかるので、動作速度は物凄く遅い。

こうして作業が終わると、実行結果は「Outputs」欄に表示される。「Logs」欄もそうだが、まさに terraform コマンドの実行結果がそのまま出力されている。

この Resource Manager の利点は、状態管理ファイル .tfstate の共有が不要になること。Terraform の機能にリモートステートといったモノがあるが、その設定すら不要になる。一度アップした Terraform ファイル群は Resource Manager からダウンロードできるし、複数の開発者で一つの Terraform ファイルを編集し、リソースを更新していきやすいのが特徴だろう。

削除について

Stack を削除する場合は、きちんと「Destroy」Job を実行してから Stack を Delete するようにしないと、リソースが残ったままになってしまうので注意。

また、Stack を削除した後、その Stack が所属していたコンパートメントを削除しようとすると、「Job」リソースが裏側でまだ残ったままとみなされてしまい、コンパートメントの削除に失敗してしまった。コレはどうやったら解決できるのか、まだ分かっていない。しばらく放置してみるか。


以上。実行速度が著しく遅いが、定義ファイルなどを共用しやすいので、例えば本番環境の構築などは、ローカルから Terraform を叩くのではなく、Resource Manager を使うようにしておくと良いかもしれない。

Terraform - Up & Running: Writing Infrastructure As Code

Terraform - Up & Running: Writing Infrastructure As Code

Infrastructure as Code ―クラウドにおけるサーバ管理の原則とプラクティス

Infrastructure as Code ―クラウドにおけるサーバ管理の原則とプラクティス

DevOpsを支えるHashiCorpツール大全 ThinkIT Books

DevOpsを支えるHashiCorpツール大全 ThinkIT Books

サブウィンドウの二重起動を防ぐ JavaScript

懐かしいコードが出てきたので紹介。

確か IE で window.open() しようとした時に、既に開いているウィンドウを無視して同じページを別ウィンドウで開いてしまうのが気になって、それをなんとかするために作ったモノ。だから変数宣言が var だったりする。

/**
 * 二重起動を防ぎウィンドウを開く
 * 
 * @param {string} windowName ウィンドウ名
 * @param {string} url 開きたい URL
 */
function openWindow(windowName, url) {
  // 指定のウィンドウ名で空の URL を開いてみる
  var win = window.open('', windowName);
  
  // 開いたウィンドウの URL が about:blank だったら、空ウィンドウが開けたことになる
  if(win.location.href === 'about:blank') {
    // 空ウィンドウが開けた = その名前のウィンドウはそれまで存在していなかったので
    // 開いたウィンドウの location.href に開きたいページを指定する
    win.location.href = url;
  }
  else {
    // ウィンドウの URL が about:blank ではなかった場合、既にそのウィンドウは存在している
    // この場合も変数 win にはウィンドウの参照が取得できているので、以下のように掴んだウィンドウを閉じて開き直したりできる
    win.close();
    window.open(url, windowName);
  }
}

もう言うことはない。

レガシーコード改善ガイド (Object Oriented SELECTION)

レガシーコード改善ガイド (Object Oriented SELECTION)

  • 作者: マイケル・C・フェザーズ,ウルシステムズ株式会社,平澤章,越智典子,稲葉信之,田村友彦,小堀真義
  • 出版社/メーカー: 翔泳社
  • 発売日: 2009/07/14
  • メディア: 大型本
  • 購入: 45人 クリック: 673回
  • この商品を含むブログ (157件) を見る

レガシーソフトウェア改善ガイド

レガシーソフトウェア改善ガイド

OCI で Terraform を始めてみる

インフラ構築を自動化できる Terraform。コレを Oracle Cloud Infrastructure (OCI) で動かしてみる。

Terraform をインストールする

Terraform は、Vagrant などで知られる HashiCorp が提供している。terraform コマンドは以下の公式ページからダウンロードできる。

ダウンロードした Zip ファイルを解凍すると、MacOS 向けの場合は terraform という実行可能ファイル、Windows 向けの場合は terraform.exe というファイルが出てくる。コレを PATH の通っている場所に置くだけで良い。

Terraform 実行用の OCI ユーザを作成する

Terraform は、各種クラウドサービスが提供する API をコールする「ラッパー」でしかなく、OCI 環境を触るためには、その環境でリソースを作れる権限を持ったユーザアカウントを用意しないといけない。

細かな手順は省略するが、全体的な流れとしては以下のとおり。

  1. OCI 管理コンソールにログインする
    • この時、Tenancy 詳細を開き、Tenancy の OCID と、操作したいリージョンの名前を控えておく
  2. Identity → Users と移動し、Terraform 実行用の User を作成する
    • 作成した User の OCID は控えておく
  3. Identity → Groups と移動し、Terraform 実行用ユーザが所属する Group を作成する
  4. 作成した Group に Terraform 実行用 User を所属させる
  5. Identity → Policies と移動し、Terraform 実行用ユーザが所属する Group に対し、Tenancy 全体や Compartment 配下のリソースを操作できる権限を付与する
    • Terraform から OCI ユーザを作ったりもできるので、最初はテナンシー全体で何でもできる Allow group 【グループ名】 to manage all-resources in tenancy といったステートメントを付与してしまうのが手っ取り早いかと思う
  6. Terraform 実行用 User に登録するための API 鍵ペアを作成する
    • $ openssl genrsa -out ./api_key.pem 2048 コマンドで秘密鍵を作成する
    • $ openssl rsa -pubout -in ./api_key.pem -out ./api_key_public.pem コマンドで公開鍵を作成する
  7. 生成した公開鍵ファイルを Terraform 実行用 User の API Keys に登録する
    • 登録後に表示される Fingerprint を控えておく

以上の操作で、

  1. 操作対象の Tenancy の OCID
  2. 操作対象のリージョン名
  3. Terraform 実行用 User の OCID
  4. Terraform 実行用 User に登録した API Key の Fingerprint
  5. Terraform 実行用 User に登録した API Key の秘密鍵ファイル

の5つの情報が準備できたはずだ。この5つの情報は Terraform 定義ファイルの中で使用することになる。


先程、「Terraform はクラウドサービスの API をコールするラッパーだ」と書いたが、OCI については、OCI CLI という公式のコマンドラインツールを用いると、ほぼ全てのリソースが操作できる。Terraform が操作できる範囲は、この OCI CLI でできる範囲とほとんど変わりなく、OCI 環境を操作するための認証機構もほとんど同じだ。

OCI CLI の場合、$ oci setup config というコマンドを使うと、~/.oci/config というファイルにプロファイル情報が書き込まれる。以下はサンプル。

[DEFAULT]
user=ocid1.user.oc1..xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
fingerprint=xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx
key_file=/PATH/TO/.oci/oci_api_key.pem
tenancy=ocid1.tenancy.oc1..xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
region=us-ashburn-1

先程準備するよう記載した、5つの情報が列挙されていることが分かるだろうか。つまり、この OCI CLI 向けのプロファイル情報を流用すれば、Terraform を使って同じ範囲を操作できるということだ。

Terraform 定義ファイルを書く

それではいよいよ、Terraform 定義ファイルを書いていく。適当な作業ディレクトリを作ったら、形式的に以下のようにファイルを作ろう。

$ mkdir terraform-oci-test
$ cd $_
$ touch main.tf
$ touch variables.tf
$ touch terraform.tfvars
$ touch outputs.tf

Terraform は、カレントディレクトリ内にある .tf 形式のファイルを全て拾い上げて結合して実行してくれる。拡張子さえ守っていれば、1ファイルに全ての情報を記載しても、細かくファイルを分けても、動作には変わりない。ただ、ベストプラクティスとして、

  1. main.tf … プロバイダの指定やリソースの定義
  2. variables.tf … 変数の定義
  3. outputs.tf … アウトプットの定義

という3つのファイルはお決まりで作ることが多い。

terraform.tfvars というファイルは、変数に対して値を設定するためのファイル。.env ファイル的なモノと思えばよいだろう。コチラは慣例的にこのようなファイル名、拡張子を取るが、コマンド実行時に引数でこのファイルを指定しないと参照されないので、例えば環境別に env_dev.tfvarsenv_prod.tfvars などと名付けて複数ファイルを用意しても良い。

この辺り、広く採用される「ベストプラクティス」はあるものの、構築する環境の規模や内容によっても変わってくるし、Terraform のバージョンアップによって新機能が追加されたりするとまた変わってくるので、「そのディレクトリを開いた時に全体的な構成が読み取りやすい状態であること」をとりあえず意識できれば良いかなと思う。

今回は、作成済のVM (Compute Instance) を1台作成するサンプルを作ってみた。以降は、各ファイルに記述する内容を記していく。

main.tf

main.tf には、「OCI を操作しますよー」という「プロバイダ宣言」や、リソース作成時に定数的に参照するようなリソース定義をしたりする。

/* 
 * OCI プロバイダ定義 : https://www.terraform.io/docs/providers/oci/index.html
 */
provider "oci" {
  region           = "${var.region}"
  tenancy_ocid     = "${var.tenancy_ocid}"
  user_ocid        = "${var.user_ocid}"
  fingerprint      = "${var.fingerprint}"
  private_key_path = "${var.private_key_path}"
}

/* 
 * 当該テナンシで利用可能な AD の一覧を取得する : https://www.terraform.io/docs/providers/oci/d/identity_availability_domains.html
 */
data "oci_identity_availability_domains" "my_ads" {
  compartment_id = "${var.tenancy_ocid}"
}

Terraform の構文はひたすらお勉強。全体的には、【リソース種別】 "【予め決まっているリソース名】" "【自分で任意に付ける名前】" { } というブロックで、一つのリソースを宣言する。

プロバイダの宣言である provider "oci" 部分は、任意の名前が付いていないが、コレで「OCI を操作するための Terraform 定義ファイル群である」という宣言がなされている。region だの tenancy_ocid だの、といったプロパティ名は、予め決められているプロパティ名だ。

プロパティに対する値は = "${var.region}" といった形で代入されている。"${文字列}" という記法で、環境変数の値や、よそのリソースの情報などを変数として利用できる。リージョン名や Tenancy の OCID などは、"${var.【環境変数名】}" という記法を使い、環境変数で値を設定するように定義している。環境変数への値の割当方法は後述。

次に記載している data "oci_identity_availability_domains" "my_ads" {} というブロックは、OCI 上の Availability Domain 情報を配列で取得するための Data Sources というモノ。コレを利用して、「AD1 にインスタンスを置こう」とか、「Load Balancer は AD1 と AD2 に割り当てよう」などと記述できるワケだ。

そうそう、コメントは /* */ で複数行コメントができる他、単一行コメントは //# のいずれかで記述できる。ココらへんはお好みで。

instance.tf

ココで、今回は VM (Compute Instance) を構築しようとしているので、そのリソースを定義するためのファイルを別に作っておこうと思う。名前は任意だが、分かりやすく instance.tf とした。中身は以下のとおり。

/* 
 * Instance 監視サーバ : https://www.terraform.io/docs/providers/oci/r/core_instance.html
 */
resource "oci_core_instance" "my_instance" {
  compartment_id      = "${var.compartment_ocid}"
  availability_domain = "${lookup(data.oci_identity_availability_domains.my_ads.availability_domains[0], "name")}"  // AD1
  shape               = "${var.instance_shape}"
  display_name        = "my-instance"
  source_details {
    source_type = "image"
    source_id   = "${var.instance_image_ocids[var.region]}"  // 当該リージョン用のイメージの OCID を指定する
  }
  create_vnic_details {
    subnet_id        = "${var.subnet_ocid}"  // Subnet の OCID
    assign_public_ip = true                  // Public IP を割り当てる
    hostname_label   = "myinstance"
  }
  metadata {
    ssh_authorized_keys = "${var.instance_ssh_public_key}"
  }
}

resource から始まるブロックで、「何らかのリソースを作成する定義」を行う。今回は oci_core_instance、つまり Compute Instance を作るためのリソース定義、ということだ。

availability_domain プロパティ内で、lookup() 関数を使い、AD 一覧の配列 (my_ads) から1つ目の要素を取得し、その中の name プロパティの値を拾っている。コレで kKLm:US-ASHBURN-AD-1 といったような Availability Domain 名を拾い上げ、プロパティに設定している。

今回は小さく作りたいので、VCN や Subnet は別途作成済であるものとして、この Compute Instance を配置する Subnet の指定は、変数 "${var.subnet_ocid}" から行うようにしている。勿論、Terraform で VCN を作り、その下に Subnet を作り、そうして生成された Subnet の OCID を拾い上げ、この Compute Instance を作成する、といった依存関係も実現できる。コード量が増えてしまうので今回は省略するが、記述は難しくないので、OCI Provider の API ドキュメントを見ながら作ってみてほしい。

variables.tf

main.tfinstance.tf の定義で、「何かを作る」ための定義は終わり。variables.tf では、他のファイルで "${var.【変数名】}" と書いて参照した変数の「宣言」のみを列挙しておく。以下のような要領だ。

/* 変数定義 */

variable "region" {
  type        = "string"
  description = "リージョン (ex. us-ashburn-1)"
  default     = "us-ashburn-1"
}

variable "tenancy_ocid"     { description = "テナンシの OCID" }
variable "user_ocid"        { description = "Terraform を実行するユーザの OCID" }
variable "fingerprint"      { description = "Terraform を実行するユーザの API Key のフィンガープリント" }
variable "private_key_path" { description = "Terraform を実行するユーザの API Key 秘密鍵のフルパス" }
variable "compartment_ocid" { description = "コンパートメントの OCID" }

// Compute Instance 関連

variable "instance_image_ocids" {
  description = "インスタンスイメージの OCID マップ"
  type        = "map"
  default     = {
    // - イメージ定義のベスト・プラクティス : https://www.terraform.io/docs/providers/oci/guides/best_practices.html#referencing-images
    // - イメージ情報は次の URL より確認できる : https://docs.us-phoenix-1.oraclecloud.com/images/
    // - 以下は Oracle-Linux-7.6-2019.05.14-0 イメージの OCID を指定している : https://docs.cloud.oracle.com/iaas/images/image/54f22559-7638-4da9-9e09-7fc78527608c/
    us-ashburn-1   = "ocid1.image.oc1.iad.aaaaaaaa4bfsnhv2cd766tiw5oraw2as7g27upxzvu7ynqwipnqfcfwqskla"
    ap-tokyo-1     = "ocid1.image.oc1.ap-tokyo-1.aaaaaaaamc2244t7h3gwrrci5z4ni2jsulwcg76gugupkb6epzrypawcz4hq"
    ap-seoul-1     = "ocid1.image.oc1.ap-seoul-1.aaaaaaaalhbuvdg453ddyhvnbk4jsrw546zslcfyl7vl4oxfgplss3ovlm4q"
    ca-toronto-1   = "ocid1.image.oc1.ca-toronto-1.aaaaaaaakjkxzw33dcocgu2oylpllue34tjtyngwru7pcpqn4qh2nwon7n7a"
    eu-frankfurt-1 = "ocid1.image.oc1.eu-frankfurt-1.aaaaaaaandqh4s7a3oe3on6osdbwysgddwqwyghbx4t4ryvtcwk5xikkpvhq"
    uk-london-1    = "ocid1.image.oc1.uk-london-1.aaaaaaaa2xe7cufdwkksdazshtmqaddgd72kdhiyoqurtoukjklktf4nxkbq"
    us-phoenix-1   = "ocid1.image.oc1.phx.aaaaaaaavtjpvg4njutkeu7rf7c5lay6wdbjhd4cxis774h7isqd6gktqzoa"
  }
}

variable "instance_shape" {
  description = "Compute Instance のシェイプ"
  default     = "VM.Standard1.1"
}

variable "subnet_ocid" {
  description = "Subnet の OCID"
}

variable "instance_ssh_public_key" {
  description = "管理サーバへの SSH 接続用の公開鍵"
}

variable "【変数名】" {} というブロックで、一つの変数の宣言を行う。コレをなくして "${var.【変数名】}" とだけ書くのは、「宣言がないから NG」という関係だ。

type プロパティは必須ではない。大抵は暗黙的に "string" で解釈されるが、中には map などを使うこともある。

description プロパティで説明文を書いておくと、terraform コマンド実行時に説明として表示されるので、単なるコメントとしてではなく、description プロパティで書いておくと良いだろう。

default プロパティも任意だが、コレを書いておくと、環境変数で値を渡さなかった時にその値がデフォルトとして使用される。

変数 instance_image_ocids の書き方は、OCI Provider が公式に推奨しているベスト・プラクティスに沿った書き方。このように変数を用意しておくと、instance.tf"${var.instance_image_ocids[var.region]}" という風に OCID を参照できる。

terraform.tfvars

変数の宣言は variables.tf で行った。変数の使用箇所は main.tfinstance.tf などに登場する。では、変数の値をどう設定するか、というと、簡単なやり方は、.tfvars という拡張子で変数の値を設定したファイルを作ることだ。

/* 変数値ファイル */

region           = "us-ashburn-1"
tenancy_ocid     = "ocid1.tenancy.oc1..xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
user_ocid        = "ocid1.user.oc1..xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
fingerprint      = "xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx"
private_key_path = "/PATH/TO/.oci/oci_api_key.pem"
compartment_ocid = "ocid1.compartment.oc1..xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

// Compute Instance 関連

// instance_image_ocids 変数の値は特に変更しなくて良い
// instance_shape 変数の値も、今回は default 値を使用するので定義しない

// Compute Instance を所属させる Subnet の OCID を設定しておく
subnet_ocid = "ocid1.subnet.oc1.iad.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
// Compute Instance に SSH 接続するための SSH 公開鍵を設定しておく
instance_ssh_public_key = "ssh-rsa xxxxx"

こんな感じ。default 値を使いまわしたいものはいちいち記述する必要はない。ただ、default がない状態で、.tfvars ファイルでも値を設定していない変数があった場合は、コマンド実行時に値を入力するよう問われる。

outputs.tf

最後に outputs.tf。このファイルは、一連のリソース作成が終わった後にコンソール出力したい情報を定義しておく。今回の場合であれば、作成した Compute Instance の Public IP がココで分かれば、そのあとすぐに SSH 接続できたりするだろう。

/* 結果出力 */

// 作成した Compute Instance に割り当てられた Public IP を出力する
output "my_instance_public_ip" {
  value = [ "${oci_core_instance.my_instance.public_ip}" ]
}

結果出力したい情報は output "【適当な名前】" { value = 【出力したい値】 } というブロックで記述する。value プロパティは固定。

instance.tf で、resource "oci_core_instance" "my_instance" { } というブロックでリソースを作るよう定義したが、コレで作ったリソースから情報を引っ張ってくるには、"${【予め決まっているリソース名】.【宣言した任意の名前】.【予め決まっているプロパティ名】}" という形で参照する。コレで、作成された Compute Instance の Public IP が拾えている。

ファイルの準備は以上

コレでファイルの準備は以上だ。どのようなリソースがあって、どんなプロパティがあるか、といった情報は、以下の公式ドキュメントを読み込んでいくしかない。

terraform init でプラグインを準備する

.tf ファイルや .tfvars ファイルが用意できたら、いよいよ実行していきたいワケだが、その前に、これらのファイルがあるディレクトリで$ terraform init というコマンドを実行する。

コレを実行すると、Terraform から OCI を操作するためのプラグインなどをダウンロードして、./.terraform/ ディレクトリ配下に自動的に置いてくれる。

terraform plan で Dry-Run してみる

terraform init で準備したらいよいよ実行…といきたいところだが、いきなりインフラ構築を始めてしまい、コードに間違いがあったりすると、復旧させるのが困難になる場合もある。

そこで、Terraform には実際にインフラ構築をする前にテストするための、$ terraform plan という Dry-Run コマンドがある。コレを使ってみよう。

ココからは、-var-file オプションを使って、用意していた .tfvars ファイルを参照するようにして実行する。

$ terraform plan -var-file='./terraform.tfvars'

このように実行すると、実際にはリソース作成などは行われないものの、コードに間違いがないか、コードを実行した結果、どのようなリソースが追加・変更・破棄されるのか、といった実行計画が確認できる。

output.tf で定義した output 情報は、terraform plan で実行した場合は出力されないので留意。

terraform apply でいよいよ実行する

実行計画を確認して問題なければ、いよいよ実行に移る。実行するには、$ terraform apply コマンドを使う。

$ terraform apply -var-file='./terraform.tfvars'

先程の plan 部分を apply に変更するだけで実行できる。

リソースの作成にかかる時間はまちまちだが、Compute Instance 1台くらいであれば、2・3分もあれば完了するだろう。

時々、terraform plan で異常が見つからなかったのに、terraform apply で実行して初めて問題が発生する場合があったりする。特に output の内容は terraform plan 実行時はあまり厳密にチェックされないので、よくよく注意して実行しよう。

上手く実行できると、OCI 管理画面上でも Compute Instance が作成できていることが確認できるはずだ。また、カレントディレクトリには terraform.tfstate といったファイルが生成されており、Terraform コマンドによってどのようなリソースが作成されたのか、といった履歴が全て記録されている。

terraform destroy で環境を破棄できる

terraform apply で作った環境は、$ terraform destroy というコマンドで丸ごと削除することもできる。

# -destroy オプションを付ければ削除時の実行計画が見られる
$ terraform plan -destroy -var-file='./terraform.tfvars'

# 削除する
$ terraform destroy -var-file='./terraform.tfvars'

今回は Compute Instance 一つの例だから効果が分かりづらいかもしれないが、VCN を丸ごと作るようなコードの場合、OCI 管理画面でポチポチ削除していったりするよりもはるかに容易だ。

今回はココまで

駆け足になったが、Terraform を使って、OCI 上に簡単なリソースを作成・破棄する基礎を紹介した。世間的にはまだマイナーな OCI を例に Terraform を紹介したが、GCP・AWS・Azure なども対応している。各クラウドサービスが提供する CLI ツールなどの使い方を個別に勉強するよりも、Terraform という単一の形式で管理した方が、言語やツールの仕様に関する学習コストは削減できるだろう。また、今回深くは紹介しなかったが、Terraform の機能によって「冪等性の担保」「差分管理」「変更・破棄の容易性」といったメリットを享受できるので、クラウドサービスを活用していく際はぜひとも Terraform を導入していきたい。

Infrastructure as Code ―クラウドにおけるサーバ管理の原則とプラクティス

Infrastructure as Code ―クラウドにおけるサーバ管理の原則とプラクティス

DevOpsを支えるHashiCorpツール大全 ThinkIT Books

DevOpsを支えるHashiCorpツール大全 ThinkIT Books

Terraform: Up and Running: Writing Infrastructure as Code (English Edition)

Terraform: Up and Running: Writing Infrastructure as Code (English Edition)

Twitter の iOS 公式アプリからプロモツイートを消す方法

最近、iPhone で使う Twitter クライアントアプリを、Echofon から Twitter 公式のアプリに変更した。すると、「プロモツイート」と呼ばれる広告ツイートがタイムラインの間に挟まるようになった。コレが目障りなので、消す方法がないか調べてみた。

完全に消す方法はない

まず、プロモツイート自体を完全に非表示にする方法はない。アプリを有料購入する、といった課金での対応はできないのだ。

そこで次に考えられるのは、プロモツイートをするアカウントをブロックすることで非表示にする方法だ。しかし、手作業でシコシコと100アカウントほどブロックしたが、際限がないことが見えてきた。

もう少し調べてみると、「ブロックするアカウント」の情報は CSV でインポート・エクスポートでき、他のユーザと共用できるというのだ。ブロックするアカウントを一括インポーする方法があるということなので、どこかから「プロモツイートしているアカウント一覧」が引っ張って来れれば、それをインポートして大抵の広告を非表示にできるかもしれない、と考えたのだ。

プロモツイートしているアカウント一覧

するとドンズバなページがあった。以下の「プロモツイートしているアカウント一覧」というページだ。

本稿執筆時点で、プロモツイートを行っているアカウントを7,608件も収集していて、そのアカウントリストを CSV で提供してくれている。「アカウントリスト ダウンロード」ボタンより、3000件ずつに分割されている CSV をダウンロードし、Twitter の設定画面より「リストをインポート」すれば良い。

なお、Twitter の画面デザインが最近変更されて、一部で適用されている新デザインでは、リストをインポートする「詳細設定オプション」が表示されていなかった。その場合は、使用するブラウザを変えてやると、旧デザインで作業できると思われる。アカウントのブロック処理は非同期で行われ、多少時間がかかるので、インポートしたら反映されるまでは10分程度待とう。

個人的にはコレで7,000件超のアカウントをブロックしたことで、ほとんどのプロモツイートを駆逐できた。

Block Together

あと、ついでに見つけたのは Block Together というサービス。

コレは外部サービス連携して使うモノ。ブロックすべきアカウント情報をみんなで共有して、みんなでブロックしようというサービスみたい。コレが自動的にアカウントをブロックしていくので、スパムや過激な発言のユーザを駆逐して、クリーンなタイムラインを得られるようだ。

コレの効果はイマイチ分かっていない。既にブロックリストが7,000件を超えている状態だったので、Block Together がどのくらい自動ブロックしているのか分からない。


プロモツイートの駆逐は以上で、以下はオマケ。


全フォロワーの「リツイートを表示しない」にするとタイムラインからノイズが減る

僕は最近、Twitter でのフォロワー数を大きく減らした。「リツイート」機能が公式で実装された辺りから、SNS はもう「楽しいモノ」ではなくなってしまった。有益な情報、面白いツイートは、ひねくれた人間の愚痴や過激な主張に揉み消されてしまっている。そこで、少しでも気に入らないツイートをする人はどんどんフォローを外し、ノイズを減らしていくことにしたのだ。

さらに、フォローしている人自身のツイートは良くても、その人がリツイートしたツイートには興味がないことも分かってきた。その人が賛成のつもりで RT したのか、反対のつもりで RT したのかは知らないが、いずれにしても「その人が関心を示した他人」には、僕は興味がない。

だから、少々手間ではあったが、全フォロワーのページに飛んで、「リツイートを表示しない」設定を適用しまくった。コレでタイムラインには一切リツイートが表示されなくなった。

僕は RSS (Feedly) も使い続けているし、Twitter を何か有益な情報交換・議論の場にする必要はない。ふぁぼったーが流行っていた頃のような、人々の面白い日常のつぶやきを時々垣間見られるだけで十分なのだ。嫌いな人やモノの話も、愚痴も文句も見たくない。ある程度「面白いモノ」を観測しそこねるとしても、視野を狭めてストレス因子を排除する方を優先させたいので、このような対応を取った。

リツイートが流れてこない僕のタイムラインは、とても平穏だ。

以上

バカなノイズが多くてイライラする Twitter も、こうやって工夫すればだいぶクリーンに戻せる。

LINE, Instagram, Facebook, Twitter やりたいことが全部わかる本 この一冊で今すぐはじめられる

LINE, Instagram, Facebook, Twitter やりたいことが全部わかる本 この一冊で今すぐはじめられる

Twitter Perfect GuideBook 改訂版

Twitter Perfect GuideBook 改訂版