Für die mit Ansible festgelegte Linux-Servergruppe habe ich versucht, (?) Ansible und serverspec zu ändern, um die folgenden Probleme zu lösen, die ich beim Testen mit serverspec hatte.
serverspec-init
bereitgestellten Anfangseinstellung ist es schwierig, den Testcode für jedes Verzeichnis mit dem Namen des zu testenden Servers vorzubereiten.Bitte bezeichnen Sie es als Einführungs- / Anfängerausgabe, wenn Sie Ansible und serverspec in Zusammenarbeit verwenden.
Implementieren Sie, damit Sie:
Ansible Control Node
Ansible Managed Node
$ tree -aF /autotools
/autotools
|-- .ssh/
| `-- aws_key.pem #Privater SSH-Schlüssel für verwalteten Knoten
|-- ansible/
| |-- ansible.cfg
| |-- group_vars/ #Variables Verzeichnis für Gruppen
| |-- host_vars/ #Hostvariablenverzeichnis
| |-- inventory/ #Inventarplatzierungsverzeichnis für Ansible
| `-- centos.yml # Playbook
`-- serverspec/
|-- .rspec
|-- Rakefile
|-- spec/
| |-- base/ #Testen Sie das Verzeichnis für die Platzierung des Mantels auf die Grundrolle
| | `-- sample_spec.rb #Testcode
| `-- spec_helper.rb
`-- spec_hosts/ #Variables Platzierungsverzeichnis für Serverspezifikation
Ansible
Lassen Sie uns zunächst project_name
mit einer englischen Zeichenfolge festlegen, um diese Servergruppe gemeinsam zu verwalten.
Verwenden Sie hier als Beispiel "Projektname" mit dem Namen "Anken".
ansible.cfg Geben Sie hier "ansible.cfg" an, das in der Umgebungsvariablen "ANSIBLE_CONFIG" verwendet werden soll. Ich verwende denselben Hostnamen für die Codeentwicklung, daher habe ich die ssh-Argumente hier aufgelistet.
$ export ANSIBLE_CONFIG=/autotools/ansible/ansible.cfg
/autotools/ansible/ansible.cfg
[defaults]
[ssh_connection]
ssh_args = -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no
[privilege_escalation]
become = true
Platzieren Sie den für SSH verwendeten privaten SSH-Schlüssel in den Ansible Managed Node in / autotools / .ssh
.
Der Schlüsselpfad ist in der Inventardatei aufgeführt.
Platzieren Sie die Inventardatei "anken.ini" unter "/ autotools / ansible / inventar /".
Grundsätzlich ist es in Ordnung, wenn Sie nach der Ansible-Regel schreiben. Da es jedoch im Mechanismus für die Verknüpfung mit Serverspezifikationen verwendet wird, setzen Sie bitte die folgenden drei unverzichtbaren Punkte.
project_name
mit [all: vars]
an/autotools/ansible/inventory/anken.ini
[anken]
prod_foobar1 ansible_host=xx.xx.xx.xx
dev_foobar1 ansible_host=yy.yy.yy.yy
[anken:vars]
ansible_user=centos
ansible_ssh_private_key_file=~/.ssh/aws_key.pem
[all:vars]
project_name=anken
Ansible wird für die IP oder den Namen von "ansible_host" ausgeführt.
Der inventar_hostname
(wobei im Beispiel prod_foobar1`` dev_foobar2
angegeben ist) muss nicht mit dem tatsächlichen Hostnamen des Knotens übereinstimmen.
Playbook
Das in diesem Implementierungsbeispiel verwendete Playbook-Beispiel lautet wie folgt.
name: Configure for serverspec at localhost
gibt die von serverspec verwendete Variablendatei aus.
centos.yml
---
- name: Playbook for centos7 managed node
hosts: all
gather_facts: true
tasks:
- name: Create group
group:
name: "{{ item.name }}"
gid: "{{ item.gid }}"
loop: "{{ group }}"
tags: group
- name: Create User
user:
name: "{{ item.name }}"
uid: "{{ item.uid }}"
group: "{{ item.group }}"
groups: "{{ item.groups }}"
home: "{{ item.home }}"
shell: "{{ item.shell }}"
loop: "{{ user }}"
tags: user
- name: System service
systemd:
name: "{{ item.name }}"
enabled: "{{ item.enabled }}"
state: "{{ item.state }}"
loop: "{{ service }}"
tags: service
- name: Configure for serverspec at localhost
hosts: localhost
connection: local
gather_facts: false
tasks:
- name: Dump hostvars for serverspec
copy:
content: "{{ hostvars | to_nice_yaml }}"
dest: "../serverspec/spec_hosts/{{ project_name }}.yml"
tags: serverspec
Platzieren Sie die für das Projekt gemeinsamen Variablen in / autotools / ansible / group_vars / # {project_name} .yml
. Wenn Sie eine andere Variable nur für einen bestimmten Inventar-Hostnamen angeben möchten, platzieren Sie sie in / autotools / ansible / host_vars / # {Inventar-Name} .yml
.
Geben Sie in der Variablendatei die Rolle an, die beim Testen mit serverspec mit serverspec_role
verwendet werden soll.
/autotools/ansible/group_vars/anken.yml
serverspec_role:
- base
group:
- name: unyo
gid: 1101
- name: infra
gid: 1102
- name: app
gid: 1103
user:
- name: user1
uid: 2001
group: customer
groups: [ unyo, infra]
home: /home/user1
shell: /bin/bash
- name: user2
uid: 2002
group: customer
groups: [ app ]
home: /home/user2
shell: /bin/bash
- name: user3
uid: 2003
group: customer
groups: [ app, infra ]
home: /home/user3
shell: /bin/bash
service:
- name: chronyd.service
enabled: false
state: stopped
- name: rsyncd.service
enabled: true
state: started
Hier werde ich es auf den Knoten "prod_foobar" beschränken und einige Variablen überschreiben.
/autotools/ansible/group_vars/prod_foobar.yml
group:
- name: unyo
gid: 2101
- name: infra
gid: 2102
- name: app
gid: 2103
Nach dem Anordnen der erforderlichen Dateien sollte es so aussehen.
$ tree /autotools/ansible -aF
/autotools/ansible
|-- ansible.cfg
|-- centos.yml
|-- group_vars/
| `-- anken.yml
|-- host_vars/
| `-- prod_foobar1
`-- inventory/
`-- anken.ini
Führen Sie das Playbook centos.yml mit der Inventardatei wie unten gezeigt aus.
$ cd /autotools/ansible
$ ansible -i ./inventory/anken centos.yml
serverspec
Nach dem Ausführen von Ansible sollte die Verzeichnis- / Dateistruktur auf der Serverspezifikationsseite folgendermaßen aussehen.
# tree /autotools/serverspec -aF
/autotools/serverspec
|-- .rspec
|-- Rakefile
|-- spec/
| |-- base/
| | `-- sample_spec.rb
| `-- spec_helper.rb
`-- spec_hosts/
`-- anken.yml #Von Ansible generierte variable Datei
Die Reihenfolge ist unterschiedlich, aber der Ausführungsbefehl von serverspec lautet wie folgt. Dies ist ein Bild der Übergabe des variablen Dateinamens (von Ansible generiert), der in serverspec verwendet wird, an den Befehl rake als Argument.
$ rake spec anken -T
rake spec # Run spec to all hosts
rake spec:dev_foobar1 # Run spec to dev_foobar1
rake spec:prod_foobar1 # Run spec to prod_foobar1
$ rake spec anken
Rakefile
Es gibt einige Änderungen gegenüber dem von serverspec-init
erstellten Standard-Rakefile.
/autotools/serverspec/Rakefile
require 'rake'
require 'rspec/core/rake_task'
require 'yaml'
#Variablendatei lesen
project_name = ARGV[1]
hosts = YAML.load_file("./spec_hosts/#{project_name}.yml")
desc "Run spec to all hosts"
task :spec => 'spec:all'
namespace :spec do
task :all => hosts.keys.map {|key| 'spec:' + key }
hosts.keys.each do |key|
desc "Run spec to #{key}"
RSpec::Core::RakeTask.new(key.to_sym) do |t|
ENV['INVENTORY_HOST'] = key
ENV['PROJECT_NAME'] = project_name
# serverspec_Unter einem Verzeichnis mit dem gleichen Namen wie die Rolle*_spec.Rb-Datei lesen
t.pattern = 'spec/{' + hosts[key]['serverspec_role'].join(',') + '}/*_spec.rb'
t.fail_on_error = false
end
end
end
#Fälschen Sie das Argument des Rechenbefehls als leere Aufgabe
ARGV.slice(1,ARGV.size).each{|v| task v.to_sym do; end}
Ich habe es unten als Referenz verwendet. Vielen Dank.
Referenz: Schreiben Sie eine normale argumentähnliche Verarbeitung in die Rake-Task https://qiita.com/nao58/items/aa50514d97f05eb8d128
Referenz: Offizielle Verwendung hostspezifischer Eigenschaften https://serverspec.org/advanced_tips.html
spec_helper.rb
Dies ändert auch einige Funktionen gegenüber dem Ausgangszustand "spec_helper.rb".
/autotools/serverspec/spec/spec_helper.rb
require 'serverspec'
require 'pathname'
require 'net/ssh'
require 'yaml'
#Lesen Sie die variable yml-Datei
key = ENV['INVENTORY_HOST']
project_name = ENV['PROJECT_NAME']
properties = YAML.load_file("./spec_hosts/#{project_name}.yml")
set_property properties["#{key}"]
set :backend, :ssh
set :path, '/sbin:/usr/sbin:$PATH'
#SSH-Ausführungsteil
RSpec.configure do |c|
c.before :all do
#Extrahieren Sie den in Ansible verwendeten Host, Benutzer, Kennwort oder Schlüssel aus der Datei mit den gelesenen Variablen
set :host, property['ansible_host']
options = Net::SSH::Config.for(c.host)
options[:user] = property['ansible_user']
if property['ansible_password']
options[:password] = property['ansible_password']
else
options[:keys] = [ property['ansible_ssh_private_key_file'] ]
end
options[:user_known_hosts_file] = '/dev/null'
set :ssh_options, options
end
end
Diese spec_helper.rb
unterstützt WinRM nicht, da sie set: backend,: ssh
ist. Da Sie jedoch alles in Ruby schreiben können, sollte es nicht schwierig sein, Windows zu unterstützen.
Dies ist ein Beispiel. Wie in "spec_helper.rb" geschrieben, kann "property ['xxx']" verwendet werden, um eine Variable aus einer Variablendatei abzurufen und wiederzuverwenden.
/autotools/serverspec/spec/base/
# frozen_string_literal: true
require 'spec_helper'
puts "\nRun serverspec to #{property['inventory_hostname']}"
property['group'].each do |attr|
describe group(attr['name']) do
it { should exist }
it { should have_gid attr['gid'] }
end
end
property['user'].each do |attr|
describe user(attr['name']) do
it { should exist }
it { should have_uid attr['uid'] }
it { should belong_to_group attr['group'] }
end
end
property['service'].each do |attr|
describe service(attr['name']) do
attr['enabled'] ? it { should be_enabled } : it { should_not be_enabled }
attr['state'] == 'started' ? it { should be_running } : it { should_not be_running }
end
end
Führen Sie den Befehl rake spec erneut mit dem von Ansible generierten Variablendateinamen als Argument aus, wie unten gezeigt. Es ist auch möglich, Tests für jede Einheit durchzuführen.
$ rake spec anken
$
$ rake spec anken -T #Befehl zum Anzeigen der Aufgabenliste
rake spec # Run spec to all hosts
rake spec:dev_foobar1 # Run spec to dev_foobar1
rake spec:prod_foobar1 # Run spec to prod_foobar1
$
$ rake spec:dev_foobar1 anken
Mit Ansible und serverspec konnten wir variable Dateien und Ereignis-Refiles vereinheitlichen, die in der Regel doppelt verwaltet werden. Außerdem konnte ich den Testcode rollenweise verwalten und ausführen, indem ich mich auf die in der Serverspezifikationsformel beschriebene Methode bezog.
Da serverspec ein ziemlich rubinrotes Tool ist, ist es für Leute, die nicht mit Ruby vertraut sind, schwierig, aber wenn Sie sich erst einmal daran gewöhnt haben, ist es gut, dass verschiedene Prozesse einfach zu schreiben sind.
Es wird unten veröffentlicht. https://github.com/kentarok/autotools
Recommended Posts