【问题标题】:How to run scritps after create ec2 using terraform during apply?如何在应用期间使用 terraform 创建 ec2 后运行脚本?
【发布时间】:2021-01-06 17:43:23
【问题描述】:

在 terraform 中有一个在 aws 中创建 EC2 机器的示例。

# Create a new instance of the latest Ubuntu 20.04 on an
# t3.micro node with an AWS Tag naming it "HelloWorld"
provider "aws" {
  region = "us-west-2"
}

data "aws_ami" "ubuntu" {
  most_recent = true

  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
  }

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }

  owners = ["099720109477"] # Canonical
}

resource "aws_instance" "web" {
  ami           = data.aws_ami.ubuntu.id
  instance_type = "t3.micro"

  tags = {
    Name = "HelloWorld"
  }
}

但是我也可以在里面运行一些脚本吗?像安装詹金斯?安装 docker,还是在 terraform apply 操作期间运行命令:sudo yum update -y

如果是这样,我会非常适合类似的例子或指导资源。

【问题讨论】:

    标签: amazon-web-services terraform terraform-provider-aws


    【解决方案1】:

    是的,你可以。在 AWS 中,您使用 UserData 来表示:

    可用于执行常见的自动化配置任务,甚至在实例启动后运行脚本。

    在terraform中,对应的属性是user_data

    要使用它安装 Jenkins,您可以尝试以下操作:

    resource "aws_instance" "web" {
      ami           = data.aws_ami.ubuntu.id
      instance_type = "t3.micro"
    
      user_data = <<-EOL
      #!/bin/bash -xe
    
      apt update
      apt install openjdk-8-jdk --yes
      wget -q -O - https://pkg.jenkins.io/debian/jenkins.io.key | sudo apt-key add -
      echo "deb https://pkg.jenkins.io/debian binary/" >> /etc/apt/sources.list
      apt update
      apt install -y jenkins
      systemctl status jenkins
      find /usr/lib/jvm/java-1.8* | head -n 3  
      EOL
    
      tags = {
        Name = "HelloWorld"
      }
    }
    

    请注意,上面的代码是示例,我不能保证它可以在 Ubuntu 20.04 上运行。但它适用于 18.04。 Jenksis 也在端口 8080 上工作,因此如果您想直接访问 jenkins,您的安全组需要允许它,例如没有 ssh 隧道。

    【讨论】:

      【解决方案2】:

      还有 Provisioners 的选项,但是 Terraform 上面有注释

      /// 来自 TF 文档 /// 注意:供应商只能作为最后的手段。对于最常见的情况,有更好的选择。有关更多信息,请参阅主供应商页面。 ///

      在您决定之前请查看这些链接: https://www.terraform.io/docs/provisioners/index.html https://www.terraform.io/docs/provisioners/remote-exec.html

      我还是发布了一个简单的例子。

      resource "aws_instance" "WebServer"  {
        ami           = "ami-SomeValid_AMI_ID"
        instance_type = "t2.micro"
        key_name = "SomeValid_keypair"
         
          provisioner "remote-exec" {
          
          inline = [
          "sudo amazon-linux-extras install -y nginx1.12",
          "sudo systemctl start nginx"
          ]
          
          connection {
          type = "ssh"
          user = "ec2-user"
          private_key = file("F:\\PathToMyKeysFolder\\SomeValid_keypair.pem")
          host = self.public_ip
          
          }
          
          }
      

      【讨论】:

        【解决方案3】:

        注意:

        如果现有实例处于停止状态,AWS 允许我们直接在控制台中更新“用户数据”。人们会期望 Terraform 也以相同的方式运行,您将在 Terraform 脚本中更新您的“user_data”部分,并且在下一次应用期间,如果服务器处于停止状态,它会在 AWS 中更新。但是没有。

        如果您通过 terraform 更新现有 EC2 实例中的 user_data,该实例将被重新创建 --> 销毁并添加。无论如何,“Terraform Plan”都会显示这一点(我不确定它背后的逻辑是什么,但它似乎是今天的样子,所以要小心它)。

            # aws_instance.my-instance **must be replaced**\
        .....
        .....
            Plan: **1 to add**, 0 to change, **1 to destroy**.
        

        如果您在 AWS 控制台中手动进行更改,也会出现同样的问题 - terraform 将获取更改并告诉它必须重新创建服务器。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-02-14
          • 2020-07-19
          • 1970-01-01
          • 2021-09-12
          • 2021-09-17
          • 1970-01-01
          • 2021-08-30
          • 2020-08-26
          相关资源
          最近更新 更多