Terraform 系列二 在AWS上创建EC2并自动挂载磁盘

Terraform 系列二 在AWS上创建EC2并自动挂载磁盘

image-20241112170226186

需求说明

在AWS上创建一台EC2,添加数据盘并自动挂载到/opt/ 目录

创建资源

新建 variables.tf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
variable "ec2_ami" {
type = string
default = "ami-00f07845aed8c0ee7" #Amazon Linux 2023 AMI 2023.5.20240819.0 x86_64 HVM kernel-6.1 不同region ami id不同,请参考当各个region
description = "ec2_ami"
}

#EC2 系统盘
variable "ec2_root_disk_size" {
type = number
default = 50
description = "ec2_root_disk_size"
}
#EC2 数据盘
variable "ec2_disk_size" {
type = number
default = 200
description = "ec2_disk_size"
}

创建ssh-key

1
ssh-keygen

新建ec2.tf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# 前置VPC等参考系列一
# 创建 EC2 密钥对
resource "aws_key_pair" "ec2_key" {
key_name = "ec2_key"
public_key = "xxxx" 上面创建的ssh-key id_rsa
}
# 创建EC2 SSM IAM_ROLE
resource "aws_iam_role" "iam_ssm_role" {
name = "ssm_role"
assume_role_policy = jsonencode({
Version = "2012-10-17",
Statement = [
{
Effect = "Allow",
Principal = {
Service = "ec2.amazonaws.com"
},
Action = "sts:AssumeRole"
}
]
})
}

# SSM_POLICY绑定EC2 SSM_IAM
resource "aws_iam_role_policy_attachment" "iam_ssm_role_policy" {
role = aws_iam_role.iam_ssm_role.name
policy_arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
}
# 创建 EC2_Profile
resource "aws_iam_instance_profile" "ec2_ssm_profile" {
name = "ec2_ssm_profile"
role = aws_iam_role.iam_ssm_role.name
}

# 创建 EC2 实例
resource "aws_instance" "ec2" {
count = 3
ami = var.ec2_ami # 根据需要更改 AMI ID
instance_type = var.ec2_instance_type
key_name = aws_key_pair.ec2_key.key_name
subnet_id = element(
[
aws_subnet.vpc_subnet_private1.id,
aws_subnet.vpc_subnet_private2.id
],
count.index % 2
)
iam_instance_profile = aws_iam_instance_profile.ec2_ssm_profile.name #绑定iam
vpc_security_group_ids = [aws_security_group.security_group.id]

root_block_device {
volume_size = var.ec2_root_disk_size
volume_type = "gp3"
}

# 挂载数据盘
ebs_block_device {
device_name = "/dev/xvdb"
volume_size = var.ec2_disk_size
volume_type = "gp3"
}

user_data = file("auto_disk.sh")

tags = {
Name = "ec2"
}
}

创建security_group.tf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 创建DB安全组
resource "aws_security_group" "security_group" {
name = "security_group"
description = "security_group"
vpc_id = aws_vpc.vpc.id
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"] # 根据需要调整允许的IP范围
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}

tags = {
Name = "security_group"
}
}

创建auto_disk.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#!/bin/bash

# 找到未挂载且没有分区的磁盘
DISK_NAME=$(lsblk -ndo NAME,TYPE | grep disk | awk '{print $1}' | while read DISK; do
if ! lsblk /dev/$DISK | grep -q part; then
echo "/dev/$DISK"
fi
done | head -n 1)

# 如果没有找到磁盘,退出
if [ -z "$DISK_NAME" ]; then
echo "未找到未分区的磁盘。"
exit 1
fi

echo "找到未分区的磁盘: $DISK_NAME"

# 创建新的分区
echo "正在创建新的分区..."
parted $DISK_NAME --script mklabel gpt
parted $DISK_NAME --script mkpart primary 0% 100%
partprobe $DISK_NAME

# 获取新创建的分区名
PARTITION_NAME=$(ls ${DISK_NAME}* | grep -E "${DISK_NAME}p?[0-9]$" | head -n 1)

# 格式化分区为 xfs 文件系统
echo "正在格式化分区为 xfs 文件系统..."
mkfs.xfs $PARTITION_NAME
echo "格式化完成。"

# 创建挂载点并挂载到 /opt
if [ ! -d /opt ]; then
mkdir /opt
fi

echo "挂载分区到 /opt..."
mount $PARTITION_NAME /opt

# 设置开机自动挂载,编辑 /etc/fstab
UUID=$(blkid -s UUID -o value $PARTITION_NAME)
echo "UUID=${UUID} /opt xfs defaults,nofail 0 2" >> /etc/fstab

echo "挂载完成并设置自动挂载。"

运行

1
2
3
4
5
terraform init
# 查看预期变更
terraform plan
# 生效变更
terraform apply

Terraform 系列二 在AWS上创建EC2并自动挂载磁盘
https://www.starsfox.com/posts/4cc59e32.html
作者
Flycat
发布于
2024年11月11日
许可协议