前言
最近想認真學 CI / CD 相關技術,所以想先從 GitHub action 和 terraform 開始,而按照開發流程來說,先建立一台開發 / 實驗用的 Server 一定是 Hello world 一般的開始了,這篇文章會按照 terraform 建立一台開發用的 EC2 server。
https://developer.hashicorp.com/terraform/tutorials/aws-get-started
步驟
在這次的步驟中我假設你已經有了 AWS 的基礎知識,並且安裝好了 terraform,我們就可以按照以下幾個步驟進行實作。
- Terraform 步驟
- main.tf 內容解釋
- 建立 Server
- 實際連線測試
Terraform 步驟
一個基本的 Terraform 使用流程,會有以下幾個步驟。
- init
- 安裝各種插件,像是 Provider(註1)。
- validate
- 事先驗證語法是否正確,但不保證 runtime 不會有 error。
- plan
- 檢視即將建立怎麼樣的資源。
- apply
- 實際在該服務上建立資源。
- show
- 觀察已建立的資源的資訊,以 EC2 為例,我們就可以看到我們建立的 Instance 的 IP, Image 及區域等等資訊。
- change
- 更改已建立的資源的內容。
- destroy
- 將建立起的資源刪除掉。
註1: Terraform 中用來與對應的服務(像 AWS)溝通的插件
main.tf 內容
以下是我們的 main.tf 內容,也就是描述我們資源內容的 terraform 檔案,為了可讀性,以下提供兩個版本,一個有附上註解一個沒有,方便讀者比對。
# 無註解版
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.16"
}
}
required_version = ">= 1.2.0"
}
provider "aws" {
region = "ap-northeast-3"
}
resource "aws_instance" "dev_server" {
ami = "ami-0f33119c704c2aa59"
instance_type = "t2.micro"
tags = {
Name = "MyDevServerInstance"
}
}
# 有註解版
# terraform block 中是 Terraform 的設定內容,
# 像是 provider 以及版本選擇都在這個區塊進行設定
terraform {
# 設定我們這個檔案需要哪些 provider
# 並且設定 provider 的來源以及其版本
# hashicorp/aws => registry.terraform.io/hashicorp/aws
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.16"
}
}
# 定義這個檔案需要跑在 terraform 的版本上
required_version = ">= 1.2.0"
}
# provider 的初始設定
# 以 aws 為例就需要設定其 region, access key id, secret access key 等
# 但由於後兩個資料有機密性,所以放在 local 端,讓 aws cli 自行讀取
# 以防誤傳上 github 等外部程式庫
provider "aws" {
# osaka
region = "ap-northeast-3"
}
# 定義資源內容
# 格式:
# resource <resource type> <resource_name>
resource "aws_instance" "dev_server" {
# 請注意在不同的 region 的同一個 AMI 會有不同的 ID
# 所以請記得對應 region 填入對應的 AMI ID
ami = "ami-0f33119c704c2aa59"
instance_type = "t2.micro"
tags = {
Name = "MyDevServerInstance"
}
}
所以透過以上的程式碼,我們就可以得到一個建立在 ap-northeast-3(Osaka),以 t2.micro 規格運行 Amazon Linux 2 AMI 的 EC2 Instance 了。
建立 Server
透過以下指令,我們可以建立對應的資源了,輸入之後他會要求你輸入 yes 進行確認,記得輸入後就可以順利建立伺服器。
terraform apply
看到以下這行就是創建成功了
Apply complete! Resources: 1 added, 0 changed, 0 destroyed
實際連線測試
透過以下指令可以看到資源的詳細資訊,於是我們就使用該 IP 進行 ssh 連線。
terraform show
# aws_instance.dev_server:
resource "aws_instance" "dev_server" {
ami = "ami-0f33119c704c2aa59"
...
public_dns = "ec2-13-208-xxx-xxx.ap-northeast-3.compute.amazonaws.com"
public_ip = "13.208.xxx.xxx"
secondary_private_ips = []
security_groups = [
"default",
]
...
}
但是我們這裡遇到兩個問題,沒辦法連上 server
- 由於沒指定 security_groups,沒有開放 server 的 22 port
- 直接透過 ssh 連上 EC2 instance 需要 key pair。
於是我們透過更改 main.tf 的內容,新增 subnet_id 和 vpc_security_group_ids 以加入我有開放 22 port 的 security group 和對應的 subnet,並且加上新的 key pair 資源,這樣我們才能連上 server。
# 無註解版
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.16"
}
}
required_version = ">= 1.2.0"
}
provider "aws" {
region = "ap-northeast-3"
}
resource "aws_key_pair" "dev_server_key" {
key_name = "dev-server-key"
public_key = file("~/.ssh/id_rsa.pub")
}
resource "aws_instance" "dev_server" {
ami = "ami-0f33119c704c2aa59"
instance_type = "t2.micro"
key_name = aws_key_pair.dev_server_key.key_name
subnet_id = "subnet-xxxxxxxx"
vpc_security_group_ids = ["sg-xxxxxxxx"]
tags = {
Name = "MyDevServerInstance"
}
}
再次執行 apply 以更新我們的 server,就可以更新我們的伺服器資源,另外我們也可以再次執行 show 就可以看到我們的 IP 更新了,代表這個操作是直接刪除並重新建立 server。
ssh ec2-user@xxx.xxx.xxx.xxx
, #_
~\_ ####_ Amazon Linux 2023
~~ \_#####\
~~ \###|
~~ \#/ ___ https://aws.amazon.com/linux/amazon-linux-2023
~~ V~' '->
~~~ /
~~._. _/
_/ _/
_/m/'
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$
最後要記得下 destroy 指令來關掉機器,不然在沒有 free-tier 的狀況下,一直開著就是一直在噴錢呢。
結語
跟著官方教學進行機器的建置,基本上不會有什麼問題,最大的問題就是我想連上去當開發機使用,畢竟 terraform 應該是為了快速部署所建立的服務。
但是透過這篇文章把遇到的幾個問題解決之後,也更清楚 AWS 建立 EC2 Instance的流程了,也是另外的收穫~