当前位置:   article > 正文

Terraform 通过 Provisioner 配置服务器

Terraform 通过 Provisioner 配置服务器

Provisioner 介绍

虚拟服务器创建完成后,通常需要执行一些初始化的操作。例如:安装软件,配置系统,服务等。

在前面的案例中使用云商的 user_data 用户数据来执行 shell 脚本来安装 nginx 服务器。

Terraform 也提供了 Provisioner 来完成这种场景。通过 Provisioner 可以在基础设施资源创建或销毁时,执行定制化的操作。 Provisioner 可以于 ansible,puppet,saltstack 配置管理工具结合使用,利用现有的配置管理工具管理资源。

Provisioner 使用案例

使用 Provisioner 购买基础设施并搭建一个服务。使用3个文件

mian.tf

  1. /*
  2. 创建 AWS EC2 实例
  3. 运行 Docker 容器
  4. */
  5. # 供应商
  6. provider "aws" { // 云供应商
  7. region = var.region // 地域
  8. }
  9. // 数据源
  10. data "aws_security_groups" "default" { // 数据源为"aws_security_groups",数据源名称"default"
  11. filter {
  12. name = "group-name" // 过滤 group_name = default 的安全组
  13. values = ["default"]
  14. }
  15. }
  16. // 创建 EC2 实例,运行 docker 容器
  17. resource "aws_instance" "ss" {
  18. ami = lookup(var.amis, var.region) # 配置参数,ami的id。
  19. instance_type = var.instance_type # 配置参数,启动的ec2的类型,t2.micro是免费的
  20. key_name = aws_key_pair.ssh.key_name # 引用了 aws_key_pair ssh 中的 key_name。于EC2实例绑定,实现可以ssh的目的。
  21. tags = { # 将EC2 实例命名为 "ss-server"
  22. Name = "ss-server"
  23. }
  24. # 连接远程服务器
  25. connection {
  26. type = "ssh"
  27. user = "ubuntu"
  28. private_key = file("id_rsa")
  29. host = aws_instance.ss.public_ip
  30. }
  31. # 安装 docker 并运行 ss 容器
  32. provisioner "remote-exec" {
  33. inline = [
  34. "sudo apt update",
  35. "sudo apt install -y docker.io",
  36. "sudo docker run -e PASSWORD=${var.ss_password} -p 8388:8388 -p 8388:8388/udp -d shadowsocks/shadowsocks-libev",
  37. ]
  38. }
  39. }
  40. # 添加SSH登陆密钥
  41. resource "aws_key_pair" "ssh" {
  42. key_name = "admin"
  43. public_key = file(var.public_key)
  44. }
  45. // 开放22端口,允许SSH登陆
  46. resource "aws_security_group_rule" "ssh" {
  47. type = "ingress"
  48. from_port = 22
  49. to_port = 22
  50. protocol = "tcp"
  51. cidr_blocks = ["0.0.0.0/0"]
  52. security_group_id = data.aws_security_groups.default.ids[0] // 调用数据源的信息,列表的第一个值
  53. }
  54. // 开放80端口,允许WEB访问
  55. resource "aws_security_group_rule" "web" {
  56. type = "ingress"
  57. from_port = 8388
  58. to_port = 8388
  59. protocol = "all"
  60. cidr_blocks = ["0.0.0.0/0"]
  61. security_group_id = data.aws_security_groups.default.ids[0]
  62. }

variables.tf

  1. # variables.tf
  2. variable "region" { // 变量名 region,不可用重复。花括号里面是参数
  3. type = string // 输入变量的类型
  4. default = "us-west-2" // 变量的默认值
  5. description = "AWS region" // 变量的描述
  6. }
  7. variable "amis" {
  8. type = map
  9. default = {
  10. us-west-2 = "ami-03f65b8614a860c29" // ubuntu ami
  11. }
  12. description = "AWS ID"
  13. }
  14. variable "instance_type" {
  15. type = string
  16. default = "t2.micro"
  17. description = "EC2 instance type"
  18. }
  19. variable "public_key" {
  20. type = string
  21. default = "id_rsa.pub"
  22. description = "SSH public key"
  23. }
  24. variable "ss_password" {
  25. type = string
  26. description = "ss password"
  27. }

outputs.tf

  1. output "IP" {
  2.   value = aws_instance.ss.public_ip
  3.   description = "AWS EC2 public IP"

connection 连接

connection 块告诉 Terraform 用什么方式与远端机器进行通讯。

  1. # 连接远程服务器
  2. connection {
  3.   type = "ssh"                                            # 连接方式
  4.   user = "ec2-user"                                    # 远程服务器的服务名
  5.   private_key = file("id_rsa")            # 配置使用ssh密钥登陆。也可以使用password登陆
  6.   host = aws_instanc.ss.public_ip        # 远端服务器的IP地址
  7. }

provisioner remote-exec 执行命令

登陆到服务器上之后,要关注 Terraform 执行的操作。本案例是在服务器上安装 docker,在docker上运行一个镜像服务。

inline参数支持接受一个命令列表。EC2实例创建完成后,按顺序执行命令列表中的命令。

# 安装 docker 并运行 ss 容器

  1. provisioner "remote-exec" {
  2.   inline = [
  3.   "sudo apt update",
  4.   "sudo apt install -y docker.io",
  5.   "sudo docker run -e PASSWORD=${var.ss_password} -p 8388:8388 -p 8388:8388/udp -d shadowsocks/shadowsocks-libev",
  6.   ]
  7. }

除了inline参数,provisioner还支持 script 和 scripts 参数,后两者支持执行脚本,这三个参数是互斥的只能使用一个参数。

Provisioner 部署
  1. $ cp ~/.ssh/id_rsa* .
  2. $ terraform plan
  3. $ terraform apply
  4. var.ss_password
  5. ss password
  6. Enter a value: Wsj@123456
  7. ...
  8. Do you want to perform these actions?
  9. Terraform will perform the actions described above.
  10. Only 'yes' will be accepted to approve.
  11. Enter a value: yes
  12. ...

提交代码

  1. git add .
  2. git commit -m "using remote-exec"


Provisioner file 上传文件

使用 Provisioner file 完成服务的定制化配置。

新建安装服务的配置文件模板

其中${server} 和 ${password} 是变量,由 terraform apply 的时候渲染。

  1. $ cat ss-config.json
  2. {
  3.     "server": "${server}",
  4.     "server_port": 8388,
  5.     "local_port": 1080,
  6.     "password": "${password}",
  7.     "timeout": 600,
  8.     "method": "chacha20-ietf-poly1305",
  9.     "fast_open": true
  10. }
将配置文件上传到服务器上

新增了 provisioner "file" {} 代码块。可以将文件上传到服务器上。分别定义了文件内容和文件保存路径。

修改了 docker run 命令,运行 docker 的时候将本地路径挂载到 docker 容器里面。

  1. # main.tf
  2. ...
  3. // 创建 EC2 实例,运行 docker 容器
  4. resource "aws_instance" "ss" {
  5. ami = lookup(var.amis, var.region) # 配置参数,ami的id。
  6. instance_type = var.instance_type # 配置参数,启动的ec2的类型,t2.micro是免费的
  7. key_name = aws_key_pair.ssh.key_name # 引用了 aws_key_pair ssh 中的 key_name。于EC2实例绑定,实现可以ssh的目的。
  8. tags = { # 将EC2 实例命名为 "ss-server"
  9. Name = "ss-server"
  10. }
  11. # 连接远程服务器
  12. connection {
  13. type = "ssh"
  14. user = "ubuntu"
  15. private_key = file("id_rsa")
  16. host = aws_instance.ss.public_ip
  17. }
  18. # 上传文件到服务器
  19. provisioner "file" {
  20. content = templatefile("ss-config.json", { server = aws_instance.ss.public_ip, password = var.ss_password }) // 文件内容
  21. destination = "/var/tmp/ss-config.json" // 远端服务器的文件路径
  22. }
  23. # 安装 docker 并运行 ss 容器
  24. provisioner "remote-exec" {
  25. inline = [
  26. "sudo apt update",
  27. "sudo apt install -y docker.io",
  28. "sudo docker run -v /var/tmp:/var/tmp -e ARGS='-c /var/tmp/ss-config.json' -p 8388:8388 -p 8388:8388/udp -d shadowsocks/shadowsocks-libev",
  29. ]
  30. }
  31. }
  32. ...
Provisioner 部署
  1. % terraform apply
  2. var.ss_password
  3.   ss password
  4.   Enter a value: Wsj@123456
查看docker进程
  1. % ssh ubuntu@18.237.89.77 sudo docker ps
  2. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  3. ab71ac7234fd shadowsocks/shadowsocks-libev "/bin/sh -c 'exec ss…" 36 seconds ago Up 34 seconds 0.0.0.0:8388->8388/tcp, 0.0.0.0:8388->8388/udp, :::8388->8388/tcp, :::8388->8388/udp trusting_nobel
提交代码
  1. git add .
  2. git commit -m "using file provisioner"

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/430492
推荐阅读
相关标签
  

闽ICP备14008679号