ksaitoの日記

日々試したことの覚え書き

Windowsのパッケージ管理をChocoletyからscoopに変更

Windowsのパッケージ管理としてChocoletyを使ってきました。

今日から、scoopに切り替えます。

PowerShellで、下記のコマンドでインストールできます。

Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://get.scoop.sh')
iwr -useb get.scoop.sh | iex

想像通り、下記のようにするとgitがインストールできます。

scoop install git

chocoletyのように管理者権限が必要ないのがいいです。

terraformでキーペアを作る

terraformで普段使っている公開鍵でキーペアを作ります。

$ cat -n provider.tf variable.tf local.tf main.tf
     1  provider "aws" {
     2    profile = "terraform"
     3    region  = "ap-northeast-1"
     4  }
     5  variable "key_name" {
     6    default = "mykey"
     7  }
     8  variable "public_key_path" {
     9    default = "~/.ssh/id_rsa.pub"
    10  }
    11  locals {
    12    key_name = format("%s-%s", var.key_name, terraform.workspace)
    13  }
    14  module "key_pair" {
    15    source = "terraform-aws-modules/key-pair/aws"
    16
    17    key_name   = local.key_name
    18    public_key = file(var.public_key_path)
    19  }

使い捨てのEC2インスタンスを作るときに便利です。

terraformでデフォルトVPCを扱う

ちょっとした、検証をする場合に、都度、VPCを作りたくないので、デフォルトVPCを使いたいことがよくあります。

terraformでデフォルトVPCのVPCIDを参照するには、dataを使うのが良さそうです。

コードの取得

下記のコマンドでサンプルコードを取得します。

git clone https://gitlab.com/softlab-pub/terraform/sample.git -b 20200515-0955 --depth 1
cd sample/vpc/default_vpc

簡単な説明

コードは、下記の通りで、dataを使ってデフォルトVPCの情報を取得して表示します。

terraformで、スコープがモジュール内の変数は、localsに集めて定義すると、tfファイルの保守性が向上します。

$ cat -n main.tf 
     1  provider "aws" {
     2    profile = "terraform"
     3    region  = "ap-northeast-1"
     4  }
     5
     6  data "aws_vpc" "target_vpc" {
     7    default = true
     8  }
     9
    10  locals {
    11    vpc_id = data.aws_vpc.target_vpc
    12  }
    13
    14  output "vpc_id" {
    15    value = local.vpc_id.id
    16  }

使い方

初期化して変更内容を確認します。

terraform init

terraform planで適用される変更を確認することができます。 No changesと出ているので何かを変更してしまうことはありません。

terraform plan

applyするとデフォルトVPCのVPCIDが表示されます。

$ terraform apply
data.aws_vpc.target_vpc: Refreshing state...

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

vpc_id = vpc-******
$

terraform outputで外部に公開する情報を確認できます。 取得できている情報は、terraform showで確認することができます。

使い終わったら削除します。

下記の通り、変更予定の内容を表示して確認を求められます。

$ terraform destroy
data.aws_vpc.target_vpc: Refreshing state...

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:

Terraform will perform the following actions:

Plan: 0 to add, 0 to change, 0 to 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


Destroy complete! Resources: 0 destroyed.
$

シェルの未定義変数

bashで未定義な変数があった場合、下記のように処理していました。

$ cat test1.sh
#! /bin/bash

VAR1=$1

if [ -z "$VAR1" ]
then
    echo needs arg1
    exit 1
fi

echo ok $VAR1

下記のように動作します。

$ ./test1.sh
needs arg1
$ echo $?
1
$ ./test1.sh aaa
ok aaa
$ echo $?
0
$ 

set -uを使うとシンプルになります。

$ cat test2.sh
#! /bin/bash

set -u

VAR1=$1
echo ok $VAR1
$ ./test2.sh 
./test2.sh: 行 5: $1: 未割り当ての変数です
$ echo $?
1
$ ./test2.sh aaa
ok aaa
$ echo $?
0
$

画面ショットを取る

画面ショットを取る方法をいつも忘れてしまうのでメモしておきます。

範囲 Mac OS Windows 10
範囲指定 Shift + Command + 4 Win + Shift + S
指定のウィンドウ N/A Alt + Print
全画面 Shift + Command + 3 Shift + Print

Mac OSは、controlキーを追加するとクリップボードにイメージを保管します。

既存のVPCをterraformで扱う方法について考えました。

既存のVPCの情報をインポートしてterraform管理下に置く方法は、たくさん見つかりましたがVPCを扱う権限がなかったり、管理されたVPCを使うだけというケースでは、dataを使うのが良さそうです。

使い方

variable.tfdata.tfoutput.tfというファイルを使います。

data.tfに次のように定義します。

locals {
  vpc_id = var.vpc_id
}

data "aws_vpc" "target_vpc" {
  id = local.vpc_id
}

data "aws_subnet_ids" "subnet_ids" {
  vpc_id = local.vpc_id
}

data "aws_subnet" "target_subnet" {
  for_each = data.aws_subnet_ids.subnet_ids.ids
  id       = each.value
}

入力となるvariable.tfは、次のように定義します。 vpc-*****には、リソースを作成するVPC IDをハードコードするか、オプションやファイルから渡します。

variable "vpc_id" {
  default = "vpc-*****"
}
variable "region" {
  default = "ap-northeast-1"
}

output.tfで下記のように定義します。

output "vpc" {
  value = data.aws_vpc.target_vpc.id
}

output "subnets" {
  value = [for s in data.aws_subnet.target_subnet : s.id]
}

provider.tfは、下記のように定義して、接続情報を適宜設定します。

provider "aws" {
  region = var.region
  version = "= 2.58.0"
}

あとは、下記のコマンドで、情報を収集して表示します。

terraform init
terraform apply
terraform output

以上

terraformのtfファイル

terraformのtfファイルのお作法について考えました。

ファイルの分割

terraformは、カレントディレクトリのtfファイルを読み込みます。

ファイルの分割やファイル名の付け方は、開発者に委ねられているので、下記のようにすることで、どこに何があるか見通しが良くなります。

目的のリソースは、main.tfに書く

tfファイルが増えても、main.tfを見ることで意図が伝わります。

利用者が変更可能な変数は、variables.tfに書く

利用者が変更可能なパラメータを、variables.tfに一箇所で定義します。

tfへのインプットが明確になりパラメータ名の整合性が取りやすくなります。

利用者が変更不可なパラメータは、locals.tfに書く

localsは、最近のバージョン0.12で導入された変数です。

利用者は、変更できないパラメータとして共通化するときに使います。

利用者が参照できる出力は、outputs.tfに書く

利用者は、ここに書かれた出力のみ参照できます。

その他のリソースは、リソース名.tfに書く

AWSであれば、security-group.tfやiam.tfといったファイルに書きます。

main.tfから参照されるリソース名.tfとつけることで参照しやすくなります。

以上