Build mate desktop environment on ec2 with terraform (Ubuntu 20.04LTS)

1. Execution environment

As a prerequisite, run aws configure in advance so that you can access your own aws environment with the aws command.

Also, this time terraform and awscli are installed by scoop.

scoop install aws terraform

For example, installing scoop https://scoop.sh/ (Official) https://qiita.com/Dooteeen/items/12dc8fb14042888113d0 See etc.

2. Run

2-1. Creating required files

Create and place the following files in an appropriate directory

file organization


$ tree
.
├── main.tf       #terraform file
├── provision.sh  #Script for provisioning
└── set_env       #Environment variable setting, not required but for convenience

Details of each file:

2-1-1. main.tf

main.tf


#Information that changes depending on the execution environment and information that you want to keep secret can be made into variables
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 reference links for creating main.tf:

--Using the AMI image of Ubuntu 20.04

Information related to private key and public key is declared as an external variable, and it is passed to the terraform side by setting the environment variable TF_VAR_**. (Read later with source set_env) Also, ubuntu provisioning is set to another script file called provision.sh, which is uploaded and executed locally to the EC2 side.

(Compared to creating EC2 normally from the AWS Web console, it was more troublesome than I expected because I had to write each one at first.)

** Note that the instance type is not covered by the free tier because the t3a.small type is specified for building a desktop environment. (T3a.small doesn't have a deep meaning, but 1GB of memory of t2.micro doesn't have enough specs) **

2-1-2. provision.sh

provision.sh


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

#You have to wait for the setup on the cloud side to complete apt-get etc. fail
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)"

Rough setup of 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/ Refer to, and enable remote desktop with xrdp.

Especially the point that got stuck is

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

Part of. Apparently, it is not "timing when provisioning starts = cloud side environment is ready", and if this part is not included, the repository information will not be updated with apt-get update, and as a result, an error will occur with apt-get install. It will happen. (Reference: https://stackoverflow.com/questions/42279763/why-does-terraform-apt-get-fail-intermittently)

Note that the login user is set to ubuntu, which is prepared by default, and the login password is hard coded with change it for the time being.

2-1-3. set_env

Set the environment variables required to use external variables in the terraform file mentioned above:

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"

The above contents will be rewritten as appropriate. In addition, a private key and a public key are created in advance in the corresponding path. In the above example,

ssh-keygen -t rsa -b 4096 -f $HOME/.ssh/key_terraform #4096bit RSA,Specify the file name and location

OK if you do like (When you execute terraform, it will be uploaded to the AWS environment and key pairs will be created and managed automatically)

This time, I'm using bash (msys2) that comes with git for windows, and it works in the same way as linux. (If you use command prompt etc., you need to change the method a little)

2-2. Start ec2 and connect rdp

Start git bash on the directory where the file created by 2-1. is placed, and execute the following to start it.

#Setting environment variables(* If you pass, you can set variables interactively.)
source set_env

#Initialize directory
terraform init

#Start aws resource
terraform apply   #You will be asked if there is any problem, so check it and if it is OK`yes`Type and press Enter to start

Provisioning takes 20 to 30 minutes on the order. After successfully completing

terraform show

You can check the information of the resource launched in, so check public_id or public_dns from there (necessary for ssh connection. You can also check it from the EC2 dashboard of the AWS console, so it's OK)

Next, make a remote desktop connection to the launched EC2. This time, considering security, EC2 only opens the port (22) for ssh, so it is necessary to perform port forwarding. So, make an ssh connection on git bash as below:

ssh -i ~/.ssh/key_terraform [email protected] -L 13389:localhost:3389

--Specify the private key to be used with the -i option (rewrite as appropriate according to the one actually used) --In the *** part of ubuntu @ ***, enter the IP address or URL (public_id or public_dns part) of EC2 found above. --Port forwarding is performed with the -L option, and here the 3389 port on the EC2 side (used by xrdp for remote desktop) is forwarded to the 13389 port of the local terminal (also according to the usage situation). Rewrite as appropriate)

Here, if you press the Windows key and enter rdp to search, you can select" Remote Desktop Connection ", so press Enter to select it, enter localhost: 13389 in "Computer Name", and then "Connect". "push.

rdp.png

When the following screen appears, enter the password set in ubuntu for username and provision.sh for password and press OK.

rdp_connect.png

OK if the following screen appears

rdp_desktop.png

It costs money to run, so when you're not using it, you can stop the instance from the AWS console or When deleting

terraform destroy #You will be asked if it is OK to erase it, so enter yes after confirming

Allows you to delete related AWS resources at once

(Reference) Japanese environment

Since the settings for Japanese have not been made up to the above, set at the provisioning stage if necessary.

For example, by adding the following contents to provision.sh, you can install Japanese packages (IME, etc.) and set the time zone and local settings:

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

# ubuntu-defaults-ja Select and install the appropriate one according to the version
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

Reference for building a Japanese environment:

Other reference links

Recommended Posts

Build mate desktop environment on ec2 with terraform (Ubuntu 20.04LTS)
Build a XAMPP environment on Ubuntu
Build OpenCV with Java Wrapper on Ubuntu 18.04
Build an environment with Docker on AWS
Build a development environment on AWS EC2 with CentOS7 + Nginx + pm2 + Nuxt.js
[Java] Build Java development environment on Ubuntu & check execution
Build mecab (NEologd dictionary) environment with Docker (ubuntu)
How to build a Pytorch environment on Ubuntu
Apache2 on Ubuntu20.04 LTS
Build Zabbix on Ubuntu 20.04
Memo to build a Servlet environment on AWS EC2
Build Java development environment with VS Code on Mac
Setting up the FreeBSD desktop environment on Ubuntu + qemu
[Note] Build a Python3 environment with Docker in EC2
Install Ubuntu MATE 20.04 LTS on older MacBook Early 2008 (MB402 * / A, MB403 * / A, MB404 * / A)
Building WebGIS on Ubuntu20.04 LTS
Build VNC Server on Ubuntu 20.04
Japanese input on Ubuntu20.04 Desktop
Record video on ubuntu18.04 LTS
Installing OpenMX on Ubuntu 18.04.5 LTS
Install Ubuntu Desktop 20.10 on RaspberryPi4
Ubuntu on Windows build speed
Install raspi-config on Ubuntu 20.04 (LTS)
Build docker environment with WSL
Build a CentOS 8 virtual environment on your Mac with VirtualBox
Install WordPress 5.5 on Ubuntu 20.04 LTS
Build Ubuntu 18.04.5 with dual boot
Laravel environment construction (Ubuntu 18.04 LTS)
Build Go development environment with WSL2 + Docker Desktop + VSCode (Remote --Containers)
Create a development environment for Ruby 3.0.0 and Rails 6.1.0 on Ubuntu 20.04.1 LTS
Steps to build a Ruby on Rails development environment with Vagrant
Build a Node.js environment with Docker
Build a Tomcat 8.5 environment with Pleiades 4.8
Let's create Ubuntu environment with vmware
Build PlantUML environment with VSCode + Docker
Build the latest Samba 4 on Ubuntu 20.04
Build environment with vue.js + rails + docker
Build Rails environment with Docker Compose
Wake on Lan settings on Ubuntu 20.04.1 LTS
Build jooby development environment with Eclipse
How to build vim on Ubuntu 20.04
Build ffmpeg 4.3.1 on Ubuntu for Windows
Install ruby on Ubuntu 20.04 with rbenv
Build Unity development environment on docker
Build docker + laravel environment with laradock
Build debug environment on container --Build local development environment for Rails tutorial with Docker-
Minimal steps to set up a Ruby environment with rbenv on Ubuntu 20.04
How to build a Ruby on Rails development environment with Docker (Rails 6.x)
How to build a Ruby on Rails development environment with Docker (Rails 5.x)
Template: Build a Ruby / Rails development environment with a Docker container (Ubuntu version)
When building rails6 environment on Ubuntu, it gets stuck with bundle install
Connect to Amazon EC2 with SSH (Ubuntu)
Building a Deep Learning environment (Ubuntu 20.04 LTS)
EFS mount on AWS Ubuntu EC2 (amazon-efs-utils)
Fixed GitEye not booting on Ubuntu MATE 18.04
Build a PureScript development environment with Docker
Build and manage RStudio environment with Docker-compose
Use docker in proxy environment on ubuntu 20.04.1
Environment construction with Docker (Ubuntu20.04) + Laravel + nginx
DNS over HTTPS with Cloudflared on Ubuntu
[Ruby] Building a Ruby development environment on Ubuntu