Die eigene IT als digitalen Mix aus eigenen Servern und Public oder Private Clouds gestalten, das wäre technisch elegant und auf Dauer kostengünstig – aber aufwändig in der Einrichtung. Dass dank Ansible der letzte Punkt nicht so schwer wiegt wie angenommen, zeigt der folgende Artikel.
Nach seriösen Schätzungen wird kommendes Jahr die Hälfte der Unternehmen eine hybride Cloudarchitektur betreiben. Offenbar überzeugen die Vorteile des Mixes aus physisch in der Firma verbleibender, gewachsener IT und Public sowie Private Clouds beim externen Dienstleister. Oft geben geringere laufende Kosten den Ausschlag für Hybrid. Vielfach stellen sich aber auch funktionelle Vorteile ein. Angeblich agieren Firmen mit solchen IT-Strukturen erfolgreicher als ihre Mitbewerber [1].
Dass die Hybrid-Cloud in der Praxis noch nicht verbreiteter ist, liegt wohl an dem Aufwand, sie einzuführen. Dieser Artikel will beweisen, dass jeder Admin mit wenig Mühe einen beachtlichen Schritt dorthin gehen und zugleich Erfahrungen sammeln kann, um weitere Teile der lokalen IT auszulagern. Der Beitrag wird am Beispiel von AWS zeigen, wie Admins mit zwei Linux-VMs eine sichere Infrastruktur bauen, die von ihrer Struktur her sogar mandantenfähig ist. Das für den Admin Charmante ist: Nicht er selbst manuell, sondern Ansible [2] wird die Arbeitsschritte des Setup umsetzen.
Viele Anwender meinen noch, dass virtuelle Maschinen in der Cloud stets öffentlich erreichbar sind. Administratoren, die sich etwas mit den virtuellen Netzwerkinfrastrukturen bei AWS oder Azure beschäftigt haben, wissen aber, dass dort neben öffentlich zugänglichen VMs auch private Netze, VPNs und Router gängig sind. AWS und Azure bieten sogar VPNs in das private Firmennetz As a Service (kostenpflichtig) an (siehe Kasten “Amazon-Netzwerk-Glossar”).
Amazon-Netzwerk-Glossar
AWS’ Elastic Cloud Service erlaubt es, VMs komplex zu vernetzen, wie es in Open Stack oder VMware auch möglich ist. Jedoch muss der Admin dabei Amazons Logik beachten. Damit die Zielarchitektur in diesem Artikel verstehbar wird, ist eine kurze Einführung in die Begrifflichkeiten hilfreich.
Die höchste Hierarchiestufe ist ein Account, er kann zum Beispiel einer Firma gehören. Mehrere Mitarbeiter genießen dann Zugriff auf die Umgebung, deren VMs und andere Ressourcen. Der Account ist dem Projekt bei Open Stack vergleichbar.
AWS unterteilt die dem Kunden angebotene Infrastruktur in Regionen. Dies bezeichnet, wo auf der Welt das Rechenzentrum und damit die Daten liegen. Auch jedes Netzwerksetup ist relativ zu einer Region. Will der Admin seine Hybrid-Cloud in Irland und Deutschland betreiben, muss er das in diesem Artikel vorgestellte Konzept auch zweimal aufbauen.
Innerhalb des Accounts gibt es so genannte Virtual Private Clouds (VPCs). Pro Region und Account sind fünf VPCs möglich. In einer VPC kann der Anwender bis zu 200 getrennte Subnetze anlegen ([3] zeigt die Limits). Zwischen VPCs (auch zwischen Accounts) lässt sich ein Peering anlegen, das gezielt Traffic routet. Beide Peering-Partner müssen zustimmen, was besonders wichtig ist, wenn man eine Verbindung zwischen zwei Accounts aufbaut.
VMs in Subnetzen bekommen zunächst nur eine Adresse aus dem dem Subnetz zugeordneten Adressblock und sind von außen nicht erreichbar. Verwendet der Admin die Option Public IP Address, bekommt die VM zusätzlich eine IP-Adresse aus den öffentlichen Adressblöcken von AWS. Damit geschlossene VMs das Internet erreichen, muss dem Subnetz ein NAT-Gateway zugeordnet sein. Der Admin darf beim Erzeugen eines Subnetzes festlegen, dass jede VM, die er an dieses Netz bindet, automatisch eine öffentliche IP zugewiesen bekommt.
Routen speichert AWS wie erwartet in Routingtabellen. Die pflegt der Admin als separate Einheiten, die er einem VPC zuweist.
Security Groups beschreiben bei AWS eine Menge von IP-Filtern (ein- und ausgehend), die der Kunde auf eine VM anwendet, um von außen zu steuern, welche Pakete sie schicken darf beziehungsweise welche sie erreichen.
AWS bietet einen eigenen, recht kostenintensiven VPN as a Service. Daher verwendet das Setup des Artikels eine eigene VPN-VM, die preisgünstiger ausfällt – genauer: ausfallen kann, denn bei einer großen, teuren Amazon-Instanzgröße könnten die Kosten höher sein.
Die Zielarchitektur
Abbildung 1 zeigt die angestrebte Architektur, die der Autor als Projekt aufgebaut hat. Im lokalen Rechenzentrum rechts im Bild steht ein VPN-Gateway, das die Verbindung zum Gateway im AWS herstellt. Dies lässt sich zusammen mit der Firewall implementieren oder durch ein getrenntes Gateway. Außerdem konfiguriert Ansible eine lokale Open-VPN-Instanz, da der Autor schon VPN-Playbooks für Libre Swan, Fortinet und Juniper-Firewalls gebaut hat, könnte er die Komponente auch leicht austauschen.
Auf der AWS-Seite gestaltet sich der Aufbau etwas komplizierter, da der Autor eine mandantenfähige Lösung entwickeln wollte, also eine VM zum Internet, die an verschiedene geschlossene Umgebungen weiterleitet. Da die VPN-Daten in den geschlossenen Umgebungen dem Frontend nicht bekannt sein werden, dort aber trotzdem noch eine Eingangskontrolle auf Basis von IP-Adressen stattfindet, leitet die AWS-VM oben links die eingehenden Pakete per »socat« an den eigentlichen VPN-Service im geschlossenen Netz weiter, sodass trotzdem eine verschlüsselte Ende-zu-Ende-Verbindung entsteht. Wer keine Mandantenfähigkeit anstrebt, kann diese Indirektion aus dem Aufbau weglassen.
Im Subnetz im AWS existiert eine Routingtabelle, die dafür sorgt, dass das Routing zwischen dem lokalen Netze des eigenen Rechenzentrums und der AWS-VM mit Open VPN passiert.

Abbildung 1: Diese hybride Architektur ist das Ziel des vorgestellten Setup. Rechts ist der hier relevante Teil der IT im eigenen Haus zu sehen, links das anzulegende Setup in der Amazon-Cloud.
Netze und Peering
Wie bei anderen Virtualisierungsumgebungen auch beginnt der Admin mit dem Setup der virtuellen Netzwerk-Infrastruktur, damit die VMs am Schluss in den richtigen Netzen landen. Bei AWS legt er zuerst zwei VPCs an, das innere für die geschlossene Umgebung, das äußere für die Gateway-VM (Abbildung 2). Zu beiden gehört ein privates IP-Netz.
Das innere sollte so gewählt sein, dass es nicht mit dem Netz im eigenen Rechenzentrum kollidiert, da auf lokaler Seite ja die Routen in diesen Netzbereich auf das lokale VPN-Gateway zeigen müssen. Im externen Block reicht es, einen kleinen Netzbereich zu wählen, da dieser ja nur als Übergang dient. AWS benötigt nun noch Subnet-Objekte, deren IP-Netze jeweils eine Teilmenge des Gesamtbereichs des VPC zu sein haben.
Im nächsten Schritt legt der Admin ein VPC-Peering, womit er gewissermaßen ein virtuelles Kabel zwischen die beiden VPCs steckt (Abbildung 3). Dieses Peering muss der Admin in einem eigenen Arbeitsschritt akzeptieren. Damit die spätere VM im äußeren VPC hinausfindet, besteht der folgende Arbeitsschritt darin, ein Internetgateway anzulegen.
Das VPN-Routing
Die Konfigurationen bis hierhin bildet die Layer-2-Verkabelung nach, die auch bei einem physischen Aufbau notwendig wäre. Nun folgt das IP-Routing. In der Routingtabelle für das innere VPC setzt der Admin eine Route in das äußere Subnetz. Da die VPN-Verbindungen auf Applikationsebene (»socat«) weitergeleitet werden, besteht keine direkte IP-Verbindung zwischen dem VPN-Gateway und dem Internet. Das Ziel dieser Router ist das VPC-Peering – vergleichbar dem Setzen einer Interface-Route per »ip route add 1.2.3.0/24 dev eth0«.
Umgekehrt muss das externe VPC wissen, wie es zum internen findet. Das macht Routen zum internen Subnetz und ebenfalls zum VPC-Peering notwendig. Außerdem muss die Defaultroute des externen VPC auf das zuvor angelegte Internetgateway zeigen.
Die Konfiguration der Sicherheit schließt den Aufbau den virtuellen Netzwerks ab: Das VPN-Gateway im internen VPC braucht eingehend den Port für das VPN (im Falle Open VPN 1194/UDP, für IPsec mit NAT-Traversal 500/UDP und 4500/UDP). Damit der Admin noch auf die VM selber zugreifen darf, ist auch SSH-Zugang notwendig, also eingehend 22/TCP. Das Gleiche gilt für den externen Gatewayrechner. Hier lässt sich der VPN-Eingang dann auf die festen IPs der lokalen VPN-Gateways – so vorhanden – begrenzen. Das ist zwar kein sehr starker Schutz (vor allem bei UDP), es schränkt aber zumindest das Grundrauschen aus dem Internet etwas ein.
Zwei virtuelle Maschinen
Nun fehlen noch zwei VM-Instanzen, welche die Arbeit erledigen. Die bekommen die vorgesehene Software installiert und konfiguriert: Socat als Service auf der äußeren und Open VPN als VPN-Software auf der inneren.
Für das Anlegen einer VM benötigt der Admin eine Image-ID (»ami-id« in AWS-Sprache) und eine Instanzgröße. Für den Aufbau hier genügen die kleinen »t2.micro«-Instanzen vollkommen, da die Performance für die Internetanbindungen der meisten Firmen ausreicht. Wer einen 10-GBit-Anschluss ins Internet sein Eigen nennt, sollte die Größe der Instanz entsprechend anpassen. Den beiden Instanzen weist der Admin die richtigen VPCs und Subnetze sowie die vorher eingerichteten Security-Gruppen zu.
Beide VMs fußen auf einem Ubuntu-16.04-Server-Image (Abbildung 4). Die vordere VM erhält Socat als Portforwarder, den Systemd als Service startet. Für das VPN wäre dies bereits genug, aber die innere VM hat keinen Internetzugang, benötigt also zum Installieren der Pakete einen Proxy. Daher bekommt die vordere VM einen Squid-Webproxy verpasst, der allerdings so eingeschränkt ist, dass nur Clients aus dem internen Subnetz ihn verwenden dürfen. Entsprechend muss der Admin die Security Group noch um den Port 3128/TCP aus diesem Netz erweitern.
Auf die innere VM kommt Open VPN im Server-Modus. VMs im inneren Netz benötigen eine Route durch das Open-VPN-Gateway hindurch auf das lokale Netz des heimischen Rechenzentrums.

Abbildung 4: Beide anzulegenden VMs fußen auf einem von Amazon bereitgestellten Ubuntu-16.04-Server-Image.
Ansible vereinfacht und automatisiert das Ganze
Konfiguriert der Admin dies alles per Hand, bedeutet das schon einige Arbeit im AWS-Web-GUI. Dazu kommt noch, dass die Parameter auch alle zusammenpassen müssen, etwa die IP-Adressen der Netze und die entsprechenden Einträge in den Routingtabellen. Später gehen die Adressen auch in die Konfiguration der Services auf den VMs ein. Hier bieten sich dem Admin viele Möglichkeiten für Fehler, zumal das Nachgucken “Wie war noch mal die Adresse?” den Arbeitsfluss im Web-GUI unterbricht.
Ansibles Cloudmodule decken dagegen alles ab, was zum Anlegen notwendig ist. Dabei muss das Playbook immer die Ergebnisse des Anlegens einer Komponente speichern, da die IDs der einzelnen Komponenten notwendig sind, um die nächste anzulegen. Die von Amazon zugewiesene IP-Adresse der inneren VM muss der Admin zum Beispiel auch in der Socat-Konfiguration auf der äußeren VM eintragen.
Dank Ansible entsteht die ganze Konfiguration aus einem Guss und es passieren weniger Fehler. Das Gesamtensemble besitzt zwei Rollen für die Konfiguration auf der inneren und der äußeren VM. Am Anfang baut das Playbook die gesamte Infrastruktur auf.
Ein paar Daten sind parametrisiert, etwa die AWS-Region, der Adressraum für das innere VPC und das Subnetz sowie die Subnetz im lokalen LAN, damit das Generieren der VPN-Konfiguration gelingt. Diese Daten liest das Playbook aus einer Yaml-Datei ganz am Anfang.
Damit das Playbook überhaupt auf AWS zugreifen darf, muss der Admin entweder eine Datei in »~.aws/credentials« besitzen, die die Einträge »aws_access_key« und »aws_secret_access_key« enthält. Oder er setzt die Werte im Playbook als Variablen (besser über einen Ansible-Vault für die Sicherheit) oder hinterlegt sie in Environment-Variablen. Die Dokumentation der Cloudmodule (etwa unter [4]) erläutert die Varianten.
Die einzige Möglichkeit, auf eine VM in AWS zuzugreifen, ist eine SSH-Verbindung. Eine Konsole wie bei anderen Hostern gibt es nicht. Daher sollte auch der SSH-Schlüssel des Admin bei AWS hinterlegt sein. Listing 1 zeigt die Liste der Tasks, um den Schlüssel hochzukopieren (das geschieht nur, wenn er dort noch nicht vorhanden ist), die VPCs mit je einem Subnetz anzulegen und das VPC-Peering zu erzeugen.
Am Ende jeder »ec2«-Anweisung steht ein »register«-Block, der das Ergebnis der Operation in einer Variablen speichert. Zum Anlegen eines Subnet ist die ID des VPC notwendig, in dem das Subnet liegen soll. Das Gleiche passiert ab Zeile 49 auch fürs Peering, um es erst anzulegen und dann zu akzeptieren. Die letzte Task erzeugt das Internetgateway.
Listing 1
Tasks für die Basis und das Netzwerk
01 - name: Load Data
02 include_vars: "{{ datafile }}"
03 tags: getdata
04
05 - name: SSH Key
06 ec2_key:
07 name: ansible-admin-key
08 key_material: "{{ item }}"
09 state: present
10 region: "{{ region }}"
11 with_file: /home/user/.ssh/id_rsa.pub
12 register: sshkey
13 tags: sshkey
14
15 - name: Create VPC INT
16 ec2_vpc_net:
17 name: "{{ netname }}-int"
18 cidr_block: "{{ cidr_master }}"
19 region: "{{ region }}"
20 tags: create_vpc_int
21 register: myvpcint
22
23 - name: Create Subnet INT
24 ec2_vpc_subnet:
25 cidr: "{{ subnet }}"
26 vpc_id: "{{ myvpcint.vpc.id }}"
27 region: "{{ region }}"
28 state: present
29 tags: create_subnet_int
30 register: mysubnetint
31
32 - name: Create VPC Ext
33 ec2_vpc_net:
34 name: "{{ netname }}-ext"
35 cidr_block: 172.25.0.0/28
36 region: "{{ region }}"
37 tags: create_vpc_ext
38 register: myvpcext
39
40 - name: Create Subnet Ext
41 ec2_vpc_subnet:
42 cidr: 172.25.0.0/28
43 vpc_id: "{{ myvpcext.vpc.id }}"
44 region: "{{ region }}"
45 state: present
46 tags: create_subnet_ext
47 register: mysubnetext
48
49 - name: Create VPC Peering
50 ec2_vpc_peer:
51 region: "{{ region }}"
52 vpc_id: "{{ myvpcint.vpc.id }}"
53 peer_vpc_id: "{{ myvpcext.vpc.id }}"
54 state: present
55 register: myvpcpeering
56 tags: createvpcpeering
57
58 - name: Accept VPC Peering
59 ec2_vpc_peer:
60 region: "{{ region }}"
61 peering_id: "{{ myvpcpeering.peering_id }}"
62 state: accept
63 register: action_peer
64
65 - name: Create Internet Gateway
66 ec2_vpc_igw:
67 vpc_id: "{{ myvpcext.vpc.id }}"
68 region: "{{ region }}"
69 state: present
70 register: igw
71 tags: igw
Routing und VMs anlegen
Listing 2 zeigt den zweiten Teil des Playbook. Die Gather-Routes-Task sucht im internen VPC die Routingtabelle raus, um in diese die Route auf das äußere Netz einzutragen. Dann setzt das Playbook die Route von innen nach außen und in der umgekehrten Richtung. Die nächsten zwei Tasks erzeugen die Security-Gruppen für beide VMs.
Die letzte Task im Listing ist bedingt durch eine Eigenheit von Ansible, die ohne dieses laut AWS-API nicht notwendig ist. Das API kann einem Subnet mitgeben, ob Hosts in diesem Subnetz auch immer automatisch eine Public-IP zugewiesen bekommen sollen. Das geht in Ansible nur durch die im Listing gezeigte, nachträgliche Änderung.
Listing 3 sorgt für das Anlegen der beiden VMs. Die Tasks erzeugen die VMs und fügen sie jeweils zu einer Gruppe hinzu. Diese Gruppen werden gleich die folgenden Plays verwenden, um per SSH die Software zu installieren und zu konfigurieren. Die letzte Task des ersten Play wartet jetzt noch ab, bis die äußere VM per SSH erreichbar ist.
Listing 2
Routen und Filterregeln
01 - name: Gather Route tables
02 ec2_vpc_route_table_facts:
03 region: "{{ region }}"
04 filters:
05 vpc-id: "{{ myvpcint.vpc.id }}"
06 register: inttables
07 tags: gatherroutes
08
09 - name: Set Route out
10 ec2_vpc_route_table:
11 vpc_id: "{{ myvpcint.vpc.id }}"
12 region: "{{ region }}"
13 route_table_id: "{{ inttables.route_tables[0].id }}"
14 tags:
15 Name: "{{ netname }}-int"
16 subnets:
17 - "{{ mysubnetint.subnet.id }}"
18 routes:
19 - dest: 172.25.0.0/28
20 vpc_peering_connection_id: "{{ myvpcpeering.peering_id }}"
21 register: outboundroutetable
22 tags: routeout
23
24 - name: Set Route in
25 ec2_vpc_route_table:
26 vpc_id: "{{ myvpcext.vpc.id }}"
27 region: "{{ region }}"
28 tags:
29 Name: "{{ netname }}-ext"
30 subnets:
31 - "{{ mysubnetext.subnet.id }}"
32 routes:
33 - dest: "{{ subnet }}"
34 vpc_peering_connection_id: "{{ myvpcpeering.peering_id }}"
35 - dest: 0.0.0.0/0
36 gateway_id: igw
37 register: outboundroutetable
38 tags: routein
39
40 - name: internal Secgroup
41 ec2_group:
42 name: "{{ netname }}-int-secgroup"
43 vpc_id: "{{ myvpcint.vpc.id }}"
44 region: "{{ region }}"
45 purge_rules: true
46 description: Ansible-Generated internal rule
47 rules:
48 - proto: udp
49 from_port: 12345
50 to_port: 12345
51 cidr_ip: 0.0.0.0/0
52 - proto: tcp
53 from_port: 22
54 to_port: 22
55 cidr_ip: 0.0.0.0/0
56 - proto: tcp
57 from_port: 443
58 to_port: 443
59 cidr_ip: 0.0.0.0/0
60 register: intsecg
61 tags: internalsec
62
63 - name: external Secgroup
64 ec2_group:
65 name: "{{ netname }}-ext-secgroup"
66 vpc_id: "{{ myvpcext.vpc.id }}"
67 region: "{{ region }}"
68 purge_rules: true
69 description: Ansible-Generated internal rule
70 rules:
71 - proto: udp
72 from_port: 12345
73 to_port: 12345
74 cidr_ip: 0.0.0.0/0
75 - proto: tcp
76 from_port: 22
77 to_port: 22
78 cidr_ip: 0.0.0.0/0
79 - proto: tcp
80 from_port: 443
81 to_port: 443
82 cidr_ip: 0.0.0.0/0
83 - proto: tcp
84 from_port: 3128
85 to_port: 3128
86 cidr_ip: "{{ subnet }}"
87 register: extsecg
88 tags: externalsec
89
90 - name: Update Auto
91 ec2_auto_assign_public_ip_for_subnet:
92 subnet: "{{ mysubnetext.subnet.id }}"
93 region: "{{ region }}"
94 state: present
Listing 3
Ausrollen der VMs
01 - name: Deploy Backend
02 ec2:
03 key_name: ansible-user-key
04 instance_type: t2.micro
05 image: ami-d15a75c7
06 region: "{{ region }}"
07 wait: yes
08 id: test-backend
09 assign_public_ip: no
10 vpc_subnet_id: "{{ mysubnetint.subnet.id }}"
11 group_id: "{{ intsecg.group_id }}"
12 register: backendvm
13 tags: createbackend
14
15 - name: add frontend to group
16 add_host:
17 hostname: "{{ item.private_ip }}"
18 groupname: backend
19 with_items: "{{ backendvm.instances }}"
20
21
22 - name: Deploy Frontend
23 ec2:
24 key_name: ansible-user-key
25 instance_type: t2.micro
26 image: ami-d15a75c7
27 region: "{{ region }}"
28 wait: yes
29 id: test-frontend
30 assign_public_ip: yes
31 vpc_subnet_id: "{{ mysubnetext.subnet.id }}"
32 group_id: "{{ extsecg.group_id }}"
33 register: frontendvm
34 tags: createfrontend
35
36 - name: add frontend to group
37 add_host:
38 hostname: "{{ item.public_ip }}"
39 groupname: frontend
40 with_items: "{{ frontendvm.instances }}"
41
42 - name: Wait for ssh of frontend
43 wait_for:
44 host: "{{ item.public_dns_name }}"
45 port: 22
46 state: started
47 with_items: "{{ frontendvm.instances }}"
Von der Rolle
Das zweite und das dritte Play im Playbook konfigurieren die Software auf beiden VMs über jeweils eine Rolle. Besonders wichtig ist das letzte Play in Listing 4, da die innere VM nur über die äußere erreichbar ist, muss sie das SSH-Kommando über »ansible_ssh_common_args« umbiegen, damit die innere VM die äußere als Proxy verwendet. Das Einpacken in Rollen hat der Autor hier nur vorgenommen, da er die Konfiguration auf den VMs recycelbar haben wollte.
Listing 5 zeigt das Frontend-Play beziehungsweise die Tasks aus der Rolle. Die erste Task installiert Python im Raw-Modus, da auf dem verwendeten AWS-Ubuntu-Image kein Python installiert ist. Dann installiert und konfiguriert Ansible die Pakete Socat und Squid. Auffällig zeigt sich hier Socat, das ja eigentlich kein Service ist. Erst ein Systemd-Unitfile macht es zu einem Dienst auf UDP und 443/TCP. Die Zieladresse der inneren VM zum Weiterverbinden holt sich das Template aus dem vorherigen Playbook-Lauf. Das Play ab Zeile 43 schaltet die Dienste scharf und startet sie.
Das Listing 6 übernimmt die Konfiguration der inneren VM. Die kann nicht mit der Installation von Python beginnen, da »apt« erst mal mit dem vorgelagerte Proxy Bekanntschaft schließen muss, was hier auch im Raw-Modus geschieht.
Als Softwarepaket installiert die Rolle dann lediglich Open VPN und konfiguriert zwei Instanzen, eine auf dem UDP-Port und eine auf TCP/443. Diese Instanzen setzt ein Eintrag in der Datei »/etc/default/openvpn« auf Autostart. Das letzte Play im Listing schaltet den Open-VPN-Dienst an und startet ihn. Die SSL-Schlüssel waren in diesem Beispiel schon vorkonfiguriert. Es ist dem Admin selbst überlassen, per Ansible Zertifikate zu generieren und hochzuladen.
Listing 4
Die letzten beiden Plays
01 - name: Configure Frontend
02 hosts: frontend
03 remote_user: ubuntu
04 gather_facts: no
05 roles:
06 - agouros.aws.frontend
07
08 - name: Configure Backend
09 hosts: backend
10 remote_user: ubuntu
11 gather_facts: no
12 vars:
13 ansible_ssh_common_args: "-o ProxyCommand='ssh -W %h:%p -q ubuntu@{{ hostvars['localhost']['frontendvm']['instances'][0]['public_ip'] }}'"
14 roles:
15 - agouros.aws.backend
Listing 5
Die Installation des Frontends
01 - name: Install Python
02 raw: test -e /usr/bin/python || (sudo -s apt-get -y install python)
03
04 - name: Install Software
05 become: true
06 become_method: sudo
07 apt:
08 name: "{{ item }}"
09 state: present
10 cache_valid_time: 86400
11 with_items:
12 - socat
13 - squid
14
15 - name: Configure Squid
16 become: true
17 become_method: sudo
18 template:
19 src: templates/squid.conf.j2
20 dest: /etc/squid/squid.conf
21 notify: restart squid
22
23 - name: Configure socat
24 become: true
25 become_method: sudo
26 template:
27 src: templates/socat.service.j2
28 dest: /etc/systemd/system/socat.service
29 notify:
30 - daemon-reload
31 - start socat
32
33 - name: Configure socat443
34 become: true
35 become_method: sudo
36 template:
37 src: templates/socat443.service.j2
38 dest: /etc/systemd/system/socat443.service
39 notify:
40 - daemon-reload
41 - start socat
42
43 - name: Start and enable Services
44 become: true
45 become_method: sudo
46 systemd:
47 enabled: yes
48 state: started
49 daemon-reload: yes
50 name: "{{ item }}"
51 with_items:
52 - squid
53 - socat
54 - socat443
Listing 6
Die Konfiguartion der inneren VM
01 - name: Debug1
02 debug: msg="{{ inventory_hostname }}"
03
04 - name: Set Proxy
05 raw: test -e /etc/apt/apt.conf.d/80proxy || (sudo sh -c 'echo "Acquire::http::proxy \"http://{{ hostvars['localhost']['frontendvm']['instances'][0]['private_ip'] }}:3128\";" > /etc/apt/apt.conf.d/80proxy')
06
07 - name: Install Python
08 raw: test -e /usr/bin/python || (sudo -s apt-get -y install python)
09
10 - name: Install Software
11 become: true
12 become_method: sudo
13 apt:
14 name: "{{ item }}"
15 state: present
16 cache_valid_time: 86400
17 with_items:
18 - openvpn
19
20 - name: Set OpenVPN Name
21 become: true
22 become_method: sudo
23 lineinfile:
24 path: /etc/default/openvpn
25 regexp: "^AUTOSTART"
26 line: "AUTOSTART=\"{{ hostvars['localhost']['netname'] }} {{ hostvars['localhost']['netname'] }}-443\""
27
28 - name: Send SSL Files
29 become: true
30 become_method: sudo
31 copy:
32 src: "{{ item }}"
33 dest: /etc/openvpn
34 owner: root
35 mode: 0600
36 with_fileglob:
37 - "files/*"
38
39 - name: ccd-dir
40 become: true
41 become_method: sudo
42 file:
43 dest: /etc/openvpn/ccd
44 state: directory
45 mode: 0755
46 owner: root
47 group: root
48
49 - name: clientfile
50 become: true
51 become_method: sudo
52 template:
53 src: templates/clientfile.j2
54 dest: /etc/openvpn/ccd/clientfile
55
56 - name: OpenVPN Group
57 become: true
58 become_method: sudo
59 group:
60 name: openvpn
61 state: present
62
63 - name: OpenVPN user
64 become: true
65 become_method: sudo
66 user:
67 name: openvpn
68 state: present
69 groups: openvpn
70 system: yes
71
72 - name: Configure Openvpn
73 become: true
74 become_method: sudo
75 template:
76 src: templates/openvpn.conf.j2
77 dest: "/etc/openvpn/{{ hostvars['localhost']['netname']}}.conf"
78
79 - name: Configure Openvpn
80 become: true
81 become_method: sudo
82 template:
83 src: templates/openvpn.conf-443.j2
84 dest: "/etc/openvpn/{{ hostvars['localhost']['netname']}}-443.conf"
85
86 - name: Enable and start service
87 become: true
88 become_method: sudo
89 systemd:
90 name: openvpn
91 enabled: true
92 state: restarted
Ziel erreicht
Das Erweitern des eigenen Rechenzentrums um Ressourcen aus der Cloud kann deutlich Gesamtkosten sparen. Der Effekt tritt vor allem bei in der Anschaffung sehr teurer Dienste ein und bei Diensten, welche die eigene Firma nur gelegentlich braucht. Zu letzteren gehören auch zusätzliche Instanzen zum eigenen Webshop oder Webserver, wenn absehbar ein Kundenansturm droht.
Damit die Clouddienste aber – außer dies ist gerade gewünscht – nicht frei im Internet stehen, erlaubt es die Infrastruktur durchaus, AWS fast wie ein weiteres eigenes Rechenzentrum anzubinden. Für temporäre Ressourcen wäre ein händischer Auf- und Abbau aber sehr mühselig. Automation mit Ansible wie hier im Artikel, Terraform oder anderen Werkzeugen erlauben es dem Admin, schnell die Infrastruktur bereitzustellen und auch wieder abzubauen.
Infos
- IBM, “Growing up hybrid: Accelerating digital transformation”: https://www-01.ibm.com/common/ssi/cgi-bin/ssialias?htmlfid=GMW14087GBEN
- Ausgewählte Linux-Magazin-Artikel zu Ansible: Martin Loschwitz, “Operation Knopfdruck” und “Famose Automaten”: Linux-Magazin 11/17, S. 70 und 08/17, S. 60; Konstantin Agouros, “Zweite Runde”: Linux-Magazin 04/16, S. 58
- “Amazon VPC Limits” im VPC User Guide:https://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_Appendix_Limits.html
- “ec2 – create, terminate, start or stop an instance in ec2” in der Ansible-Dokumentation: http://docs.ansible.com/ansible/latest/ec2_module.html







