RaspberryPi
raspbian
Terraform

Terraformでかんたんraspberry piセットアップ

ラズパイ3を使ってWeb Bluetooth APIをやってみたく久しぶりにセットアップからやってみようと。
しかしながらラズパイのセットアップっていつも面倒ですよねー。
モニタとキーボードつなげて固定IP振ってSSH接続してようやくスタートみたいな。

そんなときインフラ勉強会でTerraformというものを知りました。

AWSやAzure,GCPなどで使われる環境構築ツールです。
golangで実装されているのでexeを配置するだけでインストールも簡単です。

本来の用途とはちょっと異なりますがこれを使ってディスプレイやキーボードなしでも
ラズパイをセットアップしてRDP接続してみました。

使ったもの

・Windows10
・Terraform v0.11.1
・Bonjour Print Services
・Raspbian Stretch with desktop November 2017

セットアップ

TerraformのWin64bit用をダウンロードして解凍。
Cドライブ直下に配置してPATHにセットしました。

https://www.terraform.io/downloads.html

ラズパイにホスト名(raspberry.local)でアクセスするために
Bonjour Print Servicesを入れました。

https://support.apple.com/kb/DL999?locale=ja_JP&viewlocale=ja_JP

raspbianを落として16GBのSDカードに焼きました。

PCとラズパイをLANケーブルで直結します。
PCのUSBポートに接続してラズパイの電源をONします。

設定ファイル(第1陣)

Terraformの設定ファイルを書き.tfで保存します。
wlan0に固定IPをセットします。

raspi_wifi.tf
variable "raspi_ip" {
  default = "raspberrypi.local"
}

resource "null_resource" "raspi_wifi" {

  connection {
    type = "ssh"
    user = "pi"
    host = "${var.raspi_ip}"
    password = "raspberry"
  }

  provisioner "remote-exec" {
    inline = [
      "sudo sh -c 'wpa_passphrase ssid password >> /etc/wpa_supplicant/wpa_supplicant.conf'",
      "sudo sh -c 'echo \"interface wlan0\" >> /etc/dhcpcd.conf'",
      "sudo sh -c 'echo \"static ip_address=192.168.0.20/24\" >> /etc/dhcpcd.conf'",
      "sudo sh -c 'echo \"static routers=192.168.0.1\" >> /etc/dhcpcd.conf'",
      "sudo sh -c 'echo \"static domain_name_servers=192.168.0.1\" >> /etc/dhcpcd.conf'",
      "sudo reboot"
    ]
  }
}

いざ実行(第1陣)

ping raspberrypi.localで接続を確認したら実行します。

C:\terraform_0.11.1_windows_amd64>terraform.exe apply -target=null_resource.raspi_wifi

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

Terraform will perform the following actions:

  + null_resource.raspi_wifi
      id: <computed>


Plan: 1 to add, 0 to change, 0 to destroy.

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

null_resource.raspi_wifi: Creating...
null_resource.raspi_wifi: Provisioning with 'remote-exec'...
null_resource.raspi_wifi (remote-exec): Connecting to remote host via SSH...
null_resource.raspi_wifi (remote-exec):   Host: raspberrypi.local
null_resource.raspi_wifi (remote-exec):   User: pi
null_resource.raspi_wifi (remote-exec):   Password: true
null_resource.raspi_wifi (remote-exec):   Private key: false
null_resource.raspi_wifi (remote-exec):   SSH Agent: false
null_resource.raspi_wifi (remote-exec): Connected!
null_resource.raspi_wifi: Still creating... (10s elapsed)
null_resource.raspi_wifi: Creation complete after 10s (ID: 5564360285778435530)

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

C:\terraform_0.11.1_windows_amd64>

再起動を待ち、Pingを飛ばしてみると応答がありました。

C:\terraform_0.11.1_windows_amd64>ping 192.168.0.20

192.168.0.20 に ping を送信しています 32 バイトのデータ:
192.168.0.20 からの応答: バイト数 =32 時間 =71ms TTL=64
192.168.0.20 からの応答: バイト数 =32 時間 =7ms TTL=64
192.168.0.20 からの応答: バイト数 =32 時間 =7ms TTL=64
192.168.0.20 からの応答: バイト数 =32 時間 =5ms TTL=64

192.168.0.20 の ping 統計:
    パケット数: 送信 = 4、受信 = 4、損失 = 0 (0% の損失)、
ラウンド トリップの概算時間 (ミリ秒):
    最小 = 5ms、最大 = 71ms、平均 = 22ms

C:\terraform_0.11.1_windows_amd64>

SSH接続して設定を確認します。
ちゃんと設定されていますね。

pi@raspberrypi:~ $ ifconfig wlan0
wlan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.0.20  netmask 255.255.255.0  broadcast 192.168.0.255
        inet6 fe80::7215:39ac:9f30:1f99  prefixlen 64  scopeid 0x20<link>
        inet6 240f:7b:96b1:1:4f85:988f:58ed:8716  prefixlen 64  scopeid 0x0<global>
        ether b8:27:eb:f2:e6:b2  txqueuelen 1000  (Ethernet)
        RX packets 64  bytes 8154 (7.9 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 61  bytes 9163 (8.9 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

pi@raspberrypi:~ $ tail -4 /etc/dhcpcd.conf
interface wlan0
static ip_address=192.168.0.20/24
static routers=192.168.0.1
static domain_name_servers=192.168.0.1

設定ファイル(第2陣)

WindowsからRDPでつなげたいのでxrdpを入れてキーボードの設定をします。

https://qiita.com/suppy193/items/e2f811dd136780099ceb

raspi_xrdp.tf
variable "raspi_ip" {
  default = "raspberrypi.local"
}

resource "null_resource" "raspi_xrdp" {

  connection {
    type = "ssh"
    user = "pi"
    host = "${var.raspi_ip}"
    password = "raspberry"
  }

  provisioner "remote-exec" {
    inline = [
      "sudo apt-get update",
      "sudo apt-get -y install xrdp",
      "sudo wget http://w.vmeta.jp/temp/km-0411.ini -P /etc/xrdp",
      "sudo ln -s /etc/xrdp/km-0411.ini /etc/xrdp/km-e0010411.ini",
      "sudo ln -s /etc/xrdp/km-0411.ini /etc/xrdp/km-e0200411.ini",
      "sudo ln -s /etc/xrdp/km-0411.ini /etc/xrdp/km-e0210411.ini",
    ]
  }
}

いざ実行(第2陣)

ログは長いので省略します。
Apply complete! で正常に完了したようなので接続してみます。

おお、なんと簡単ではないか。

まとめ

本来の使い方ではないかもだが、僕が便利だからこれはこれでよいのです。
ぶっちゃけ同じことはansibleでもできるけどansibleはWindowsじゃ動かないですしね。

ラズパイ使ってインフラ自動化を学んで行こうと思いました。(おしまい)

※みんなもおいでよインフラ勉強会