11

我正在尝试使用 EC2 实例在 AWS 中构建木偶托管基础设施(非企业)。使用 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我可以将标签添加到实例描述中,但据我所知,这在脚本中是不可读的。

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

4

1 回答 1

3

The problem is how to set up a new instance with so that it will load it's config from a particular class

Let me try and explain the problem I think you are trying to address

What I am trying to answer here

You have an existing script that sets up EC2 virtual hosts on AWS using the aws-puppet module. This module calls AWS API to actually make EC2 virtual hosts. But they only contain configuration that is "built in" to the AMI file that is used in the API call. A typical AMI file might be a Centos base image. Further configuration is possible at this phase via a "user data script". But let's assume this a shell script, difficult to test and maintain and so not containing complex setup

So further configuration, install of packages and setup is needed. In order to make this setup happen, there is a second phase of activity from puppet, using entirely different manifests (that are not detailed in the question)

This second phase is controlled by the new EC2 virtual hosts attaching to the puppet master in their own right. So what I am assuming you are doing is:

  • phase 1, making EC2 hosts
  • phase 2, when they are up config themselves from puppet

Basic Answer using roles

Here some ideas of how to make this scenario with two phase configuration of the EC2 hosts work

At create time make a custom fact "role". Make a file in /etc/facter/facts.d/role.yaml like this

role: webserver

This can be setup as the instance is made by adding a command like this to a User Data script

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

As long as this "role" is setup before puppet starts up it will work fine.

I am assuming that you have a set of modules with manifests and maybe files subdirectories in the module path with the same name as the role

Next, alter your site.pp to say something like

include "$role"

And the init.pp from the module will kick in and do the right thing, install packages, configure files etc!

This idea is explained in more detail here https://puppetlabs.com/presentations/designing-puppet-rolesprofiles-pattern


Another Approach

The above is a really crude way of doing it which I haven't tested! Our setup has roles but loads them via hiera configuration. The heira configuration looks somewhat like this

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

Then I might have a /etc/puppet/environments/production/hiera/role/webserver.yaml file which says

classes:
  - webserver
  - yum_repos
  - logstash
  - java8

And the end of the site.pp says

hiera_include('classes')

Which loads all the relevant "classes" definitions from the modules_include files

This has the advantage that multiple classes can be loaded by each role with much less duplication of code

The "global" part of the yaml configuration is intended for classes that are loaded by everything in your environment, for example admin user ssh keys


defined type example

Here is an example of how you might use a defined type as a wrapper around ec2_instance to pass the "myrole" into the template. I have not tested this, I don't have the aws puppet stuff installed

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)
于 2015-12-14T12:04:06.730 回答