如何使用基于 puppet 的引导在 EC2 实例中设置主机名

How to set hostname in EC2 instance with puppet based bootstrapping

我正在尝试使用 EC2 实例在 AWS 中构建一个 puppet 管理的基础设施(非企业)。使用 puppetlabs-aws 模块,我可以通过方便的方式创建机器。接下来是在每个节点上进行本地设置,最重要的是设置一个唯一的主机名。我该怎么做?

我知道的一种方法是通过 user_data 参数提供脚本。那太好了,但是为了可用,我需要能够对该脚本进行参数化,以避免为每个代理重复一次脚本。

有意义吗?我真的很感激实现这一目标的便捷方式,因为我想以编程方式启动新实例。任何建议都会被考虑。

更新

举一个我的问题的例子,考虑我的供应木偶清单的这个片段:

ec2_instance { 'backend':
  ensure => present,
  name => 'backend',
  region => 'us-west-2',
  image_id => 'ami-f0091d91',
  instance_type => 't2.micro',
  key_name => 'mykey',
  security_groups => ['provision-sg'],
  user_data => template('configure.erb'),
}

ec2_instance { 'webfront':
  ensure => present,
  name => 'webfront',
  region => 'us-west-2',
  image_id => 'ami-f0091d91',
  instance_type => 't2.micro',
  key_name => 'mykey',
  security_groups => ['provision-sg'],
  user_data => template('configure.erb'),
}

这将确保两个实例启动并且运行。请注意 user_data => template('configure.erb') 指的是实例创建后执行的模板脚本。如果我只知道决策所基于的数据,我就可以在这里设置主机名(或任何我想要的)。我可以在实例描述中添加标签,但据我所知,configure.erb 脚本无法读取这些标签。

无论如何,设置主机名只是我解决根本问题的想法。可能还有其他更方便的方法。我想要的只是一种让这两个实例代表木偶大师的不同节点类型的方法。

问题是如何设置新实例,以便它从特定的 class

加载配置

让我试着解释一下我认为你正在尝试解决的问题

我想在这里回答什么

您有一个现有脚本,可以使用 aws-puppet 模块在 AWS 上设置 EC2 虚拟主机。该模块调用 AWS API 实际制作 EC2 虚拟主机。但它们仅包含 "built in" 到 API 调用中使用的 AMI 文件的配置。典型的 AMI 文件可能是 Centos 基础映像。在此阶段可以通过 "user data script" 进一步配置。但我们假设这是一个 shell 脚本,难以测试和维护,因此不包含复杂的设置

因此需要进一步配置、安装包和设置。为了实现此设置,puppet 有第二阶段 activity,使用完全不同的清单(问题中未详细说明)

第二阶段由附加到 puppet master 的新 EC2 虚拟主机控制。所以我假设你正在做的是:

  • 第 1 阶段,制作 EC2 主机
  • 第 2 阶段,当他们从 puppet 自行配置时

使用角色的基本答案

这里有一些关于如何使用 EC2 主机的两阶段配置使这个场景工作的想法

在创建时创建自定义事实"role"。制作一个文件 /etc/facter/facts.d/role.yaml 这样

role: webserver

这可以设置为通过将这样的命令添加到用户数据脚本来创建实例

echo 'role: webserver' > /etc/facter/facts.d/role.yaml

只要在 puppet 启动之前设置 "role",它就可以正常工作。

我假设您有一组带有清单的模块,模块路径中可能还有与角色同名的文件子目录

接下来,将您的 site.pp 改为

include "$role"

模块中的 init.pp 将启动并做正确的事情,安装包,配置文件等!

这里更详细地解释了这个想法https://puppetlabs.com/presentations/designing-puppet-rolesprofiles-pattern


另一种方法

以上是我没有测试过的非常粗糙的方法!我们的设置有角色,但通过 hiera 配置加载它们。 heira 配置看起来有点像这样

---
:backends:
  - yaml
:hierarchy:
    - role/%{::role}
    - global
:yaml:
  :datadir: /etc/puppet/environments/production/hiera

然后我可能有一个 /etc/puppet/environments/production/hiera/role/webserver.yaml 文件,上面写着

classes:
  - webserver
  - yum_repos
  - logstash
  - java8

site.pp 的结尾说

hiera_include('classes')

从 modules_include 文件中加载所有相关的 "classes" 定义

这样做的好处是每个角色可以加载多个 classes,代码重复更少

yaml 配置的 "global" 部分用于 class 由您环境中的所有内容加载的 es,例如管理员用户 ssh 密钥


定义类型示例

这里是一个示例,说明如何使用定义的类型作为 ec2_instance 的包装器将 "myrole" 传递到模板中。我没有测试过这个,我没有安装 aws puppet 东西

define my_instance( 
  $ensure = present,
  $region = 'us-west-2',
  $image_id = 'ami-f0091d91',
  $instance_type = 't2.micro',
  $key_name= 'mykey',
  $security_groups = ['provision-sg'],
  $myrole = 'webserver'
  )
{
ec2_instance { $title :
  ensure => $ensure,
  name => $title,
  region => $region,
  image_id => $image_id,
  instance_type => $instance_type,
  key_name => $key,
  security_groups => $security_groups,
  user_data => template('configure.erb'),
}
}

$instance_data={
  'backend' =>
  {
  ensure => present,
  name => 'backend',
  region => 'us-west-2',
  image_id => 'ami-f0091d91',
  instance_type => 't2.micro',
  key_name => 'mykey',
  security_groups => ['provision-sg'],
  myrole => 'voodooswamp'
},
  'webfront'=>
  {
  ensure => present,
  region => 'us-west-2',
  image_id => 'ami-f0091d91',
  instance_type => 't2.micro',
  key_name => 'mykey',
  security_groups => ['provision-sg'],
  myrole => 'humanfly'
  }
}


create_resources(my_instance, $instance_data)