Orchestrace

V předchozích částech labu jsme si ukazovali možnosti OpenStack tak, že jsme se pohybovali v GUI a vytvářeli a propojovali jednotlivé zdroje. Tyto ruce na myši můžeme nahradit prsty na klávesnici s využitím příkazové řádky (to najdete v jiné kapitole) nebo rozehrát sekvence těchto kroků nějakým automatizovanějším způsobem jako jsou bash skripty, jednoduché aplikace třeba v Python nebo provádění operací přes Ansible (o tom všem se na tomto serveru dočtete a můžete si vyzkoušet). V této kapitole se ale zaměříme na něco jiného - na definici infrastruktury způsobem desired state. O co jde?

Základním principem je, že místo sekvenčního provádění operací (ať už ručně nebo skriptem) chceme definovat cílový stav infrastruktury a o to, jak to přeložit na sekvenci nějakých kroků, nechť se postará robot. Ať nějaký systém pozná v jakém pořadí co má dělat, nás to netrápí, ale chceme dosáhnout popsaného stavu. Vzniká tím vlastně „spustitelná dokumentace“, popis infrastruktury, který je nejen lidsky čitelný, ale slouží i systémům pro načtení a uvedení v život. Díky tomu je dokumentace vždy stoprocentně přesná a odpovídá skutečnosti (protože ta z ní automatizovaně vznikla). Tento typ práce nám také umožní verzovat celou infrastrukturu. Pokud potřebujeme provést změny v infrastruktuře, změníme její předpis a necháme orchestrační systém poladit skutečnost tak, aby odpovídala nové požadované infrastruktuře. S použitím nástrojů pro version control pak můžete mít přehled těchto verzí, zjistit kdo jaké změny navrhl a rychle se vrátit do předchozího stavu. Tento stav nezahrnuje jen VM, ale i jejich propojení, nastavení sítě, balancování, firewalling, VPNky, DNS jména, storage prostředky a jejich připojení k instancím VM a celou řadu dalších prostředků. Můžete se vrátit k předchozí konfiguraci infrastruktury nebo vytvářet šablony pro typové aplikace a ty potom sdílet a opakovaným způsobem uvádět v život.

V tomto labu se zaměříme na tři odlišné systémy, kde každý má své výhody.

  • OpenStack Heat je nativní součástí HPE Helion OpenStack a v ceně subscription máte tedy celý orchestrační systém včetně podpory. Šablony se vytváří ve formě lidsky čitelného textového souboru a zahrnují zdroje OpenStack včetně možnosti po sestavení infrastruktury předat řízení dalším nástrojům, které například nainstalují aplikace (Ansible, Chef apod.). Nevýhodou Heat je, že je určen pouze pro OpenStack.

  • Terraform je další open source nástroj pro orchestraci infrastruktury metodou desired state, který je ale vyvíjen nezávisle na OpenStack. Obsahuje koncept providerů, který vám umožní jednotným systémem pracovat s OpenStack i celou řadou dalších platforem jako je vSphere, Amazon AWS či Azure. Podobně jako u Heat se šablony vytváří textovým způsobem. Nevýhodou je, že jde o externí nástroj, takže jeho podpora není součástí HPE Helion OpenStack subscription.

  • HPE Cloud Service Automation je komerční enterprise řešení, kde samotná orchestrace je jen z jednou z komponent celého produktu. Podobně jako Terraform není CSA zaměřeno na jediného providera a podporuje i klasický vSphere či public cloud poskytovatele. CSA zahrnuje grafický designer, takže se nemusíte trápit v textovém editoru a infrastrukturu si doslova nakreslíte. Kromě desired state orchestrace zahrnuje další vlastnosti. CSA má zabudované verzování vašich infrastrukturních šablon a kromě desired state principů má v sobě i engine pro práci krok-za-krokem (workflow), což lze kombinovat, díky čemuž dokážete v CSA namodelovat i procesní stránku věci (třeba vytvoření účtů v Active Directory, zařazení do CMDB či monitoringu, schválení přidělení zdrojů sponzorem a tak podobně). CSA navíc umožňuje z jednotlivých šablon vytvářet nabídky, které jsou potom viditelné v uživatelském portálu. Vaši zákazníci či obchodní jednotky se mohou připojit do portálu ve formě e-shopu, kde si budou vybírat z vašeho katalogu služeb, objednávat služby, evidovat co odebírají, co používají, případně kolik za to platí. HPE Cloud Service Automation je tak komplexním řešením pro vaše multi-cloud IT. Nevýhodou je, že je to řešení komerční, které není v ceně Helion OpenStack. Pokud se ovšem rozhodnete jít cestou kompletního přístupu najdete CSA jako součást konvergovaného hardware + software balíku HPE Helion CloudSystem (od malých serverů v hyperkonvergovaných systémech HC250 a HC380 až k velkým CS 700 vybaveným třeba i 3PAR storage) nebo komplexního cloudového softwarového řešení HPE Helion Cloud Suite (zahrnuje integrované produkty jako je Helion OpenStack, Helion Stackato a právě Cloud Service Automation).

Pojďme si tyto systémy vyzkoušet (v případě CSA se zaměříme jen na orchestrační část, pro všechny vlastnosti CSA připravujeme samostatný oddíl).

OpenStack Heat

OpenStack nabízí velmi mocný nástroj pro tvorbu šablon a automatizaci celých prostředí. Tak jak znáte například šablonu pro VM, která zahrnuje operační systém, velikost RAM apod., šablona v OpenStack zahrnuje celou infrastrukturu. Tedy VM, privátní sítě a subnety, Floating IP, per-VM firewally, load-balancery, firewally, VPN přístupy, storage volume, diskové obrazy, přístupové SSH klíče, DNS jména či autokonfigurační skripty. Kromě toho umí orchestrátor provádět auto-scale (automatické přidávání a ubírání VM dle zátěže) nebo automatizovat instalaci aplikací (instalační skripty, vyvolání Ansible nebo Chef apod.).

Všechny šablony najdete také na labServeru v adresáři heat-sablony a celý tento lab si můžete projít z příkazové řádky. My dnes využijeme GUI, do kterého můžete kopírovat obsah šablon přímo z tohoto webu.

Připojte se do GUI a jděte na záložku Orchestration, Stacks.

a klikněte na Launch Stack

Šablonu můžete zadat přímo do okna, nebo ji nahrajete ve formě souboru. Obsah šablony používá YAML strukturu a pro začátek bude vypadat takto (na lab serveru ho najdete pod názvem 2-servery.yml):

    heat_template_version: 2015-04-30

    description: Nase prvni sablona

    resources:

      sit1:

        type: OS::Neutron::Net

        properties:

          name: stackSit1

      subnet1:

        type: OS::Neutron::Subnet

        properties:

          network_id: { get_resource: sit1 }

          cidr: 192.168.10.0/24

          allocation_pools:

            - start: 192.168.10.100

              end: 192.168.10.200

      skupina_serveru:

        type: OS::Heat::ResourceGroup

        depends_on: subnet1

        properties:

          count: 2

          resource_def:

            type: OS::Nova::Server

            properties:

              name: stackServer_%index%

              image: Cirros

              flavor: m1.tiny

              networks:

                - network: { get_resource: sit1 }

Vysvětleme si trošku z jeho obsahu. Nejprve definujeme síť a v ní subnet. Následně vytváříme skupinu serverů (instancí) v počtu dvou kusů. Specifikujeme image, flavor, jméno serveru a připojujeme do nově vzniklé sítě.

Vložte do okna (nebo přes soubor) a klikněte na Next

Použijte nějaké jméno, zadejte heslo a klikněte na Launch

Počkejte až všechno doběhne

Koukněte se do instancí – je tam něco nového?

A co v síťové topologii?

Rozklikněte si „stack“, tedy aplikovanou šablonu. Podíváme se, co se o ní můžeme dozvědět.

Na první záložce máte vizualizaci návazností. Pokud se do ni podíváte při průběhu vytváření uvidíte, jak vám jednotlivé zdroje zelenají tak, jak je engine vytváří.

V přehledu dostanete základní informace.

Velmi užitečná je záložka, kde jsou vidět zdroje, které v rámci šablony vznikly.

Co se všechno muselo stát, aby se šablona aplikovala?

A jakou šablonu to vlastně máme?

Pojďme teď změnit náš požadavek na infrastrukturu. Možná teď potřebujeme mít tyto servery tři místo dvou. Můžete tedy patřičným způsobem modifikovat náš infrastrukturní předpis a poslat výsledek do OpenStack jako aktualizaci. Heat se podívá zda tato nová verze odpovídá skutečnosti, nebo je potřeba udělat nějaké změny. V našem případě přidá server navíc.

Takhle vypadá modifikovaná šablona (jen změníme číslo u count - šablonu na serveru najdete v souboru 3-servery.yml):

    heat_template_version: 2015-04-30

    description: Nase prvni sablona

    resources:

      sit1:

        type: OS::Neutron::Net

        properties:

          name: stackSit1

      subnet1:

        type: OS::Neutron::Subnet

        properties:

          network_id: { get_resource: sit1 }

          cidr: 192.168.10.0/24

          allocation_pools:

            - start: 192.168.10.100

              end: 192.168.10.200

      skupina_serveru:

        type: OS::Heat::ResourceGroup

        depends_on: subnet1

        properties:

          count: 3

          resource_def:

            type: OS::Nova::Server

            properties:

              name: stackServer_%index%

              image: Cirros

              flavor: m1.tiny

              networks:

                - network: { get_resource: sit1 }

Řekněte teď OpenStacku, že chcete změnit požadovaný stav (desired state) infrastruktury.

Vložte nový desired state.

Zadejte svoje heslo a klikněte na UPDATE.

Po krátké chvilce bude nový stav vaší infrastruktury připraven.

Už celý stack nechceme? Nemusíme mazat jednotlivé zdroje, ale zlikvidujte to rovnou celé.

Šablona dokáže být interaktivnější a některé parametry si nechat zadat uživatelem až v okamžiku jejího deploymentu. Následující příklad dává možnost definovat typ (velikost/flavor) serveru, ale chceme dát na výběr jen ze dvou možností. Dále využijeme schopnosti formovat výstup, ve kterém předáme dál některé informace z instalace šablony, v našem případě jakou IP adresu VM dostala. Tteď se vám to bude zdát zbytečné, ale jsou dvě situace, kdy je to neocenitelné. Jednou z nich jsou složité šablony, ve kterých hledat výsledné údaje není snadné. Přitom vás třeba ve finále zajímá jen jedna věc - FloatingIP na load-balanceru a její DNS jméno. Šablona vám specificky tohle zobrazí. Druhý případ je, když potřebujete předat informace do dalšího zpracování, typicky nějakému nástroji, který to po sestavení infrastruktury potáhne dál a začne třeba instalovat software (např. HPE Server Automation, Ansible, Chef, Puppet apod.).

Použijte tuto šablonu (na serveru pod názvem infra-v1.yml):

    heat_template_version: 2015-04-30

    description: Budeme se ptat

    parameters:

      typ_instance:

        type: string

        label: Vyberte typ instance

        description: Vyberte si flavor m1.tiny nebo m1.small

        constraints:

          - allowed_values: [ m1.tiny, m1.small ]

            description: Pripustne hodnoty jsou m1.tiny nebo m1.small

    resources:

      sit1:

        type: OS::Neutron::Net

        properties:

          name: stackSit1

      subnet1:

        type: OS::Neutron::Subnet

        properties:

          network_id: { get_resource: sit1 }

          cidr: 192.168.10.0/24

          allocation_pools:

            - start: 192.168.10.100

              end: 192.168.10.200

      prvniVM:

        type: OS::Nova::Server

        properties:

          name: stackVM

          image: Cirros

          flavor: { get_param: typ_instance }

          networks:

            - network: { get_resource: sit1 }

    outputs:

      ip_instance:

        description: IP adresa vysledne instance

        value: { get_attr: [prvniVM, first_address] }

Založte tento Stack a klikněte na Next. Všimněte si, že GUI po nás chce doplnění našich parametrů.

Po nastartování stacku se podívejte do Overview – najdete tam náš požadovaný výstup.

Právě jsme si uvědomili, že tato infrastruktura potřebuje mít ještě Volume ve storage napojený do této VM. Popíšeme tento desired state a pojďme stack aktualizovat (můžete samozřejmě první i zrušit a tento založit znova, výsledek bude stejný, ale update je samozřjmě rychlejší, protože většinu zdrojů už máme rozjetých) Takhle bude šablona vypadat (na serveru pod názvem infra-v2.yml).

    heat_template_version: 2015-04-30

    description: Budeme se ptat

    parameters:

      typ_instance:

        type: string

        label: Vyberte typ instance

        description: Vyberte si flavor m1.tiny nebo m1.small

        constraints:

          - allowed_values: [ m1.tiny, m1.small ]

            description: Pripustne hodnoty jsou m1.tiny nebo m1.small

    resources:

      sit1:

        type: OS::Neutron::Net

        properties:

          name: stackSit1

      subnet1:

        type: OS::Neutron::Subnet

        properties:

          network_id: { get_resource: sit1 }

          cidr: 192.168.10.0/24

          allocation_pools:

            - start: 192.168.10.100

              end: 192.168.10.200

      prvniVM:

        type: OS::Nova::Server

        properties:

          name: stackVM

          image: Cirros

          flavor: { get_param: typ_instance }

          networks:

            - network: { get_resource: sit1 }

      prvniVolume:

        type: OS::Cinder::Volume

        properties:

          size: 1

      vol1_att:

        type: OS::Cinder::VolumeAttachment

        properties:

          instance_uuid: { get_resource: prvniVM }

          volume_id: { get_resource: prvniVolume }

          mountpoint: /dev/vdb

    outputs:

      ip_instance:

        description: IP adresa vysledne instance

        value: { get_attr: [prvniVM, first_address] }

Proveďte aktualizaci šablony (už víte jak na to) a přesvěčte se, že se Volume vytvořil a připojil.

Zatím nemáme vytvořen router ani přiřazenu Floating IP. Co kdybychom teď vytvořili nový router a síť do něj připojili a dali naší prvniVM Floating IP adresu?

Tohle je další verze naší infrastruktury, pošlete ji tam:

    heat_template_version: 2015-04-30

    description: Budeme se ptat

    parameters:

      typ_instance:

        type: string

        label: Vyberte typ instance

        description: Vyberte si flavor m1.tiny nebo m1.small

        constraints:

          - allowed_values: [ m1.tiny, m1.small ]

            description: Pripustne hodnoty jsou m1.tiny nebo m1.small

    resources:

      sit1:

        type: OS::Neutron::Net

        properties:

          name: stackSit1

      subnet1:

        type: OS::Neutron::Subnet

        properties:

          network_id: { get_resource: sit1 }

          cidr: 192.168.10.0/24

          allocation_pools:

            - start: 192.168.10.100

              end: 192.168.10.200

      stackRouter:

        type: OS::Neutron::Router

        properties:

          external_gateway_info:

            network: ext-net

      stackRouter_interface:

        type: OS::Neutron::RouterInterface

        properties:

          router_id: { get_resource: stackRouter }

          subnet_id: { get_resource: subnet1 }

      prvniVM_floating_ip:

        type: OS::Neutron::FloatingIP

        depends_on: stackRouter_interface

        properties:

          floating_network: ext-net

          port_id: { get_attr: [prvniVM,  addresses, stackSit1, 0, port] }

      prvniVM:

        type: OS::Nova::Server

        properties:

          name: stackVM

          image: Cirros

          flavor: { get_param: typ_instance }

          networks:

            - network: { get_resource: sit1 }

      prvniVolume:

        type: OS::Cinder::Volume

        properties:

          size: 1

      vol1_att:

        type: OS::Cinder::VolumeAttachment

        properties:

          instance_uuid: { get_resource: prvniVM }

          volume_id: { get_resource: prvniVolume }

          mountpoint: /dev/vdb

    outputs:

      ip_instance:

        description: IP adresa vysledne instance

        value: { get_attr: [prvniVM, first_address] }

      float_ip_instance:

        description: Venkovni IP adresa vysledne instance

        value: { get_attr: [prvniVM_floating_ip, floating_ip_address] }

Ověřte výsledek v topologii a výstupech.

Pro záklaní ukázku nám to stačí, smažte prosím tento stack.

Co tedy OpenStack orchestrace (komponenta Heat) umí?

  • Už dříve jsme si vyzkoušeli, že šablona může zahrnovat mnoho vstupních parametrů, takže dokument může být poměrně univerzální a při použití šablony si ji uživatel doladí dle reálných potřeb

  • Neukázali jsme si, ale Heat podporuje vytváření load-balancerů, DNS jmen a mikrosegmentačních pravidel, takže v šabloně zachytíte i poměrně komplexní síťařské věci

  • Šablona je v jednoduchém textovém formátu a sama o sobě může sloužit jako dokumentace (Infrastructure as code)

  • Jednoduchý textový formát můžete prohnat libovolným versioning systémem jako je třeba Git a snadno zjistíte rozdíly mezi verzemi šablony a udržujete přehled o tom kdo jaké změny provedl

  • Můžete zařadit konfigurační skripty a automatizovat i instalaci software, ideálně s předáním řízení de některého ze specializovaných nástrojů jako je Chef, Puppet, Ansible apod.

  • Heat šablony podporují automatické škálování

Terraform

Společnost Hashicorp je známe vícero svými velmi úspěšnými open source projekty, z nichž asi nejznámější je vagrant - systém pro automatické vytváření lokální virtuální infrastruktury (na úrovni například jednoho PC). Terraform je něco trochu podobného, ale se zaměřením na produkční práci s infrastrukturním prostředím různých typů. Terraform můžete použít k definici desired state, tedy deklarativního popisu vaší infrastruktury (virtuální servery, kontejnery, síťová propojení, balancery, mikrosegmentace, storage apod) a toto uložit ve versioning systému a aplikovat do reálné infrastruktury včetně řízení životního cyklu (opravit skutečný stav na desired, změnit desired state, smazat infrastrukturu atd.). Terraform má koncept providerů a můžete ho použít například pro OpenStack (tak jak to budeme dělat v tomto labu), ale také pro Amazon AWS, Azure či vSphere. Funkčně i koncepčně je tedy OpenStack Heat podobný, ale je univerzálnější.

Začněme něčím jednoduchým. Nejprve si načtěte připojovací proměnné na váš OpenStack, přidejme ještě informaci o doméně a skočme do připraveného adresáře na lab serveru.

    tomas@labserver:~$ source stack

    tomas@labserver:~$ export OS_DOMAIN_NAME=default

    tomas@labserver:~$ cd terraform/

    tomas@labserver:~/terraform$

První příklad bude jednoduchá infrastruktura čítající pouze jeden jediný volume ve storage, na které si ukážeme základní koncepty. Skočte do adresáře Volume a prozkoumejte soubor s popisem infrastruktury.

    tomas@labserver:~/terraform$ cd volume/

    tomas@labserver:~/terraform/volume$ cat volume.tf

    # OpenStack Provider (udaje vezmeme z env)

    provider "openstack" {

    }

    # Chceme volume

    resource "openstack_blockstorage_volume_v1" "volume_1" {

      name = "tf-volume"

      size = 1

    }

V souboru máme popsaného providera OpenStack s tím, že komunikační parametry získáváme z environmentální proměnné. Jedinou infrastrukturní komponentou je jeden volume ve storage.

Terraform prozkoumá současný a požadovaný stav infrastruktury a na základě toho automaticky vypracuje akční plán toho, co je potřeba udělat. Ten si můžeme prohlédnout ještě před tím, než necháme Terraform skutečně něco dělat.

    tomas@labserver:~/terraform/volume$ terraform plan

    Refreshing Terraform state prior to plan...

    The Terraform execution plan has been generated and is shown below.

    Resources are shown in alphabetical order for quick scanning. Green resources

    will be created (or destroyed and then created if an existing resource

    exists), yellow resources are being changed in-place, and red resources

    will be destroyed.

    Note: You didn't specify an "-out" parameter to save this plan, so when

    "apply" is called, Terraform can't guarantee this is what will execute.

    + openstack_blockstorage_volume_v1.volume_1

        attachment.#:      "" => "<computed>"

        availability_zone: "" => "<computed>"

        metadata.#:        "" => "<computed>"

        name:              "" => "tf-volume"

        size:              "" => "1"

        volume_type:       "" => "<computed>"

    Plan: 1 to add, 0 to change, 0 to destroy.

Pojďme teď plán aplikovat a ověřit, že volume skutečně existuje.

    tomas@labserver:~/terraform/volume$ terraform apply

    openstack_blockstorage_volume_v1.volume_1: Creating...

      attachment.#:      "" => "<computed>"

      availability_zone: "" => "<computed>"

      metadata.#:        "" => "<computed>"

      name:              "" => "tf-volume"

      size:              "" => "1"

      volume_type:       "" => "<computed>"

    openstack_blockstorage_volume_v1.volume_1: Still creating... (10s elapsed)

    openstack_blockstorage_volume_v1.volume_1: Creation complete

    Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

    The state of your infrastructure has been saved to the path

    below. This state is required to modify and destroy your

    infrastructure, so keep it safe. To inspect the complete state

    use the `terraform show` command.

    State path: terraform.tfstate

    tomas@labserver:~/terraform/volume$ openstack volume list

    +--------------------------------------+--------------+-----------+------+-------------+

    | ID                                   | Display Name | Status    | Size | Attached to |

    +--------------------------------------+--------------+-----------+------+-------------+

    | bdbe404a-a389-4851-bffc-24bb688170c6 | tf-volume    | available |    1 |             |

    +--------------------------------------+--------------+-----------+------+-------------+

Terraform si uložil stav vaší infrastruktury do souboru pro pozdější referenci. Můžete si ho prohlédnout.

    tomas@labserver:~/terraform/volume$ cat terraform.tfstate

    {

        "version": 1,

        "serial": 1,

        "modules": [

            {

                "path": [

                    "root"

                ],

                "outputs": {},

                "resources": {

                    "openstack_blockstorage_volume_v1.volume_1": {

                        "type": "openstack_blockstorage_volume_v1",

                        "primary": {

                            "id": "bdbe404a-a389-4851-bffc-24bb688170c6",

                            "attributes": {

                                "attachment.#": "0",

                                "availability_zone": "nova",

                                "description": "",

                                "id": "bdbe404a-a389-4851-bffc-24bb688170c6",

                                "metadata.#": "0",

                                "name": "tf-volume",

                                "size": "1",

                                "snapshot_id": "",

                                "source_vol_id": "",

                                "volume_type": ""

                            }

                        }

                    }

                }

            }

        ]

    }

Jaký by teď měl Terraform plán?

    tomas@labserver:~/terraform/volume$ terraform plan

    Refreshing Terraform state prior to plan...

    openstack_blockstorage_volume_v1.volume_1: Refreshing state... (ID: bdbe404a-a389-4851-bffc-24bb688170c6)

    No changes. Infrastructure is up-to-date. This means that Terraform

    could not detect any differences between your configuration and

    the real physical resources that exist. As a result, Terraform

    doesn't need to do anything.

Žádné změny nejsou potřeba. Pojďme ručně volume smazat.

    tomas@labserver:~/terraform/volume$ openstack volume delete tf-volume

Změnil Terraform plány?

    tomas@labserver:~/terraform/volume$ terraform plan

    Refreshing Terraform state prior to plan...

    openstack_blockstorage_volume_v1.volume_1: Refreshing state... (ID: bdbe404a-a389-4851-bffc-24bb688170c6)

    The Terraform execution plan has been generated and is shown below.

    Resources are shown in alphabetical order for quick scanning. Green resources

    will be created (or destroyed and then created if an existing resource

    exists), yellow resources are being changed in-place, and red resources

    will be destroyed.

    Note: You didn't specify an "-out" parameter to save this plan, so when

    "apply" is called, Terraform can't guarantee this is what will execute.

    + openstack_blockstorage_volume_v1.volume_1

        attachment.#:      "" => "<computed>"

        availability_zone: "" => "<computed>"

        metadata.#:        "" => "<computed>"

        name:              "" => "tf-volume"

        size:              "" => "1"

        volume_type:       "" => "<computed>"

    Plan: 1 to add, 0 to change, 0 to destroy.

Nechme je teď aplikovat a podívejme se do jeho souboru se stavem infrastruktury. Uvidíte, že se zvýšilo sériové číslo „verze“ infrastruktury.

    tomas@labserver:~/terraform/volume$ terraform apply

    openstack_blockstorage_volume_v1.volume_1: Creating...

      attachment.#:      "" => "<computed>"

      availability_zone: "" => "<computed>"

      metadata.#:        "" => "<computed>"

      name:              "" => "tf-volume"

      size:              "" => "1"

      volume_type:       "" => "<computed>"

    openstack_blockstorage_volume_v1.volume_1: Still creating... (10s elapsed)

    openstack_blockstorage_volume_v1.volume_1: Creation complete

    Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

    The state of your infrastructure has been saved to the path

    below. This state is required to modify and destroy your

    infrastructure, so keep it safe. To inspect the complete state

    use the `terraform show` command.

    State path: terraform.tfstate

    tomas@labserver:~/terraform/volume$ cat terraform.tfstate

    {

        "version": 1,

        "serial": 3,

        "modules": [

            {

                "path": [

                    "root"

                ],

                "outputs": {},

                "resources": {

                    "openstack_blockstorage_volume_v1.volume_1": {

                        "type": "openstack_blockstorage_volume_v1",

                        "primary": {

                            "id": "982bf30f-ebb0-4756-bb34-4543f213ab5b",

                            "attributes": {

                                "attachment.#": "0",

                                "availability_zone": "nova",

                                "description": "",

                                "id": "982bf30f-ebb0-4756-bb34-4543f213ab5b",

                                "metadata.#": "0",

                                "name": "tf-volume",

                                "size": "1",

                                "snapshot_id": "",

                                "source_vol_id": "",

                                "volume_type": ""

                            }

                        }

                    }

                }

            }

        ]

    }

Na závěr necháme Terraform zlikvidovat infrastrukturu.

    tomas@labserver:~/terraform/volume$ terraform destroy --force

    openstack_blockstorage_volume_v1.volume_1: Refreshing state... (ID: 982bf30f-ebb0-4756-bb34-4543f213ab5b)

    openstack_blockstorage_volume_v1.volume_1: Destroying...

    openstack_blockstorage_volume_v1.volume_1: Still destroying... (10s elapsed)

    openstack_blockstorage_volume_v1.volume_1: Destruction complete

    Apply complete! Resources: 0 added, 0 changed, 1 destroyed.

Už tato malá ukázka nám předvedla výborné vlastnosti Terraform. Máme deklarativní model infrastruktury, který můžeme kdykoli opakovat nebo zrušit. Stav infrastruktury se nám verzuje a před tím, než provedeme změny, můžeme Terroform požádat, aby nám řekl jaké má plány vedoucí ze současného stavu do požadovaného.

Teď když principy známe můžeme zkusit něco složitějšího. Skočte do adresáře s komplexnějším příkladem.

    tomas@labserver:~/terraform/volume$ cd ..

    tomas@labserver:~/terraform$ cd infra/

Prohlédněte si předpis, který zahrnuje infrastrukturu se sítí, routerem napojeným do externího světa a dvěma servery.

    tomas@labserver:~/terraform/infra$ cat infra.tf

    # OpenStack Provider (udaje vezmeme z env)

    provider "openstack" {

    }

    # Necht existuje Security Group

    resource "openstack_compute_secgroup_v2" "secgroup_1" {

      name = "tf-pravidla"

      description = "Moje TF Security Group"

      rule {

        from_port = 22

        to_port = 22

        ip_protocol = "tcp"

        cidr = "0.0.0.0/0"

      }

      rule {

        from_port = 80

        to_port = 80

        ip_protocol = "tcp"

        cidr = "0.0.0.0/0"

      }

      rule {

        from_port = 443

        to_port = 443

        ip_protocol = "tcp"

        cidr = "0.0.0.0/0"

      }

      rule {

        from_port = 8080

        to_port = 8080

        ip_protocol = "tcp"

        cidr = "0.0.0.0/0"

      }

    }

    # Necht existuje sit

    resource "openstack_networking_network_v2" "network_1" {

      name = "tf-net"

      admin_state_up = "true"

    }

    # Necht existuje subnet

    resource "openstack_networking_subnet_v2" "subnet_1" {

      name = "tf-sub"

      network_id = "${openstack_networking_network_v2.network_1.id}"

      cidr = "192.168.79.0/24"

      ip_version = 4

    }

    # Necht existuje router

    resource "openstack_networking_router_v2" "router_1" {

      name = "tf-router"

      external_gateway = "d4712d32-e929-4c20-9b9c-fe9fe66b85f6"

    }

    # Necht existuje interface routeru pripojujici sit

    resource "openstack_networking_router_interface_v2" "router_interface_1" {

      router_id = "${openstack_networking_router_v2.router_1.id}"

      subnet_id = "${openstack_networking_subnet_v2.subnet_1.id}"

    }

    # Necht existuje prvni server

    resource "openstack_compute_instance_v2" "server1" {

      name = "tf-server1"

      image_name = "Cirros"

      flavor_name = "m1.tiny"

      security_groups = ["${openstack_compute_secgroup_v2.secgroup_1.name}"]

      network {

        uuid = "${openstack_networking_network_v2.network_1.id}"

      }

    }

    # Necht existuje druhy server

    resource "openstack_compute_instance_v2" "server2" {

      name = "tf-server2"

      image_name = "Cirros"

      flavor_name = "m1.tiny"

      security_groups = ["${openstack_compute_secgroup_v2.secgroup_1.name}"]

      network {

        uuid = "${openstack_networking_network_v2.network_1.id}"

      }

    }

Jaké s tím má Terraform plány?

    tomas@labserver:~/terraform/infra$ terraform plan

    Refreshing Terraform state prior to plan...

    The Terraform execution plan has been generated and is shown below.

    Resources are shown in alphabetical order for quick scanning. Green resources

    will be created (or destroyed and then created if an existing resource

    exists), yellow resources are being changed in-place, and red resources

    will be destroyed.

    Note: You didn't specify an "-out" parameter to save this plan, so when

    "apply" is called, Terraform can't guarantee this is what will execute.

    + openstack_compute_instance_v2.server1

        access_ip_v4:              "" => "<computed>"

        access_ip_v6:              "" => "<computed>"

        flavor_id:                 "" => "<computed>"

        flavor_name:               "" => "m1.tiny"

        image_id:                  "" => "<computed>"

        image_name:                "" => "Cirros"

        name:                      "" => "tf-server1"

        network.#:                 "" => "1"

        network.0.access_network:  "" => "false"

        network.0.fixed_ip_v4:     "" => "<computed>"

        network.0.fixed_ip_v6:     "" => "<computed>"

        network.0.floating_ip:     "" => "<computed>"

        network.0.mac:             "" => "<computed>"

        network.0.name:            "" => "<computed>"

        network.0.port:            "" => "<computed>"

        network.0.uuid:            "" => "${openstack_networking_network_v2.network_1.id}"

        security_groups.#:         "" => "1"

        security_groups.313243212: "" => "tf-pravidla"

        volume.#:                  "" => "<computed>"

    + openstack_compute_instance_v2.server2

        access_ip_v4:              "" => "<computed>"

        access_ip_v6:              "" => "<computed>"

        flavor_id:                 "" => "<computed>"

        flavor_name:               "" => "m1.tiny"

        image_id:                  "" => "<computed>"

        image_name:                "" => "Cirros"

        name:                      "" => "tf-server2"

        network.#:                 "" => "1"

        network.0.access_network:  "" => "false"

        network.0.fixed_ip_v4:     "" => "<computed>"

        network.0.fixed_ip_v6:     "" => "<computed>"

        network.0.floating_ip:     "" => "<computed>"

        network.0.mac:             "" => "<computed>"

        network.0.name:            "" => "<computed>"

        network.0.port:            "" => "<computed>"

        network.0.uuid:            "" => "${openstack_networking_network_v2.network_1.id}"

        security_groups.#:         "" => "1"

        security_groups.313243212: "" => "tf-pravidla"

        volume.#:                  "" => "<computed>"

    + openstack_compute_secgroup_v2.secgroup_1

        description:                   "" => "Moje TF Security Group"

        name:                          "" => "tf-pravidla"

        rule.#:                        "0" => "4"

        rule.1552579484.cidr:          "" => "0.0.0.0/0"

        rule.1552579484.from_group_id: "" => ""

        rule.1552579484.from_port:     "" => "8080"

        rule.1552579484.id:            "" => "<computed>"

        rule.1552579484.ip_protocol:   "" => "tcp"

        rule.1552579484.self:          "" => "false"

        rule.1552579484.to_port:       "" => "8080"

        rule.3211544828.cidr:          "" => "0.0.0.0/0"

        rule.3211544828.from_group_id: "" => ""

        rule.3211544828.from_port:     "" => "443"

        rule.3211544828.id:            "" => "<computed>"

        rule.3211544828.ip_protocol:   "" => "tcp"

        rule.3211544828.self:          "" => "false"

        rule.3211544828.to_port:       "" => "443"

        rule.3719211069.cidr:          "" => "0.0.0.0/0"

        rule.3719211069.from_group_id: "" => ""

        rule.3719211069.from_port:     "" => "80"

        rule.3719211069.id:            "" => "<computed>"

        rule.3719211069.ip_protocol:   "" => "tcp"

        rule.3719211069.self:          "" => "false"

        rule.3719211069.to_port:       "" => "80"

        rule.836640770.cidr:           "" => "0.0.0.0/0"

        rule.836640770.from_group_id:  "" => ""

        rule.836640770.from_port:      "" => "22"

        rule.836640770.id:             "" => "<computed>"

        rule.836640770.ip_protocol:    "" => "tcp"

        rule.836640770.self:           "" => "false"

        rule.836640770.to_port:        "" => "22"

    + openstack_networking_network_v2.network_1

        admin_state_up: "" => "true"

        name:           "" => "tf-net"

        shared:         "" => "<computed>"

        tenant_id:      "" => "<computed>"

    + openstack_networking_router_interface_v2.router_interface_1

        router_id: "" => "${openstack_networking_router_v2.router_1.id}"

        subnet_id: "" => "${openstack_networking_subnet_v2.subnet_1.id}"

    + openstack_networking_router_v2.router_1

        admin_state_up:   "" => "<computed>"

        distributed:      "" => "<computed>"

        external_gateway: "" => "d4712d32-e929-4c20-9b9c-fe9fe66b85f6"

        name:             "" => "tf-router"

        tenant_id:        "" => "<computed>"

    + openstack_networking_subnet_v2.subnet_1

        cidr:        "" => "192.168.79.0/24"

        enable_dhcp: "" => "<computed>"

        gateway_ip:  "" => "<computed>"

        ip_version:  "" => "4"

        name:        "" => "tf-sub"

        network_id:  "" => "${openstack_networking_network_v2.network_1.id}"

        tenant_id:   "" => "<computed>"

    Plan: 7 to add, 0 to change, 0 to destroy.

Proveďme je.

    tomas@labserver:~/terraform/infra$ terraform apply

    openstack_networking_network_v2.network_1: Creating...

      admin_state_up: "" => "true"

      name:           "" => "tf-net"

      shared:         "" => "<computed>"

      tenant_id:      "" => "<computed>"

    openstack_networking_router_v2.router_1: Creating...

      admin_state_up:   "" => "<computed>"

      distributed:      "" => "<computed>"

      external_gateway: "" => "d4712d32-e929-4c20-9b9c-fe9fe66b85f6"

      name:             "" => "tf-router"

      tenant_id:        "" => "<computed>"

    openstack_compute_secgroup_v2.secgroup_1: Creating...

      description:                   "" => "Moje TF Security Group"

      name:                          "" => "tf-pravidla"

      rule.#:                        "0" => "4"

      rule.1552579484.cidr:          "" => "0.0.0.0/0"

      rule.1552579484.from_group_id: "" => ""

      rule.1552579484.from_port:     "" => "8080"

      rule.1552579484.id:            "" => "<computed>"

      rule.1552579484.ip_protocol:   "" => "tcp"

      rule.1552579484.self:          "" => "false"

      rule.1552579484.to_port:       "" => "8080"

      rule.3211544828.cidr:          "" => "0.0.0.0/0"

      rule.3211544828.from_group_id: "" => ""

      rule.3211544828.from_port:     "" => "443"

      rule.3211544828.id:            "" => "<computed>"

      rule.3211544828.ip_protocol:   "" => "tcp"

      rule.3211544828.self:          "" => "false"

      rule.3211544828.to_port:       "" => "443"

      rule.3719211069.cidr:          "" => "0.0.0.0/0"

      rule.3719211069.from_group_id: "" => ""

      rule.3719211069.from_port:     "" => "80"

      rule.3719211069.id:            "" => "<computed>"

      rule.3719211069.ip_protocol:   "" => "tcp"

      rule.3719211069.self:          "" => "false"

      rule.3719211069.to_port:       "" => "80"

      rule.836640770.cidr:           "" => "0.0.0.0/0"

      rule.836640770.from_group_id:  "" => ""

      rule.836640770.from_port:      "" => "22"

      rule.836640770.id:             "" => "<computed>"

      rule.836640770.ip_protocol:    "" => "tcp"

      rule.836640770.self:           "" => "false"

      rule.836640770.to_port:        "" => "22"

    openstack_compute_secgroup_v2.secgroup_1: Creation complete

    openstack_networking_network_v2.network_1: Creation complete

    openstack_compute_instance_v2.server2: Creating...

      access_ip_v4:              "" => "<computed>"

      access_ip_v6:              "" => "<computed>"

      flavor_id:                 "" => "<computed>"

      flavor_name:               "" => "m1.tiny"

      image_id:                  "" => "<computed>"

      image_name:                "" => "Cirros"

      name:                      "" => "tf-server2"

      network.#:                 "" => "1"

      network.0.access_network:  "" => "false"

      network.0.fixed_ip_v4:     "" => "<computed>"

      network.0.fixed_ip_v6:     "" => "<computed>"

      network.0.floating_ip:     "" => "<computed>"

      network.0.mac:             "" => "<computed>"

      network.0.name:            "" => "<computed>"

      network.0.port:            "" => "<computed>"

      network.0.uuid:            "" => "bd3d3293-aef7-4283-858c-200a445c5679"

      security_groups.#:         "" => "1"

      security_groups.313243212: "" => "tf-pravidla"

      volume.#:                  "" => "<computed>"

    openstack_compute_instance_v2.server1: Creating...

      access_ip_v4:              "" => "<computed>"

      access_ip_v6:              "" => "<computed>"

      flavor_id:                 "" => "<computed>"

      flavor_name:               "" => "m1.tiny"

      image_id:                  "" => "<computed>"

      image_name:                "" => "Cirros"

      name:                      "" => "tf-server1"

      network.#:                 "" => "1"

      network.0.access_network:  "" => "false"

      network.0.fixed_ip_v4:     "" => "<computed>"

      network.0.fixed_ip_v6:     "" => "<computed>"

      network.0.floating_ip:     "" => "<computed>"

      network.0.mac:             "" => "<computed>"

      network.0.name:            "" => "<computed>"

      network.0.port:            "" => "<computed>"

      network.0.uuid:            "" => "bd3d3293-aef7-4283-858c-200a445c5679"

      security_groups.#:         "" => "1"

      security_groups.313243212: "" => "tf-pravidla"

      volume.#:                  "" => "<computed>"

    openstack_networking_subnet_v2.subnet_1: Creating...

      cidr:        "" => "192.168.79.0/24"

      enable_dhcp: "" => "<computed>"

      gateway_ip:  "" => "<computed>"

      ip_version:  "" => "4"

      name:        "" => "tf-sub"

      network_id:  "" => "bd3d3293-aef7-4283-858c-200a445c5679"

      tenant_id:   "" => "<computed>"

    openstack_networking_router_v2.router_1: Creation complete

    openstack_networking_subnet_v2.subnet_1: Creation complete

    openstack_networking_router_interface_v2.router_interface_1: Creating...

      router_id: "" => "d990073a-c815-4c59-b963-070e236aba0f"

      subnet_id: "" => "f228b0c2-28e5-481f-8720-f5614faec0e7"

    openstack_compute_instance_v2.server2: Still creating... (10s elapsed)

    openstack_compute_instance_v2.server1: Still creating... (10s elapsed)

    openstack_networking_router_interface_v2.router_interface_1: Creation complete

    openstack_compute_instance_v2.server2: Still creating... (20s elapsed)

    openstack_compute_instance_v2.server1: Still creating... (20s elapsed)

    openstack_compute_instance_v2.server1: Creation complete

    openstack_compute_instance_v2.server2: Still creating... (30s elapsed)

    openstack_compute_instance_v2.server2: Creation complete

    Apply complete! Resources: 7 added, 0 changed, 0 destroyed.

    The state of your infrastructure has been saved to the path

    below. This state is required to modify and destroy your

    infrastructure, so keep it safe. To inspect the complete state

    use the `terraform show` command.

    State path: terraform.tfstate

Podívejte se do GUI, jak se mu to povedlo.

Dejme tomu, že jsme právě zjistili, že port 8080 tyto aplikace nepoužívají a není tedy vhodné jej nechat přístupný. Otevřete soubor infra.tf a poveďte tuto změnu (odmažte příslušné pravidlo):

    # Necht existuje Security Group

    resource "openstack_compute_secgroup_v2" "secgroup_1" {

      name = "tf-pravidla"

      description = "Moje TF Security Group"

      rule {

        from_port = 22

        to_port = 22

        ip_protocol = "tcp"

        cidr = "0.0.0.0/0"

      }

      rule {

        from_port = 80

        to_port = 80

        ip_protocol = "tcp"

        cidr = "0.0.0.0/0"

      }

      rule {

        from_port = 443

        to_port = 443

        ip_protocol = "tcp"

        cidr = "0.0.0.0/0"

      }

    }

Jaký plán Teraform má, aby nás dostal z existujícího stavu do nového požadovaného?

    tomas@labserver:~/terraform/infra$ terraform plan

    Refreshing Terraform state prior to plan...

    openstack_networking_network_v2.network_1: Refreshing state... (ID: bd3d3293-aef7-4283-858c-200a445c5679)

    openstack_networking_router_v2.router_1: Refreshing state... (ID: d990073a-c815-4c59-b963-070e236aba0f)

    openstack_compute_secgroup_v2.secgroup_1: Refreshing state... (ID: 73ce6029-9b1a-40f0-959c-29c956c85e56)

    openstack_networking_subnet_v2.subnet_1: Refreshing state... (ID: f228b0c2-28e5-481f-8720-f5614faec0e7)

    openstack_networking_router_interface_v2.router_interface_1: Refreshing state... (ID: fb6f919b-f809-46df-9a37-e85f37c36aed)

    openstack_compute_instance_v2.server1: Refreshing state... (ID: 1a375fbc-0422-4c5f-b628-b09c3dc0d700)

    openstack_compute_instance_v2.server2: Refreshing state... (ID: c550eabb-b4cf-4b75-9915-bf5973c9acd0)

    The Terraform execution plan has been generated and is shown below.

    Resources are shown in alphabetical order for quick scanning. Green resources

    will be created (or destroyed and then created if an existing resource

    exists), yellow resources are being changed in-place, and red resources

    will be destroyed.

    Note: You didn't specify an "-out" parameter to save this plan, so when

    "apply" is called, Terraform can't guarantee this is what will execute.

    ~ openstack_compute_secgroup_v2.secgroup_1

        rule.#:                        "4" => "3"

        rule.1552579484.cidr:          "0.0.0.0/0" => ""

        rule.1552579484.from_group_id: "" => ""

        rule.1552579484.from_port:     "8080" => "0"

        rule.1552579484.ip_protocol:   "tcp" => ""

        rule.1552579484.self:          "false" => "false"

        rule.1552579484.to_port:       "8080" => "0"

        rule.3211544828.cidr:          "0.0.0.0/0" => "0.0.0.0/0"

        rule.3211544828.from_group_id: "" => ""

        rule.3211544828.from_port:     "443" => "443"

        rule.3211544828.ip_protocol:   "tcp" => "tcp"

        rule.3211544828.self:          "false" => "false"

        rule.3211544828.to_port:       "443" => "443"

        rule.3719211069.cidr:          "0.0.0.0/0" => "0.0.0.0/0"

        rule.3719211069.from_group_id: "" => ""

        rule.3719211069.from_port:     "80" => "80"

        rule.3719211069.ip_protocol:   "tcp" => "tcp"

        rule.3719211069.self:          "false" => "false"

        rule.3719211069.to_port:       "80" => "80"

        rule.836640770.cidr:           "0.0.0.0/0" => "0.0.0.0/0"

        rule.836640770.from_group_id:  "" => ""

        rule.836640770.from_port:      "22" => "22"

        rule.836640770.ip_protocol:    "tcp" => "tcp"

        rule.836640770.self:           "false" => "false"

        rule.836640770.to_port:        "22" => "22"

    Plan: 0 to add, 1 to change, 0 to destroy.

Nechť tedy změny provede.

    tomas@labserver:~/terraform/infra$ terraform apply

    openstack_networking_network_v2.network_1: Refreshing state... (ID: bd3d3293-aef7-4283-858c-200a445c5679)

    openstack_networking_router_v2.router_1: Refreshing state... (ID: d990073a-c815-4c59-b963-070e236aba0f)

    openstack_compute_secgroup_v2.secgroup_1: Refreshing state... (ID: 73ce6029-9b1a-40f0-959c-29c956c85e56)

    openstack_networking_subnet_v2.subnet_1: Refreshing state... (ID: f228b0c2-28e5-481f-8720-f5614faec0e7)

    openstack_networking_router_interface_v2.router_interface_1: Refreshing state... (ID: fb6f919b-f809-46df-9a37-e85f37c36aed)

    openstack_compute_instance_v2.server1: Refreshing state... (ID: 1a375fbc-0422-4c5f-b628-b09c3dc0d700)

    openstack_compute_instance_v2.server2: Refreshing state... (ID: c550eabb-b4cf-4b75-9915-bf5973c9acd0)

    openstack_compute_secgroup_v2.secgroup_1: Modifying...

      rule.#:                        "4" => "3"

      rule.1552579484.cidr:          "0.0.0.0/0" => ""

      rule.1552579484.from_group_id: "" => ""

      rule.1552579484.from_port:     "8080" => "0"

      rule.1552579484.ip_protocol:   "tcp" => ""

      rule.1552579484.self:          "false" => "false"

      rule.1552579484.to_port:       "8080" => "0"

      rule.3211544828.cidr:          "0.0.0.0/0" => "0.0.0.0/0"

      rule.3211544828.from_group_id: "" => ""

      rule.3211544828.from_port:     "443" => "443"

      rule.3211544828.ip_protocol:   "tcp" => "tcp"

      rule.3211544828.self:          "false" => "false"

      rule.3211544828.to_port:       "443" => "443"

      rule.3719211069.cidr:          "0.0.0.0/0" => "0.0.0.0/0"

      rule.3719211069.from_group_id: "" => ""

      rule.3719211069.from_port:     "80" => "80"

      rule.3719211069.ip_protocol:   "tcp" => "tcp"

      rule.3719211069.self:          "false" => "false"

      rule.3719211069.to_port:       "80" => "80"

      rule.836640770.cidr:           "0.0.0.0/0" => "0.0.0.0/0"

      rule.836640770.from_group_id:  "" => ""

      rule.836640770.from_port:      "22" => "22"

      rule.836640770.ip_protocol:    "tcp" => "tcp"

      rule.836640770.self:           "false" => "false"

      rule.836640770.to_port:        "22" => "22"

    openstack_compute_secgroup_v2.secgroup_1: Modifications complete

    Apply complete! Resources: 0 added, 1 changed, 0 destroyed.

    The state of your infrastructure has been saved to the path

    below. This state is required to modify and destroy your

    infrastructure, so keep it safe. To inspect the complete state

    use the `terraform show` command.

    State path: terraform.tfstate

Ověřme si to.

    tomas@labserver:~/terraform/infra$ openstack security group rule list tf-pravidla

    +-----------------------------+-------------+-----------+------------+-----------------------+

    | ID                          | IP Protocol | IP Range  | Port Range | Remote Security Group |

    +-----------------------------+-------------+-----------+------------+-----------------------+

    | 2b2fbd0c-f481-41db-95ec-    | None        | None      |            | None                  |

    | dd5e41c0112c                |             |           |            |                       |

    | 546e73b2-73b3-4642-9e14-62c | tcp         | 0.0.0.0/0 | 80:80      | None                  |

    | 8ce91deb2                   |             |           |            |                       |

    | 55037e08-dc5a-4764-ad12-3ec | tcp         | 0.0.0.0/0 | 22:22      | None                  |

    | 2abe0ef86                   |             |           |            |                       |

    | 6782ba2e-ae5b-4634-9edc-    | None        | None      |            | None                  |

    | ccce1960d8bd                |             |           |            |                       |

    | f576a9e2-6564-47d9-8999-141 | tcp         | 0.0.0.0/0 | 443:443    | None                  |

    | 5ea444fbf                   |             |           |            |                       |

    +-----------------------------+-------------+-----------+------------+-----------------------+

Na závěr pojďme celou infrastrukturu zrušit. Při tomto procesu si všimněte, že Terraform postupuje ve správném pořadí, ale současně se snaží paralelizovat, co se dá. Nemusíme o tom přemýšlet, tohle si plánuje sám.

    tomas@labserver:~/terraform/infra$ terraform destroy --force

    openstack_networking_router_v2.router_1: Refreshing state... (ID: d990073a-c815-4c59-b963-070e236aba0f)

    openstack_networking_network_v2.network_1: Refreshing state... (ID: bd3d3293-aef7-4283-858c-200a445c5679)

    openstack_compute_secgroup_v2.secgroup_1: Refreshing state... (ID: 73ce6029-9b1a-40f0-959c-29c956c85e56)

    openstack_networking_subnet_v2.subnet_1: Refreshing state... (ID: f228b0c2-28e5-481f-8720-f5614faec0e7)

    openstack_networking_router_interface_v2.router_interface_1: Refreshing state... (ID: fb6f919b-f809-46df-9a37-e85f37c36aed)

    openstack_compute_instance_v2.server2: Refreshing state... (ID: c550eabb-b4cf-4b75-9915-bf5973c9acd0)

    openstack_compute_instance_v2.server1: Refreshing state... (ID: 1a375fbc-0422-4c5f-b628-b09c3dc0d700)

    openstack_networking_router_interface_v2.router_interface_1: Destroying...

    openstack_compute_instance_v2.server1: Destroying...

    openstack_compute_instance_v2.server2: Destroying...

    openstack_networking_router_interface_v2.router_interface_1: Still destroying... (10s elapsed)

    openstack_compute_instance_v2.server1: Still destroying... (10s elapsed)

    openstack_compute_instance_v2.server2: Still destroying... (10s elapsed)

    openstack_networking_router_interface_v2.router_interface_1: Destruction complete

    openstack_networking_subnet_v2.subnet_1: Destroying...

    openstack_networking_router_v2.router_1: Destroying...

    openstack_compute_instance_v2.server2: Destruction complete

    openstack_compute_instance_v2.server1: Destruction complete

    openstack_compute_secgroup_v2.secgroup_1: Destroying...

    openstack_networking_subnet_v2.subnet_1: Still destroying... (10s elapsed)

    openstack_networking_router_v2.router_1: Still destroying... (10s elapsed)

    openstack_networking_subnet_v2.subnet_1: Destruction complete

    openstack_networking_network_v2.network_1: Destroying...

    openstack_compute_secgroup_v2.secgroup_1: Still destroying... (10s elapsed)

    openstack_networking_router_v2.router_1: Destruction complete

    openstack_compute_secgroup_v2.secgroup_1: Destruction complete

    openstack_networking_network_v2.network_1: Still destroying... (10s elapsed)

    openstack_networking_network_v2.network_1: Destruction complete

    Apply complete! Resources: 0 added, 0 changed, 7 destroyed.

HPE Cloud Service Automation

V rámci povídání o HPE Helion OpenStack se podíváme pouze na podmnožinu funkcí CSA zaměřenou na orchestraci OpenStack, tedy vytvoříme si topologický návrh virtuální infrastruktury a otestujeme, že dojde k jejímu deploymentu do OpenStack. V této části labu se nebudeme zabývat budováním procesní workflow orchestrace, práci s jinými IaaS/PaaS/SaaS rešeními ani vytvářením katalogu služeb a nabídek pro uživatelský portál. Těmto částem se budeme v budoucnu věnovat v samostatném labu na HPE Cloud Service Automation.

V labu je pro vás připravena instance CSA, ale můžete si ji zprovoznit i sami. Community Edition, která obsahuje plný trial na 30 dní, je kontejnerizovaná a veřejně dostupná. Informace najdete na https://github.com/HewlettPackard/csa-ce.

Připojte se do CSA a nalogujte se jako admin/cloud.

Měl by pro vás být připraven nastavený OpenStack provider. Ten míří do našeho OpenStack labu a používá tenanta/projekt csa a uživatele csa/helion. Podívejte se na seznam providerů.

Můžete si prohlédnout jeho nastavení.

Vraťte se na úvodní stránku jděte do sekce pro vytváření designů.

Vyzkoušíme si topologický designer, tedy kreslení infrastruktury.

Spusťte designer

Vytvořte nový design

Zadejte název a klikněte na Create

Jděte do sekce Designer a vyfiltrujte si pouze objekty související s OpenStack

Přetáhněte server a vyplňte jeho parametry

Přidejte na plochu Volume a vyplňte jeho parametry

Volume chceme připojit k serveru. Klikněte myší na symbol žlutého kolečka a připojte ho k serveru.

Designer nám indikuje chybu a radí nám, co dělat dál.

Server musí být připojen do nějakého portu ve switchi, to je logické. Přidejte tedy na plochu interface a připojte server.

Port musí vést do nějaké sítě - přidejme ji tedy na plochu a nastavme její parametry. Může to být buď existující síť nebo necháme CSA vytvořit novou (to bude náš případ) a také ať vytvoří subnet.

Připojte port do sítě

Pojďme si teď tuto privátní síť napojit do routeru - přidejte router na plochu a zadejte jeho parametry. Opět necháme CSA vytvořit nový router.

Router musíme také připojit do externí sítě, tak ji dejte na plochu a vyplňte název venkovní sítě.

Propojte tyto komponenty

Co kdybychom si přidali Floating IP? Dejte ji na plochu a propojte se síťovým portem (na něm plovoucí venkovní adresa bude) a také s routerem (z tohoto segmentu se vezme).

Poslední co uděláme je, že přidáme mikrosegmentaci, tedy firewallové pravidlo. Dejte na plochu Security Group a vyplňte její parametry, zejména TCP porty, které bude naše aplikace používat.

Připojte tuto filtraci na síťový port

Výborně, design infrastruktury máme vytvořený. Můžeme z něj udělat položku v servisním katalogu, ocenit ji, nabídnout uživatelům v jejich portálu apod. (to není předmětem tohoto labu). Co my uděláme je, že šablonu otestujeme, tedy zkusíme ji poslat do OpenStack.

Jděte na záložku Test a klikněte na Test Run.

Můžeme mít různé testy pro různá prostředí (například různé OpenStack projekty, různé OpenStack instance apod.). My jen klikneme na Finish.

Podívejme se náš test

Infrastruktura se posílá do OpenStack

Chcete se podívat CSA pod ruce a zjistit jak to dělá, případně provádět troubleshooting? Robot, který to všechno provádí se jmenuje HPE Operation Orchestration a jeho základní verze je právě součástí CSA. Nalogujte se do GUI jménem a heslem admin/cloud.

Prohlédněte si flow úlohy - ta nejčerstvější, která dopadla dobře, se týká vašeho deploymentu.

Rozklikněte ji a podívejte se CSA/OO pod ruce.

Každý krok se skládá z několika operací, můžeme se na ně podívat. Takhle třeba vypadá vytvoření serveru.

Tento krok má také své flow.

Můžeme rozkliknout až jednotlivé atomární operace a přesně se podívat co a jak se kam posílá a jaká byla odpověď.

Na rozdíl od jiných orchestračních řešení tak nemusíte zkoumat složité log soubory nebo otevřít zdrojový kód, abyste zjistili, jak to orchestrátor dělá. Všechno je vám k dispozici v HPE Operation Orchestration a hotové tasky a kroky může upravovat nebo si vytvářet jakékoli jiné.

Podívejme se ještě do OpenStack (login je domain default, jméno csa, heslo helion) a ověřmě, že vše je jak očekáváme.

Hotový design můžeme publikovat do katalogu služeb a nabídnout uživatelům v samoobsluze případně navázat další procesy jako je zařazení do CMDB, asset managementu, vytvoření identit třeba v AD a tak podobně. O tom ale připravuje lab dedikovaný na HPE Cloud Service Automation.

Na závěr prosím uvolněte zdroje v labu a testovací deployment smažte.