terraform使ってみたときの色々メモ
terraformとは
要は、クラウドの環境を作成するときに手順書作ってマニュアルで作成するのではなく、
その辺も全部コードでやってしまおうというツールのようです。
(コードで管理できると環境自体をバージョン管理しやすかったり、属人性を排除できたり良いことあります)
目的(私の場合)
スクレイピングのスクリプトをColaboratoryでテストしてて、
それを一晩中動かしたいときとかにサクッとサーバーを立ち上げる用とか
環境
cloudshell
デフォルトのcloudshellのdockerイメージにterraformがインストールされているので、カスタムイメージを作る必要はなし
前提
GCRにDocker imageがpushしてある
(参考)pythonスクレイピング用のDockerfile
seleniumとbeautiful soup使って、pandasデータフレームにスクレイピング結果投入して
pandasからBigQueryにInsertしたいときに使えるDockerfile
GCPのJSONキーファイルとスクレイピング用のpythonファイルはDockerfileと同一ディレクトリにある前提
FROM python:3
ARG project_dir=/selenium/
ARG credential_json=<JSONキーファイル名>
ADD requirements.txt $project_dir
ADD $credential_json $project_dir
ADD <スクレイピングpythonファイル> $project_dir
ENV GOOGLE_APPLICATION_CREDENTIALS ./$credential_json
WORKDIR $project_dir
RUN apt-get update
RUN apt-get install -y vim less python3-selenium
RUN pip install -r requirements.txt
CMD ["/bin/bash"]
selenium==3.141.0
requests==2.23.0
pandas==1.0.4
bs4==0.0.1
google-cloud-bigquery==1.21.0
pandas-gbq==0.11.0
lxml==4.5.1
terraform設定ファイル(tfファイル)を作る
適当なディレクトリにリソースを定義するファイル(tfファイル)を作成する
main.tf
GCEに関する諸々を設定するメインのファイル
provider "google" {
credentials = "${file("<JSONキーファイル>")}"
project = "${var.project_name}"
region = "${var.region}"
}
data "google_compute_network" "default" {
name = "default"
}
resource "google_compute_instance" "apps-gcp-terraform" {
name = "selenium-docker"
machine_type = "n1-standard-1"
zone = "${var.zone}"
boot_disk {
auto_delete = true
initialize_params {
image = "${var.boot_image_name}"
type = "pd-standard"
}
}
metadata = {
gce-container-declaration = "${var.docker_declaration}"
}
network_interface {
network = "default"
access_config {
}
}
service_account {
email = "<サービスアカウント>"
scopes = ["cloud-platform"]
}
}
variables.tf
パラメータを扱うファイル
Docker imageからGCEインスタンス作る場合は、container-optimized imageというブートイメージを使用する
現在のcontainer-optimized imageのバージョンは以下コマンドで確認できる
gcloud compute images list --project cos-cloud --no-standard-images
variable "project_name" {
type = string
default = "<プロジェクトID>"
}
variable "region" {
type = string
default = "us-central1"
}
variable "zone" {
type = string
default = "us-central1-a"
}
variable "boot_image_name" {
type = string
default = "projects/cos-cloud/global/images/cos-stable-81-12871-119-0"
}
variable "docker_declaration" {
type = string
default = "spec:\n containers:\n - name: selenium-docker\n image: '<dockerイメージ>'\n stdin: false\n tty: true\n restartPolicy: Always\n"
}
terraformでGCEインスタンスを作成する
tfファイルがあるディレクトリで以下コマンドを実行していく
1. terraform init
terraformを初期化する
成功すると、実行したディレクトリに .terraformディレクトリが作成され必要なプラグインとかがインストールされるっぽい
こんなメッセージ出るときは
Terraform has initialized, but configuration upgrades may be needed.
terraform 0.12upgrade
↑する
いい感じにtfファイルを最新のバージョンに更新してくれるっぽい
2. terraform plan
tfファイルが正しいかチェックする
エラー出たらtfファイル修正する
3. terraform apply
gcp にアップする
途中で実行するか聞かれるのでyesを入力
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
google_compute_instance.apps-gcp-terraform: Creating...
google_compute_instance.apps-gcp-terraform: Still creating... [10s elapsed]
google_compute_instance.apps-gcp-terraform: Creation complete after 13s
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
↑みたいな感じででたらOK
あとは作られたGCEインスタンスに入って
docker container ls
するとコンテナが稼働しているので、
docker container exec -it コンテナID /bin/bash
等のコマンドでコンテナの中に入り、
nohup python スクレイピングpythonファイル > log.txt 2>&1 &
とかでプログラム実行させる
インスタンスを削除する
terrafrom destroy
Do you really want to destroy all resources?
Terraform will destroy all your managed infrastructure, as shown above.
There is no undo. Only 'yes' will be accepted to confirm.
Enter a value:yes
で削除される
ハマりどころ
サービスアカウントをアタッチする
Error: Cannot get auth token: Metadata server responded with status 404
が起きたとき、、
GCEのメタデータサーバーからトークンゲットできないということらしい、、
で、インスタンスの中で以下コマンドを実行すると、
curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" \
-H "Metadata-Flavor: Google"
↓のメッセージが出る
Service account not enabled on this instance
ということで、サービスアカウントのアタッチをmain.tfに追加したらOKとなった↓
service_account {
email = "<サービスアカウント>"
scopes = ["cloud-platform"]
}
参考
terraformドキュメント
インスタンスの作成と構成
Terraform で変数を使う
GCPインフラ構築自動化の道 part1 ~Terraform 導入編~
TerraformでGoogle Compute EngineにWebアプリをデプロイする。
Terraform 0.12がリリースされたのでアップグレードしてみた
TerraformでGCP環境を構築してみる
scopes param for service_account of google_compute_instance should be optional