2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

terraformでec2上にmateデスクトップ環境を構築(Ubuntu20.04LTS)

Last updated at Posted at 2020-12-30

1. 実行環境

  • Windows10
  • git for windows(必須ではないが、Windows上でbashなどを使うため)
  • Terraform v0.14.3
  • awscli(2.1.14)

前提条件として、aws configureを予め実行しておくなどして、自身のaws環境にawsコマンドでアクセスできるようにしておく。

また、今回terraformとawscliはscoopでインストールしている。

scoop install aws terraform

scoopのインストールは例えば
https://scoop.sh/ (公式)
https://qiita.com/Dooteeen/items/12dc8fb14042888113d0
などを参照

2. 実行

2-1. 必要ファイルの作成

適当なディレクトリに以下のファイルを作成、配置

ファイル構成
$ tree
.
├── main.tf       # terraformファイル
├── provision.sh  # provisioning用スクリプト
└── set_env       # 環境変数設定、必須ではないが便利のため

各ファイルの詳細:

2-1-1. main.tf

main.tf
# 実行環境ごとに変わるものや秘匿したい情報は変数化出来る
variable "key_name" {}
variable "public_key_path" {}
variable "private_key_path" {}

provider "aws" {
  profile = "default"
  region  = "ap-northeast-1"
}

data "aws_ami" "ubuntu" {
  most_recent = true

  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
  }

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }

  owners = ["099720109477"] # Canonical
}

resource "aws_instance" "example" {
  ami = data.aws_ami.ubuntu.id
  instance_type               = "t3a.small"
  key_name                    = aws_key_pair.deployer.id
  associate_public_ip_address = true
  vpc_security_group_ids      = ["${aws_security_group.default.id}"]
  tags = {
    Name = "terraform-ubuntu-mate-test1"
  }
  provisioner "file" {
    source      = "provision.sh"
    destination = "/tmp/provision.sh"
    connection {
      type        = "ssh"
      host        = self.public_ip
      user        = "ubuntu"
      private_key = file(var.private_key_path)
    }
  }
  provisioner "remote-exec" {
    inline = [
      "chmod +x /tmp/provision.sh",
      "/tmp/provision.sh",
    ]

    connection {
      type        = "ssh"
      host        = self.public_ip
      user        = "ubuntu"
      private_key = file(var.private_key_path)
    }
  }
}

resource "aws_key_pair" "deployer" {
  key_name = var.key_name
  public_key = file(var.public_key_path)
}

resource "aws_security_group" "default" {
  name        = "ssh_default_security_group"
  description = "ssh default"

  # SSH access from anywhere
  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

main.tf作成における主な参考リンク:

秘密鍵・公開鍵関係の情報は外部変数として宣言しておき、環境変数TF_VAR_**を設定することでterraform側に渡すようにしている。(後でsource set_envして読み込む)
また、ubuntuのprovisioningはprovision.shという別のスクリプトファイルにしておき、ローカルからEC2側へアップロード・実行させている。

(AWSのWebコンソール上からEC2を普通に作るのと比べると、はじめは一つ一つ記述しないといけないため思った以上に面倒だった。。。)

注意点として、デスクトップ環境構築のためにインスタンスタイプはt3a.smallタイプを指定しているため無料枠の対象外となっている。(t3a.smallにあまり深い意味は無いが、t2.microのメモリ1GBでは流石にスペックが足りないため)

2-1-2. provision.sh

provision.sh
#!/usr/bin/env sh
set -eux

# クラウド側のセットアップ完了を待たないとapt-get等が失敗する
while [ ! -f /var/lib/cloud/instance/boot-finished ]; do
    sleep 1
done

sudo apt-get update

# mate-desktop
sudo apt-get -y install \
    mate-desktop \
    mate-desktop-environment \
    mate-desktop-environment-extra \
    mate-session-manager

# xrdp
sudo apt-get install -y xrdp
sudo sed -e 's/^new_cursors=true/new_cursors=false/g' \
  -i /etc/xrdp/xrdp.ini
sudo service xrdp start

# xrdp xsession
echo "mate-session" > ~/.xsession
XDG_DATA_DIRS=/usr/share/mate:/usr/share/mate:/usr/local/share
XDG_DATA_DIRS=${XDG_DATA_DIRS}:/usr/share:/var/lib/snapd/desktop
cat <<EOF > ~/.xsessionrc
export XDG_SESSION_DESKTOP=mate
export XDG_DATA_DIRS=${XDG_DATA_DIRS}
export XDG_CONFIG_DIRS=/etc/xdg/xdg-mate:/etc/xdg
EOF

# set password
sudo USER_PASSWD=${USER_PASSWD:-changeit} sh -c '
  echo "${USER_PASSWD}\n${USER_PASSWD}" | passwd ubuntu
'

echo "Done: $(basename $0)"

mate-desktopのセットアップは大まかに
https://www.hiroom2.com/2018/05/06/ubuntu-1804-mate-ja/
https://www.hiroom2.com/2018/05/07/ubuntu-1804-xrdp-mate-ja/
を参考にして、xrdpによってリモートデスクトップを使えるようにしている。

特に詰まったポイントは、

while [ ! -f /var/lib/cloud/instance/boot-finished ]; do
    sleep 1
done

の部分。
どうやら「provisioningが始まるタイミング=クラウド側の環境の準備完了」ではないらしく、この部分を入れないとapt-get updateでリポジトリ情報が更新されず、その結果apt-get installでエラーが起こってしまう。
(参考: https://stackoverflow.com/questions/42279763/why-does-terraform-apt-get-fail-intermittently

ここで、ログインユーザーはデフォルトで用意されているubuntuにしており、ログインパスワードはとりあえずchangeitでハードコードしていることに注意。

2-1-3. set_env

先述のterraformファイルで外部変数を使用するために必要な環境変数を設定:

set_env
export TF_VAR_key_name=key_terraform
export TF_VAR_public_key_path="${HOME}/.ssh/key_terraform.pub"
export TF_VAR_private_key_path="${HOME}/.ssh/key_terraform"

上記の内容は適宜書き換えを行う。また、また、該当するパスに秘密鍵と公開鍵を予め作っておく。上記の例であれば、

ssh-keygen -t rsa -b 4096 -f $HOME/.ssh/key_terraform # 4096bitのRSA, ファイル名と置き場所も指定しておく

のようにすればOK
(terraformを実行するとAWS環境にアップロードされて、自動でキーペアが作成・管理されるようになる)

なお、今回はgit for windowsに付属のbash(msys2)を使っており、linuxと同様のやり方で動くようにしている。
(コマンドプロンプトなどを使う場合は少しやり方を変える必要)

2-2. ec2の起動とrdp接続

2-1. で作ったファイルを置いたディレクトリ上でgit bashを立ち上げ、以下を実行すると起動

# 環境変数の設定(※パスした場合は、対話形式で変数を設定することも可能)
source set_env

# ディレクトリを初期化
terraform init

# awsリソースの起動
terraform apply   # 問題無いか聞かれるので、確認してOKなら`yes`を入力してEnterを押すとスタートする

provisioningには20~30分オーダーで時間がかかる。
無事完了した後は、

terraform show

で立ち上がったリソースの情報を確認出来るので、そこからpublic_idpublic_dnsを調べる(ssh接続に必要。他にはAWSコンソールのEC2ダッシュボード等からも確認出来るのでそれでもOK)

次に立ち上がったEC2へのリモートデスクトップ接続を行う。
今回はセキュリティを考えてEC2はssh用のポート(22)のみを開放しているため、ポートフォワードを行う必要がある。
そこで、git bash上で下記のようにssh接続を行う:

ssh -i ~/.ssh/key_terraform ubuntu@ec2-XX-XX-XX-XX.ap-northeast-1.compute.amazonaws.com -L 13389:localhost:3389
  • -iオプションで使用する秘密鍵を指定している(実際に使っているものに合わせて適宜書き換え)
  • ubuntu@******部分には上記で調べたEC2のIPアドレスかURL(public_idないしpublic_dns部分)を入れる
  • -Lオプションでポートフォワードを行っており、ここではEC2側の3389ポート(リモートデスクトップ用のxrdpで使用)をローカル端末の13389ポートに転送している(ここも使用状況に合わせて適宜書き換え)

ここで、ウィンドウズキーを押してrdpと入力して検索を行うと「リモートデスクトップ接続」を選択出来るので、Enterを押して選択し、「コンピュータ名」にlocalhost:13389を入力して「接続」を押す。

rdp.png

以下の画面が出てきたらusernameにubuntu、passwordにprovision.shで設定したパスワードを入力してOKを押す。

rdp_connect.png

以下のような画面が出てくればOK

rdp_desktop.png

実行にはお金がかかるので、使わないときはAWSコンソールからインスタンスを停止したり、
削除するときは

terraform destroy # 消してOKか聞かれるので、確認してからyesを入力

によって関連するAWSリソースをひとまとめに削除出来る

(参考)日本語環境

上記までだと日本語用の設定が行われていないので、必要に応じてprovisioningの段階で設定を行う

例えば、以下のような内容をprovision.shに追記することで、日本語用パッケージ(IMEなど)のインストールやタイムゾーン・local設定などを行える:

apt install -y \
    language-pack-ja-base language-pack-ja \
    ibus-kkc ibus-mozc

# ubuntu-defaults-ja バージョンに応じて適切なものを選択・インストール
UBUNTU_VERSION=$(. /etc/lsb-release; echo $DISTRIB_RELEASE)
UBUNTU_CODENAME=$(. /etc/lsb-release; echo $DISTRIB_CODENAME)
if [ $UBUNTU_VERSION = "20.10" ]; then
    echo $UBUNTU_CODENAME
    wget https://www.ubuntulinux.jp/ubuntu-jp-ppa-keyring.gpg -P /etc/apt/trusted.gpg.d/
    wget https://www.ubuntulinux.jp/ubuntu-ja-archive-keyring.gpg -P /etc/apt/trusted.gpg.d/
    wget https://www.ubuntulinux.jp/sources.list.d/groovy.list -O /etc/apt/sources.list.d/ubuntu-ja.list
elif [ $UBUNTU_VERSION = "20.04" ]; then
    echo $UBUNTU_CODENAME
    wget -q https://www.ubuntulinux.jp/ubuntu-ja-archive-keyring.gpg -O- | apt-key add -
    wget -q https://www.ubuntulinux.jp/ubuntu-jp-ppa-keyring.gpg -O- | apt-key add -
    wget https://www.ubuntulinux.jp/sources.list.d/focal.list -O /etc/apt/sources.list.d/ubuntu-ja.list
elif [ $UBUNTU_VERSION = "18.04" ]; then
    echo $UBUNTU_CODENAME
    wget -q https://www.ubuntulinux.jp/ubuntu-ja-archive-keyring.gpg -O- | apt-key add -
    wget -q https://www.ubuntulinux.jp/ubuntu-jp-ppa-keyring.gpg -O- | apt-key add -
    wget https://www.ubuntulinux.jp/sources.list.d/bionic.list -O /etc/apt/sources.list.d/ubuntu-ja.list
else
    :
fi
apt-get -y update
apt-get -y upgrade
apt-get -y install ubuntu-defaults-ja

# locale
update-locale LANG=ja_JP.UTF8

# manual, if need
apt-get -y install manpages-ja manpages-ja-dev

# timezone
TIMEZONE="Asia/Tokyo"
echo $TIMEZONE > /etc/timezone
cp /usr/share/zoneinfo/${TIMEZONE} /etc/localtime   # This sets the time

日本語環境構築の参考:

その他の参考リンク

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?