完整範例: https://github.com/nyogjtrc/practice-terraform/tree/master/web-packer-terraform
首先準備腳本 script.sh
放入要執行的工作,今天只要安裝 nginx 而已。
如果腳本有問題的話,不用擔心 Packer 突然中斷工作。它會關閉正在使用的資源再停止,不會留下半成品。
#!/bin/bash
lsb_release -a
sudo apt-get install -y nginx
接著準備 web.json
在 provisioners
區塊裡,我們做了以下幾件事
file
佈建器上傳 html 檔shell
佈建器執行腳本安裝 nginxshell
佈建器執行指令複製檔案{
"variables": {
"aws_access_key": "{{env `AWS_ACCESS_KEY_ID`}}",
"aws_secret_key": "{{env `AWS_SECRET_ACCESS_KEY`}}",
"region": "ap-northeast-1"
},
"builders": [
{
"type": "amazon-ebs",
"access_key": "{{user `aws_access_key`}}",
"secret_key": "{{user `aws_secret_key`}}",
"region": "{{user `region`}}",
"ami_name": "packer-ubuntu-web-{{timestamp}}",
"source_ami_filter": {
"filters": {
"virtualization-type": "hvm",
"name": "ubuntu/images/*ubuntu-focal-20.04-amd64-server-*",
"root-device-type": "ebs"
},
"owners": ["099720109477"],
"most_recent": true
},
"instance_type": "t2.micro",
"ssh_username": "ubuntu"
}
],
"provisioners": [
{
"type": "file",
"source": "./index.html",
"destination": "/home/ubuntu/"
},
{
"type": "shell",
"script": "script.sh"
},
{
"type": "shell",
"inline": [
"sudo cp /home/ubuntu/index.html /var/www/html/index.html"
]
}
]
}
$ packer build web.json
amazon-ebs: output will be in this color.
==> amazon-ebs: Prevalidating any provided VPC information
==> amazon-ebs: Prevalidating AMI Name: packer-ubuntu-web-1600356640
amazon-ebs: Found Image ID: ami-09b86f9709b3c33d4
==> amazon-ebs: Creating temporary keypair: packer_5f638121-50f9-a89a-36ce-e5958d9007cf
==> amazon-ebs: Creating temporary security group for this instance: packer_5f638123-2388-0772-a51a-b01f4c2ca2cc
==> amazon-ebs: Authorizing access to port 22 from [0.0.0.0/0] in the temporary security groups...
==> amazon-ebs: Launching a source AWS instance...
==> amazon-ebs: Adding tags to source instance
amazon-ebs: Adding tag: "Name": "Packer Builder"
amazon-ebs: Instance ID: i-09a2c6675e3fe9e7f
==> amazon-ebs: Waiting for instance (i-09a2c6675e3fe9e7f) to become ready...
==> amazon-ebs: Using ssh communicator to connect: 52.194.251.155
==> amazon-ebs: Waiting for SSH to become available...
==> amazon-ebs: Connected to SSH!
==> amazon-ebs: Uploading ./index.html => /home/ubuntu/
amazon-ebs: index.html 290 B / 290 B [===========================================================================================] 100.00% 0s
==> amazon-ebs: Provisioning with shell script: script.sh
amazon-ebs: Distributor ID: Ubuntu
==> amazon-ebs: No LSB modules are available.
amazon-ebs: Description: Ubuntu 20.04.1 LTS
amazon-ebs: Release: 20.04
amazon-ebs: Codename: focal
amazon-ebs: Reading package lists...
amazon-ebs: Building dependency tree...
amazon-ebs: Reading state information...
amazon-ebs: The following additional packages will be installed:
...
==> amazon-ebs: Provisioning with shell script: /var/folders/qc/26b601512_lcvbbb8qg8vrfm0000gp/T/packer-shell382611512
==> amazon-ebs: Stopping the source instance...
amazon-ebs: Stopping instance
==> amazon-ebs: Waiting for the instance to stop...
==> amazon-ebs: Creating AMI packer-ubuntu-web-1600356640 from instance i-09a2c6675e3fe9e7f
amazon-ebs: AMI: ami-03b20ac44de8dc56a
==> amazon-ebs: Waiting for AMI to become ready...
==> amazon-ebs: Terminating the source AWS instance...
==> amazon-ebs: Cleaning up any extra volumes...
==> amazon-ebs: No volumes to clean up, skipping
==> amazon-ebs: Deleting temporary security group...
==> amazon-ebs: Deleting temporary keypair...
Build 'amazon-ebs' finished after 2 minutes 52 seconds.
==> Wait completed after 2 minutes 52 seconds
==> Builds finished. The artifacts of successful builds are:
--> amazon-ebs: AMIs were created:
ap-northeast-1: ami-03b20ac44de8dc56a
成功的話,會看到 ami id
準備檔案 main.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "3.5.0"
}
}
}
provider "aws" {
profile = "default"
region = "ap-northeast-1"
}
resource "aws_vpc" "this" {
cidr_block = "10.0.0.0/16"
}
resource "aws_internet_gateway" "this" {
vpc_id = aws_vpc.this.id
}
resource "aws_route" "internet_access" {
route_table_id = aws_vpc.this.main_route_table_id
destination_cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.this.id
}
resource "aws_subnet" "this" {
vpc_id = aws_vpc.this.id
cidr_block = "10.0.1.0/24"
map_public_ip_on_launch = true
}
resource "aws_security_group" "ssh" {
name = "ssh"
description = "sg for ssh incoming"
vpc_id = aws_vpc.this.id
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = [format("%s/32", var.my_ip)]
}
}
resource "aws_security_group" "web" {
name = "web"
description = "sg for web incoming"
vpc_id = aws_vpc.this.id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
# outbound internet access
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_key_pair" "practice" {
key_name = "practice"
public_key = file(var.public_key_path)
}
data "aws_ami" "web" {
filter {
name = "state"
values = ["available"]
}
owners = ["self"]
filter {
name = "name"
values = ["packer-ubuntu-web-*"]
}
most_recent = true
}
resource "aws_instance" "web" {
ami = data.aws_ami.web.id
instance_type = "t2.micro"
key_name = aws_key_pair.practice.id
vpc_security_group_ids = [
aws_security_group.ssh.id,
aws_security_group.web.id,
]
subnet_id = aws_subnet.this.id
tags = {
Name = "web-packer-terraform"
topic = "web-packer"
}
}
這次多使用了一個 data
區塊 aws_ami
。
用 aws_ami
來搜尋剛剛建立的映像檔
執行 terraform apply
$ terraform apply
Apply complete! Resources: 8 added, 0 changed, 0 destroyed.
Outputs:
vpc_id = vpc-020b696d702910188
web_instance_id = i-0585626b7f287e116
web_public_ip = 18.183.103.41
成功之後會看到建立的 instance id
跟服務的 IP
。
在瀏覽器開啟 http://18.183.103.41/ ,可以看到我們放進去的首頁文字。
This service install via Packer and Terraform