使用 Terraform 好處是,可以直接把公司內部的基礎建設做好配置或是標準,使得要開始建立雲端資源時,可以確保每次建立出來的服務、VPC、Instance、ClodPlatform 設定檔都一致,這篇文章示範如何使用 Terraform 去佈署 AWS Lightsail ,然後想要在建立 Instance 後, 連進去做某些事。
必備安裝
Terraform 是在【本地電腦】中,去代替你執行各大 Platform 亦或是 Docker 等 Deploy 相關指令,因此,本篇文章要佈署的目的是 AWS Lightsail,所以需要安裝 AWS-CLI ,而且,要完成 AWS-CLI 設定:
aws configure
這個 AWS Access Key ID 跟 AWS Secret Access ,你需要去 AWS Platform 上新增 IAM 並賦予使用者操作 Lightsail 權限,才可以使用下去。
用 Terraform 腳本
Terraform 腳本寫好後,依序是【先安裝必要的 Model】、再做資料驗證、最後再佈署上去,到著從目的看,其實不同的雲端,就代表是不同的 provider,以下是 main.tf 檔案寫法:
terraform { required_providers { #定義提供者 aws = { source = "hashicorp/aws" #引用該 model version = "~> 2.70" } } } provider "aws" { #定義服務提供者 region = "ap-northeast-1" #定義要用哪個 region } # Create a new Lightsail Instance #resource "服務提供者的服務名稱" "自訂執行區塊名稱" resource "aws_lightsail_instance" "app" { name = "HELLO.MYAPP" #[NAME].[DOMAIN] availability_zone = "ap-northeast-1a" #instance 開啟的區域 (東京 1a) blueprint_id = "centos_7_1901_01" #instance 開啟的 OS 或服務 (E.g: wordpress) bundle_id = "nano_2_0" #instance 放案類型 }
關於上面的設定,我該填上什麼值,請參考 Terraform - lightsail_instance
Terraform 執行指令
執行指令,依序步驟是:
- terraform init (初始化,安裝必要的 model)
- terraform fmt (格式化)
- terraform validate (驗證你寫的東西有沒有問題)
- terraform apply (真實的佈署到你的 aws)
- terraform destroy (毀滅你剛才佈署到 aws 的東西)
用 Terraform 打開機器後,在裡面傳檔案執行指令
雖然是開了機器,但我想要把 shell 檔案傳上去,預先安裝甚麼東西的話,可以怎麼做?
首先,必備項目是,去 Lightsail 取得你的連線專用 pem key (以下腳本中,用的是我下載的檔案: LightsailDefaultKey-ap-northeast-1.pem) ,下載後跟 main.tf 放在一起 (注意最好不要放到甚麼公開資料夾,這可是你的 private key)。
然後,目的是希望產生 instance 後,可以自動執行某檔案的指令,所以,希望等等可以執行 setup.sh 這個檔案,首先,先寫好 main.tf:
terraform { #定義 init required_providers { aws = { source = "hashicorp/aws" version = "~> 2.70" } } } provider "aws" { region = "ap-northeast-1" } #綁住 instance_name 跟 static_ip 的關係,也就是,當下面那個 resource (aws_lightsail_static_ip) 產生之後, #要求跟指定的 instance_name 綁定,這樣靜態 IP 就會綁在該 instance。 resource "aws_lightsail_static_ip_attachment" "app" { static_ip_name = aws_lightsail_static_ip.app.name instance_name = aws_lightsail_instance.app.name } #取得 lightsail 一產生 instance 後的靜態 IP 位置,用於等一下要連進去 #也用於等一下要綁定 IP 到 instance resource "aws_lightsail_static_ip" "app" { name = "HELLO" #name } # Create a new Lightsail Instance resource "aws_lightsail_instance" "app" { name = "HEELLO.MYAPP" #name.domain availability_zone = "ap-northeast-1a" blueprint_id = "centos_7_1901_01" bundle_id = "nano_2_0" } # 定義無服務提供者,是自己 resource "null_resource" "app" { triggers = { #該服務觸發器,是等到 static_ip 取得後。 public_ip = aws_lightsail_static_ip.app.ip_address } # 開啟連線事件,要準備連上 lightsail 的 instance connection { type = "ssh" host = aws_lightsail_static_ip.app.ip_address user = "centos" #這 aws 有寫你欲設的 user 會是啥名字, 開 ubuntu 就叫 ubuntu private_key = "${file("./LightsailDefaultKey-ap-northeast-1.pem")}" timeout = "2m" } # 要複製過去的檔案 // copy our example script to the server provisioner "file" { source = "setup.sh" destination = "/tmp/setup.sh" } # 要在遠端執行的命令 // change permissions to executable and pipe its output into a new file provisioner "remote-exec" { inline = [ "chmod +x /tmp/setup.sh", "/tmp/setup.sh > /tmp/setup.log", ] } }
再來,要處理 setup.sh 這個檔案,我們希望他可以預設幫我們先安裝好 Node.js 12.x 跟先建立好資料庫:
#! /bin/bash # 注意檔案 CR 問題,會導致 file format 不是 unix # init script: # init sql sudo yum -y update sudo yum -y install mariadb-server sudo systemctl enable mariadb sudo systemctl start mariadb systemctl status mariadb # 安裝 mysql https://gist.github.com/vdvm/24754bf1aee6fd85e1aa echo "正在安裝 mysql_secure_installition, 密碼: [PASSWORD] (請自行覆蓋)" echo -e "\n\n[PASSWORD]\n[PASSWORD]\n\n\nn\n\n " | mysql_secure_installation 2>/dev/null
# 安裝 SQL 資料庫 echo "正在建立資料庫: [db_name]" mysql -u root -p'[PASSWORD]' -h localhost -P 3306 -e "CREATE DATABASE [db_name];"
# 安裝 SQL 表 echo "== 請自行手動安裝 SQL 表。" # init port echo "開啟防火牆 80 port" sudo yum install -y firewalld sudo firewall-cmd --zone=public --add-port=80/tcp --permanent sudo firewall-cmd --zone=public --add-port=22/tcp --permanent sudo firewall-cmd --reload # node.js install sudo yum install -y gcc-c++ make echo "如果 nodesource 找不到東西,可以嘗試改北清大 mirror" curl -sL https://rpm.nodesource.com/setup_12.x | sudo bash - sudo yum install -y nodejs sudo npm config set registry http://registry.npmjs.org/ sudo npm config set strict-ssl false # deploy script sudo npm install pm2 -g # CI/CD KEY (/tmp/sshkey.pub) ssh-keygen -b 2048 -t rsa -f /tmp/sshkey -q -N ""
注意,上述腳本註解有提到 Sehll CR 轉換問題,如果你這個 setup.sh 是在 windows 上寫的,很可能會在 Linux 上無法被執行腳本,是因為檔案的斷行模式問題,如果是在 windows 寫的用戶,最好是在 WSL 中,用 vim 打開這個檔案,然後使用轉換指令:
- :set fileformat=unix
- :wq!
完成後,直接執行 terraform apply,需要等待一陣子,就可以看到 Instance 自動被建立,直接進去也裝好 Node.js 了。
Reference:
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lightsail_instance
https://www.terraform.io/
https://stackoverflow.com/questions/2920416/configure-bin-shm-bad-interpreter
https://medium.com/@chihsuan/terraform-%E8%87%AA%E5%8B%95%E5%8C%96%E7%9A%84%E5%9F%BA%E7%A4%8E%E6%9E%B6%E6%A7%8B%E4%BB%8B%E7%B4%B9-f827e8975e98
沒有留言:
張貼留言