Fujitsu K5 Infrastructure as Code (Cookie Cutter)

2017-03-10

Fujitsu K5 Infrastructure as Code (Cookie Cutter)

Machine-translated — the English original is authoritative.

Meine neueste Herausforderung bestand darin, einen Prozess zur Bereitstellung eines vordefinierten Infrastrukturmodells – ein einfaches Netzwerk mit 3 Knoten – in einer konsistenten und wiederholbaren Weise zu entwickeln. Dieses Modell musste jedoch in jeder Geschmacksrichtung (Flavor) mit unterschiedlichen Konfigurationen bereitgestellt werden.

Im Grunde wollte ein Kunde einen wiederholbaren Mechanismus, um die verschiedenen Knoten-Geschmacksrichtungen im großen Maßstab zu Leistungstests zu verwenden.

Wir hätten einfach auf den vorherigen HEAT-Beispielen aufbauen und eine massive YAML-Vorlage schreiben können, die die erforderliche Infrastruktur enthält. Dies ist jedoch fehleranfällig, schwer zu debuggen und weder sehr effizient noch flexibel.

Was wir benötigen, ist die Trennung der statischen und dynamischen Infrastrukturkomponenten – eine Vorlage zu definieren, die den statischen Komponenten entspricht und es ermöglicht, die dynamischen Komponenten als Parameter zu übergeben. Jeder Programmierer kennt das DRY-Code-Prinzip (Don’t Repeat Yourself – Wiederhole dich nicht) – das Gleiche gilt hier.

Da wir in ein Projekt mit bestehender Infrastruktur bereitstellten, habe ich auch einige dieser Details als Eingabeparameter an den Heat-Stack übergeben – z. B. routerId, kpName.

Die grundlegende Infrastrukturvorlage sah wie folgt aus:

Diese Datei enthält versteckte oder bidirektionale Unicode-Zeichen, die anders interpretiert oder kompiliert werden könnten als das, was unten angezeigt wird. Um sie zu überprüfen, öffnen Sie die Datei in einem Editor, der versteckte Unicode-Zeichen anzeigt.
Erfahren Sie mehr über bidirektionale Unicode-Zeichen

Versteckte Zeichen anzeigen

heat_template_version: 2013-05-23
# Autor: Graham Land
# Datum: 08/03/2017
# Zweck: Fujitsu K5 OpenStack IaaS Heat-Vorlage, die 3 Server in einem neuen Netzwerk bereitstellt und das Netzwerk an einen bestimmten Router anschließt.
# Eingabeparameter –
# routerId – eindeutige ID des Routers, an den das Netzwerk angeschlossen werden soll
# imageName – das zu bereitstellende Betriebssystem-Image
# flavorName – die vCPU- und RAM-Größe der Server
# dataVolume – die Größe des an die Server anzuschließenden Datenvolumens
# cidr – Details zur privaten Netzwerk-IP-Adresse
# azName – die Verfügbarkeitszone, in der die Server bereitgestellt werden sollen – dies muss offensichtlich mit dem Speicherort des Routers übereinstimmen
# kpName – der Name eines vorhandenen SSH-Schlüsselpaares, das in der Verfügbarkeitszone verwendet werden soll
#
#
# Ausgabeparameter – die IP-Adressen der 3 Server
#
# Twitter: @allthingsclowd
# Blog: https://allthingscloud.eu
#
description: Fujitsu K5 OpenStack IaaS Heat-Vorlage, die 3 Server in einem neuen Netzwerk bereitstellt und das Netzwerk an einen bestimmten Router anschließt.
# Eingabeparameter
parameters:
imageName:
type: string
label: Image-Name oder ID
description: Zu verwendendes Image für die Compute-Instanz
default: "Ubuntu Server 14.04 LTS (Englisch) 02"
flavorName:
type: string
label: Flavor
description: X vCPU und XXXXMB RAM
default: "T-1"
kpName:
type: string
label: Schlüsselname
description: Name des für die Compute-Instanz zu verwendenden Schlüsselpaares
default: "k5-loadtest-az1"
cidr:
type: string
label: IP-Adressdetails
description: Netzwerk-Adressbereich
default: "10.99.99.0/24"
dataVolume:
type: string
label: Volumengröße
description: Größe in GB des an den Server anzuschließenden Datenvolumens
default: "3"
osVolume:
type: string
label: Volumengröße
description: Größe in GB des an den Server anzuschließenden OS-Volumens
default: "20"
azName:
type: string
label: Verfügbarkeitszone
description: Zu verwendende Region-AZ
default: "uk-1a"
securityGroup:
type: string
label: Vorhandener K5-Sicherheitsgruppenname
description: Projekt-Sicherheitsgruppe
default: "demosecuritygroup"
routerId:
type: string
label: Externer Router
description: Router mit externem Zugriff für die globale IP-Zuweisung
default: "fcb1dddc-e0c8-4dd5-8a3f-4eee3b042912"
# K5-Infrastrukturressourcen, die erstellt werden sollen
resources:
############################ Netzwerkressourcen ####################
# Erstellen Sie ein privates Netzwerk in der Verfügbarkeitszone
demostack_private_net :
type: OS::Neutron::Net
properties:
name: "private"
availability_zone: { get_param: azName}
# Erstellen Sie ein neues Subnetz im privaten Netzwerk
demostack_private_subnet :
type: OS::Neutron::Subnet
depends_on: demostack_private_net
properties:
availability_zone: { get_param: azName}
network_id: { get_resource: demostack_private_net }
cidr: { get_param: cidr}
dns_nameservers: ["62.60.39.9", "62.60.39.10"]
# Schließen Sie eine Schnittstelle im Subnetz des demostacks-Netzwerks an den Router an
router_interface:
type: OS::Neutron::RouterInterface
depends_on: [demostack_private_subnet ]
properties:
router_id: { get_param: routerId }
subnet_id: { get_resource: demostack_private_subnet }
################## Server-Ressourcen ###########################
################################ Server erstellen demo-mgmt1-server ##############################
# Erstellen Sie ein Datenvolumen zur Verwendung mit dem Server
demo-mgmt1-server-data-vol:
type: OS::Cinder::Volume
properties:
availability_zone: { get_param: azName}
description: Datenspeicher
size: { get_param: dataVolume}
volume_type: "M1"
# Erstellen Sie ein Systemvolumen zur Verwendung mit dem Server
demo-mgmt1-server-sys-vol:
type: OS::Cinder::Volume
properties:
availability_zone: { get_param: azName}
size: { get_param: osVolume}
volume_type: "M1"
image : { get_param: imageName }
# Erstellen Sie einen Server unter Verwendung des oben definierten Systemvolumens
demo-mgmt1-server:
type: OS::Nova::Server
depends_on: [ demostack_private_subnet ]
properties:
key_name: { get_param: kpName }
image: { get_param: imageName }
flavor: { get_param: flavorName }
security_groups: [{get_param: securityGroup}]
block_device_mapping: [{"volume_size": { get_param: osVolume}, "volume_id": {get_resource: demo-mgmt1-server-sys-vol}, "delete_on_termination": True, "device_name": "/dev/vda"}]
admin_user: "ubuntu"
metadata: { "fcx.autofailover": True, "Example Custom Tag": "Multiple Server Build" }
user_data:
str_replace:
template:
#cloud-config
write_files:
– content:
#!/bin/bash
voldata_id=%voldata_id%
voldata_dev="/dev/disk/by-id/virtio-$(echo ${voldata_id}
mkfs.ext4 ${voldata_dev}
mkdir -pv /mnt/appdata
echo "${voldata_dev} /mnt/appdata ext4 defaults 1 2" >> /etc/fstab
mount /mnt/appdata
chmod 0777 /mnt/appdata
path: /tmp/format-disks
permissions: '0700'
runcmd:
– /tmp/format-disks
params:
"%voldata_id%": { get_resource: demo-mgmt1-server-data-vol }
user_data_format: RAW
networks: ["uuid": {get_resource: demostack_private_net} ]
# Schließen Sie das zuvor definierte Datenvolumen an den Server an
attach-demo-mgmt1-server-data-vol:
type: OS::Cinder::VolumeAttachment
depends_on: [ demo-mgmt1-server-data-vol, demo-mgmt1-server ]
properties:
instance_uuid: {get_resource: demo-mgmt1-server}
mountpoint: "/dev/vdb"
volume_id: {get_resource: demo-mgmt1-server-data-vol}
################################ Server erstellen demo-mgmt2-server ##############################
# Erstellen Sie ein Datenvolumen zur Verwendung mit dem Server
demo-mgmt2-server-data-vol:
type: OS::Cinder::Volume
properties:
availability_zone: { get_param: azName}
description: Datenspeicher
size: { get_param: dataVolume}
volume_type: "M1"
# Erstellen Sie ein Systemvolumen zur Verwendung mit dem Server
demo-mgmt2-server-sys-vol:
type: OS::Cinder::Volume
properties:
availability_zone: { get_param: azName}
size: { get_param: osVolume}
volume_type: "M1"
image : { get_param: imageName }
# Erstellen Sie einen Server unter Verwendung des oben definierten Systemvolumens
demo-mgmt2-server:
type: OS::Nova::Server
depends_on: [ demostack_private_subnet ]
properties:
key_name: { get_param: kpName }
image: { get_param: imageName }
flavor: { get_param: flavorName }
block_device_mapping: [{"volume_size": { get_param: osVolume}, "volume_id": {get_resource: demo-mgmt2-server-sys-vol}, "delete_on_termination": True, "device_name": "/dev/vda"}]
admin_user: "ubuntu"
security_groups: [{get_param: securityGroup}]
metadata: { "fcx.autofailover": True, "Example Custom Tag": "Multiple Server Build" }
user_data:
str_replace:
template:
#cloud-config
write_files:
– content:
#!/bin/bash
voldata_id=%voldata_id%
voldata_dev="/dev/disk/by-id/virtio-$(echo ${voldata_id}
mkfs.ext4 ${voldata_dev}
mkdir -pv /mnt/appdata
echo "${voldata_dev} /mnt/appdata ext4 defaults 1 2" >> /etc/fstab
mount /mnt/appdata
chmod 0777 /mnt/appdata
path: /tmp/format-disks
permissions: '0700'
runcmd:
– /tmp/format-disks
params:
"%voldata_id%": { get_resource: demo-mgmt2-server-data-vol }
user_data_format: RAW
networks: ["uuid": {get_resource: demostack_private_net} ]
# Schließen Sie das zuvor definierte Datenvolumen an den Server an
attach-demo-mgmt2-server-data-vol:
type: OS::Cinder::VolumeAttachment
depends_on: [ demo-mgmt2-server-data-vol, demo-mgmt2-server ]
properties:
instance_uuid: {get_resource: demo-mgmt2-server}
mountpoint: "/dev/vdb"
volume_id: {get_resource: demo-mgmt2-server-data-vol}
################################ Server erstellen demo-mgmt3-server ##############################
# Erstellen Sie ein Datenvolumen zur Verwendung mit dem Server
demo-mgmt3-server-data-vol:
type: OS::Cinder::Volume
properties:
availability_zone: { get_param: azName}
description: Datenspeicher
size: { get_param: dataVolume}
volume_type: "M1"
# Erstellen Sie ein Systemvolumen zur Verwendung mit dem Server
demo-mgmt3-server-sys-vol:
type: OS::Cinder::Volume
properties:
availability_zone: { get_param: azName}
size: { get_param: osVolume}
volume_type: "M1"
image : { get_param: imageName }
# Erstellen Sie einen Server unter Verwendung des oben definierten Systemvolumens
demo-mgmt3-server:
type: OS::Nova::Server
depends_on: [ demostack_private_subnet ]
properties:
key_name: { get_param: kpName }
image: { get_param: imageName }
flavor: { get_param: flavorName }
block_device_mapping: [{"volume_size": { get_param: osVolume}, "volume_id": {get_resource: demo-mgmt3-server-sys-vol}, "delete_on_termination": True, "device_name": "/dev/vda"}]
admin_user: "ubuntu"
security_groups: [{get_param: securityGroup}]
metadata: { "fcx.autofailover": True, "Example Custom Tag": "Multiple Server Build" }
user_data:
str_replace:
template:
#cloud-config
write_files:
– content:
#!/bin/bash
voldata_id=%voldata_id%
voldata_dev="/dev/disk/by-id/virtio-$(echo ${voldata_id}
mkfs.ext4 ${voldata_dev}
mkdir -pv /mnt/appdata
echo "${voldata_dev} /mnt/appdata ext4 defaults 1 2" >> /etc/fstab
mount /mnt/appdata
chmod 0777 /mnt/appdata
path: /tmp/format-disks
permissions: '0700'
runcmd:
– /tmp/format-disks
params:
"%voldata_id%": { get_resource: demo-mgmt3-server-data-vol }
user_data_format: RAW
networks: ["uuid": {get_resource: demostack_private_net} ]
# Schließen Sie das zuvor definierte Datenvolumen an den Server an
attach-demo-mgmt3-server-data-vol:
type: OS::Cinder::VolumeAttachment
depends_on: [ demo-mgmt3-server-data-vol, demo-mgmt3-server ]
properties:
instance_uuid: {get_resource: demo-mgmt3-server}
mountpoint: "/dev/vdb"
volume_id: {get_resource: demo-mgmt3-server-data-vol}
outputs:
server1_ip:
description: Dem Server 1 zugewiesene feste IP
value: { get_attr: [demo-mgmt1-server, networks, "private", 0]}
server2_ip:
description: Dem Server 2 zugewiesene feste IP
value: { get_attr: [demo-mgmt2-server, networks, "private", 0]}
server3_ip:
description: Dem Server 3 zugewiesene feste IP
value: { get_attr: [demo-mgmt3-server, networks, "private", 0]}

Rohansicht
simple_3_node_template.yml
Gehostet mit ❤ von GitHub

Nun, da wir unsere Infrastructure as Code haben, wie können wir sie im großen Maßstab bereitstellen, während wir die Eingabeparameter ändern? Nun, hier kommt die „API Economy“ ins Spiel. Fujitsu K5 basiert auf OpenStack, einer API-first-Plattform – in einfachen Worten bedeutet dies, dass die Plattform zu 100 % über API-Interaktionen gesteuert werden kann….immer noch verwirrt? Ich kann mehr Code verwenden!

Ich kann die oben genannte Heat-Vorlage zusammen mit den verschiedenen Parametersätzen an die Orchestrierungs-Engine von K5 senden, indem ich ein Python-Skript verwende, das die Daten an den Orchestrierungs-Endpunkt sendet.

Diese Datei enthält versteckte oder bidirektionale Unicode-Zeichen, die anders interpretiert oder kompiliert werden könnten als das, was unten angezeigt wird. Um sie zu überprüfen, öffnen Sie die Datei in einem Editor, der versteckte Unicode-Zeichen anzeigt.
Erfahren Sie mehr über bidirektionale Unicode-Zeichen

Versteckte Zeichen anzeigen

def deploy_heat_stack(k5token, stack_name, stack_to_deploy, stack_parameters):
"""Zusammenfassung: K5 HEAT API-Aufruf, um einen Heat-Stack, eingebettet in einen String, an ein K5-Projekt zu senden
Gibt zurück:
TYP: JSON-Objekt, das die neue Stack-ID oder Fehlercodes enthält
"""
orchestrationURL = unicode(get_endpoint(k5token, "orchestration")) + unicode("/stacks")
print orchestrationURL
token = k5token.headers['X-Subject-Token']
try:
response = requests.post(orchestrationURL,
headers={
'X-Auth-Token': token, 'Content-Type': 'application/json', 'Accept': 'application/json'},
json={
"files": {},
"disable_rollback": True,
"parameters": stack_parameters,
"stack_name": stack_name,
"template": stack_to_deploy,
"timeout_mins": 60
})
return response
except:
return ("\nUnerwarteter Fehler:", sys.exc_info())

Rohansicht
Deploy_Heat_Stack.py
Gehostet mit ❤ von GitHub

Der Vorteil hierbei ist, dass der gesamte Prozess nun in Code definiert ist – und dies kann problemlos versioniert werden, was konsistente Bereitstellungen garantiert.

Die vollständige Version dieser Lösung kann hier ausgecheckt werden: https://github.com/allthingsclowd/Fujitsu_OpenStack_K5_Heat_Cookie_Cutter

openstack heat cookie cutterv2

K5_Stack_Deployer – OpenStack-Vorlage

Autor: Graham Land

Datum: 08/03/17

Twitter: @allthingsclowd

Github: https://github.com/allthingscloud

Blog: https://allthingscloud.eu

deploy_stacks.py

Dieses Skript demonstriert, wie eine OpenStack HEAT-Vorlage
mehrmals mit unterschiedlichen Parametern bei jedem Aufruf bereitgestellt wird.

k5regionapiv1.py

Diese Datei wird von deploy_stacks.py importiert und enthält K5/OpenStack API-Funktions-Wrapper.

simple_3_node_stack.py

Diese Datei enthält einfach die YAML HEAT-Stack-Vorlage, eingebettet als String zur Verwendung in Python.

simple_3_node_stack.yml

Ist die native HEAT-Vorlage, die bereitgestellt wird (wird nicht verwendet, nur falls Sie separat damit spielen möchten).

k5contractsettingsV12.py

Sie MÜSSEN diese Datei konfigurieren, um sie an Ihre Umgebung anzupassen, bevor Sie die Bereitstellung durchführen.
Sie enthält einen Abschnitt für die Umgebung und einen Abschnitt für die Anwendung.
Im Abschnitt für die Umgebung geben Sie Ihre K5-Details ein, während im Anwendungsabschnitt die „Batches“ von Parametern konfiguriert werden, die in die Heat-Vorlage eingespeist werden sollen.
Jeder Batch enthält eine Liste von Heat-Vorlagen-Eingabeparametern – jede Parameterliste repräsentiert einen bereitgestellten Heat-Stack.

Link zu Github
https://github.com/allthingsclowd/Fujitsu_OpenStack_K5_Heat_Cookie_Cutter

Rohansicht
K5_Cookie_Cutter.md
Gehostet mit ❤ von GitHub

Viel Spaß beim Stapeln!

withk5youcan

Originally published on allthingscloud.eu (2017-03-10).

← All posts