You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Puppet管理Ambari Server并调用其API启动服务?

Solving Ambari Service Startup via Puppet

Got it, this is a common friction point when moving from Ansible (which plays nice with imperative API calls) to Puppet's declarative, resource-focused model. The key is bridging that gap between Puppet's "state desired" approach and the imperative API calls needed to control Ambari services. Here are your best options:

1. Use exec Resources (Quickest Fix)

Puppet's exec resource lets you run arbitrary commands, and you can add guard clauses (onlyif/unless) to ensure it only runs when the service isn't already in the desired state—keeping things idempotent, which is critical for Puppet.

Example: Start Hive via Ambari API with curl

# Define Ambari credentials (store these in Hiera with encryption for production!)
$ambari_host = 'your-ambari-server.example.com'
$ambari_port = '8080'
$ambari_user = 'admin'
$ambari_pass = 'your-secure-password'
$cluster_name = 'your-cluster'

exec 'start_hive_service' {
  command => "curl -u ${ambari_user}:${ambari_pass} -X PUT -H 'X-Requested-By: ambari' http://${ambari_host}:${ambari_port}/api/v1/clusters/${cluster_name}/services/HIVE -d '{\"ServiceInfo\":{\"state\":\"STARTED\"}}'",
  path    => ['/usr/bin', '/bin'],
  # Only run if Hive is NOT already started
  onlyif  => "curl -s -u ${ambari_user}:${ambari_pass} http://${ambari_host}:${ambari_port}/api/v1/clusters/${cluster_name}/services/HIVE | grep -q '\"state\":\"INSTALLED\"'",
  # Allow time for Ambari to process the start request
  timeout => 300,
}

You can replicate this pattern for HDFS, SmartSense, or any other Ambari-managed service—just swap out the service name in the API endpoints and onlyif check.

2. Build a Custom Puppet Type/Provider (Cleanest, Most Puppet-Idiomatic)

For a scalable, maintainable solution, wrap Ambari API interactions into a custom declarative resource. This lets you define service states just like you would with Puppet's native service resource.

Step 1: Define the Custom Type

Save this in modules/ambari/lib/puppet/type/ambari_service.rb:

Puppet::Type.newtype(:ambari_service) do
  @doc = 'Manages the state of an Ambari-managed service'

  ensurable do
    newvalue(:running) do
      provider.start
    end
    newvalue(:stopped) do
      provider.stop
    end
    defaultto(:running)
  end

  newparam(:name) do
    desc 'The name of the Ambari service (e.g., HIVE, HDFS, SMARTSENSE)'
    isnamevar
  end

  newparam(:cluster_name) do
    desc 'Name of the Ambari cluster'
    isrequired
  end

  newparam(:ambari_host) do
    desc 'Ambari server hostname/IP'
    isrequired
  end

  newparam(:ambari_port) do
    desc 'Ambari server port'
    defaultto('8080')
  end

  newparam(:username) do
    desc 'Ambari admin username'
    isrequired
  end

  newparam(:password) do
    desc 'Ambari admin password'
    isrequired
  end
end

Step 2: Implement the Provider

Save this in modules/ambari/lib/puppet/provider/ambari_service/ruby.rb:

require 'net/http'
require 'json'

Puppet::Type.type(:ambari_service).provide(:ruby) do
  def exists?
    # Check current service state via Ambari API
    uri = URI("http://#{resource[:ambari_host]}:#{resource[:ambari_port]}/api/v1/clusters/#{resource[:cluster_name]}/services/#{resource[:name]}")
    req = Net::HTTP::Get.new(uri)
    req.basic_auth(resource[:username], resource[:password])
    req['X-Requested-By'] = 'ambari'

    res = Net::HTTP.start(uri.hostname, uri.port) do |http|
      http.request(req)
    end

    state = JSON.parse(res.body)['ServiceInfo']['state']
    state == 'STARTED'
  end

  def start
    uri = URI("http://#{resource[:ambari_host]}:#{resource[:ambari_port]}/api/v1/clusters/#{resource[:cluster_name]}/services/#{resource[:name]}")
    req = Net::HTTP::Put.new(uri)
    req.basic_auth(resource[:username], resource[:password])
    req['X-Requested-By'] = 'ambari'
    req['Content-Type'] = 'application/json'
    req.body = { 'ServiceInfo' => { 'state' => 'STARTED' } }.to_json

    Net::HTTP.start(uri.hostname, uri.port) do |http|
      http.request(req)
    end
  end

  def stop
    # Similar to start, but set state to 'STOPPED'
    uri = URI("http://#{resource[:ambari_host]}:#{resource[:ambari_port]}/api/v1/clusters/#{resource[:cluster_name]}/services/#{resource[:name]}")
    req = Net::HTTP::Put.new(uri)
    req.basic_auth(resource[:username], resource[:password])
    req['X-Requested-By'] = 'ambari'
    req['Content-Type'] = 'application/json'
    req.body = { 'ServiceInfo' => { 'state' => 'STOPPED' } }.to_json

    Net::HTTP.start(uri.hostname, uri.port) do |http|
      http.request(req)
    end
  end
end

Step 3: Use the Custom Resource in Your Manifest

ambari_service { 'HIVE':
  ensure        => running,
  cluster_name  => 'your-cluster',
  ambari_host   => 'your-ambari-server.example.com',
  username      => 'admin',
  password      => 'your-secure-password',
}

ambari_service { 'HDFS':
  ensure        => running,
  cluster_name  => 'your-cluster',
  ambari_host   => 'your-ambari-server.example.com',
  username      => 'admin',
  password      => 'your-secure-password',
}

This approach fits perfectly with Puppet's declarative model—you define the desired state, and the provider handles the API calls and state checks automatically.

3. Leverage Community Modules (If Available)

Check the Puppet Forge for maintained Ambari modules (e.g., puppet-ambari). These often include pre-built resources for managing services out of the box, saving you from writing custom code. Just verify compatibility with your Ambari version before using.

Key Notes for All Solutions

  • Idempotency is Non-Negotiable: Always add checks (onlyif for exec, exists? for custom providers) to avoid repeating API calls unnecessarily.
  • Secure Credentials: Never hardcode passwords in manifests. Use Hiera with encryption (e.g., eyaml) or Puppet Vault to store sensitive data.
  • Timeout Handling: Ambari service starts can take several minutes—set appropriate timeouts to avoid Puppet failing prematurely.

内容的提问来源于stack exchange,提问作者L.HAMES

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:39:31