

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

# Beispiel 4: Hinzufügen der Flusssteuerung
<a name="cookbooks-101-basics-ruby"></a>

**Wichtig**  
Der AWS OpsWorks Stacks Dienst hat am 26. Mai 2024 das Ende seiner Lebensdauer erreicht und wurde sowohl für neue als auch für bestehende Kunden deaktiviert. Wir empfehlen Kunden dringend, ihre Workloads so bald wie möglich auf andere Lösungen zu migrieren. Wenn Sie Fragen zur Migration haben, wenden Sie sich an das AWS Support Team auf [AWS re:POST](https://repost.aws/) oder über den [AWS Premium-Support](https://aws.amazon.com/support).

Einige Rezepte sind nur eine Reihe von Chef-Ressourcen. In dem Fall werden bei der Rezeptausführung einfach die einzelnen Ressourcenanbieter nacheinander ausgeführt. Allerdings ist ein komplexerer Ausführungspfad meist sinnvoller. Nachfolgend finden Sie zwei gängige Szenarien:
+ Ein Rezept soll die gleiche Ressource mehrfach und mit unterschiedlichen Attributeinstellungen ausführen.
+ Für unterschiedliche Betriebssysteme sollen verschiedene Attributeinstellungen verwendet werden.

Sie können solche Szenarien durch die Einbindung von Ruby-Steuerungsstrukturen in das Rezept realisieren. In diesem Abschnitt wird erklärt, wie Sie das Rezept aus [Beispiel 3: Erstellen von Verzeichnissen](cookbooks-101-basics-directories.md) für beide Szenarien anpassen.

**Topics**
+ [Iteration](#cookbooks-101-basics-ruby-iteration)
+ [Bedingungslogik](#cookbooks-101-basics-ruby-conditional)

## Iteration
<a name="cookbooks-101-basics-ruby-iteration"></a>

In [Beispiel 3: Erstellen von Verzeichnissen](cookbooks-101-basics-directories.md) wurde veranschaulicht, wie Sie mit einer `directory`-Ressource ein oder mehrere Verzeichnisse erstellen. Aber was ist, wenn Sie zwei separate Verzeichnisse – `/srv/www/config` und `/srv/www/shared` – erstellen möchten? Sie können für jedes Verzeichnis eine separate "directory"-Ressource implementieren. Sollen viele Verzeichnisse erstellt werden, ist das jedoch sehr mühselig. Das folgende Rezept bietet dafür eine einfachere Methode. 

```
[ "/srv/www/config", "/srv/www/shared" ].each do |path|
  directory path do
    mode 0755
    owner 'root'
    group 'root'
    recursive true
    action :create
  end
end
```

Anstatt für jedes Unterverzeichnis eine separate "directory"-Ressource zu verwenden, wird im Rezept eine Zeichenfolgensammlung mit enthaltenen Unterverzeichnispfaden genutzt. Bei der `each`-Methode von Ruby wird die Ressource einmal für jedes Sammlungselement (beginnend mit dem ersten) ausgeführt. Der Elementwert wird in der Ressource durch die `path`-Variable – in diesem Fall der Verzeichnispfad – dargestellt. Dieses Beispiel können Sie einfach anpassen, um eine beliebige Anzahl an Unterverzeichnissen zu erstellen.

**So führen Sie das Rezept aus**

1. Bleiben Sie im Verzeichnis `createdir`. Dieses Rezeptbuch wird auch in den nächsten Beispielen verwendet. 

1. Führen Sie `kitchen destroy` aus, damit Sie mit einer neuen Instance beginnen können (sofern noch nicht geschehen). 

1. Ersetzen Sie den Code in `default.rb` durch den Beispiel-Code und führen Sie `kitchen converge` aus.

1. Melden Sie sich an der Instance an. Die neu erstellten Verzeichnisse werden unter `/srv` angezeigt.

Sie können mithilfe einer Hash-Tabelle zwei Werte für jede Iteration angeben. Mit dem folgenden Rezept werden `/srv/www/config` und `/srv/www/shared` jeweils mit einem anderen Modus erstellt.

```
{ "/srv/www/config" => 0644, "/srv/www/shared" => 0755 }.each do |path, mode_value|
  directory path do
    mode mode_value
    owner 'root'
    group 'root'
    recursive true
    action :create
  end
end
```

**So führen Sie das Rezept aus**

1. Führen Sie `kitchen destroy` aus, damit Sie mit einer neuen Instance beginnen können (sofern noch nicht geschehen). 

1. Ersetzen Sie den Code in `default.rb` durch den Beispiel-Code und führen Sie `kitchen converge` aus.

1. Melden Sie sich an der Instance an. Die neu erstellten Verzeichnisse werden unter `/srv` mit den angegebenen Modi angezeigt.

**Anmerkung**  
OpsWorks In Stacks-Rezepten wird dieser Ansatz häufig verwendet, um Werte aus der [JSON-Datei für die Stack-Konfiguration und Bereitstellung](workingcookbook-json.md) zu extrahieren — was im Grunde eine große Hashtabelle ist — und sie in eine Ressource einzufügen. Ein Beispiel finden Sie unter [Bereitstellungsrezepte](create-custom-deploy.md).

## Bedingungslogik
<a name="cookbooks-101-basics-ruby-conditional"></a>

Mithilfe der Bedingungslogik von Ruby können Sie auch mehrere Ausführungsvarianten erstellen. Im folgenden Rezept wird die Logik `if-elsif-else` als Erweiterung des vorherigen Beispiels eingesetzt, um das Unterverzeichnis `/srv/www/shared` zu erstellen, sofern es sich um Debian- und Ubuntu-Systeme handelt. Auf allen anderen Systemen wird in der Test Kitchen-Ausgabe eine Fehlermeldung protokolliert.

```
if platform?("debian", "ubuntu")
  directory "/srv/www/shared" do
    mode 0755
    owner 'root'
    group 'root'
    recursive true
    action :create
  end
else
  log "Unsupported system"
end
```

**So führen Sie das Beispielrezept aus**

1. Falls die Instance noch aktiv ist, fahren Sie sie mit `kitchen destroy` herunter.

1. Ersetzen Sie den Code in `default.rb` durch den Beispiel-Code.

1. Bearbeiten Sie `.kitchen.yml` und fügen Sie das CentOS 6.4-System zur Liste der Plattformen hinzu. Der `platforms`-Abschnitt der Datei sieht nun aus wie folgt.

   ```
   ...
   platforms:
     - name: ubuntu-12.04
     - name: centos-6.4
   ...
   ```

1. Führen Sie `kitchen converge` aus, um eine Instance zu erstellen und die Rezepte für die einzelnen Plattformen in `.kitchen.yml` nacheinander auszuführen. 
**Anmerkung**  
Wenn nur eine Instance konvergiert werden soll, können Sie den Instance-Namen als Parameter hinzufügen. Um beispielsweise das Rezept nur auf der Ubuntu-Plattform zu konvergieren, führen Sie `kitchen converge default-ubuntu-1204` aus. Falls Sie die Namen der Plattformen vergessen haben, führen Sie einfach `kitchen list` aus.

Die Protokollmeldung im CentOS-Abschnitt der Test Kitchen-Ausgabe sieht in etwa folgendermaßen aus:

```
...
Converging 1 resources
Recipe: createdir::default
* log[Unsupported system] action write[2014-06-23T19:10:30+00:00] INFO: Processing log[Unsupported system] action write (createdir::default line 12)
[2014-06-23T19:10:30+00:00] INFO: Unsupported system
       
[2014-06-23T19:10:30+00:00] INFO: Chef Run complete in 0.004972162 seconds
```

Nun können Sie sich an den Instances anmelden und prüfen, ob die Verzeichnisse erstellt wurden. Allerdings können Sie hier nicht einfach `kitchen login` ausführen. Sie müssen unter Angabe des Plattformnamens die Instance angeben, z. B. `kitchen login default-ubuntu-1204`. 

**Anmerkung**  
Sofern ein Test Kitchen-Befehl den Instance-Namen übernimmt, müssen Sie nicht den vollständigen Namen eingeben. Test Kitchen behandelt den Instance-Namen als regulären Ruby-Ausdruck, daher müssen nur genügend Zeichen eingegeben werden, um einen eindeutigen Treffer zu finden. Beispielsweise können Sie durch Ausführen von `kitchen converge ub` nur die Ubuntu-Instance konvergieren oder sich durch Ausführen von `kitchen login 64` an der CentOS-Instance anmelden.

Möglicherweise stellen Sie sich jetzt die Frage, woher das Rezept wissen kann, auf welcher Plattform es ausgeführt wird. Chef führt das Tool [Ohai](https://docs.chef.io/ohai.html) bei jeder Ausführung aus und erfasst so Systemdaten, darunter auch die Plattform. Diese Daten werden als Attribute in einer Struktur mit der Bezeichnung *Knotenobjekt* dargestellt. Mit der `platform?`-Methode von Chef werden die in Klammern gesetzten Systeme mit den Ohai-Plattformwerten verglichen. Bei einer Übereinstimmung wird der Wert "true" zurückgegeben.

Sie können den Wert eines Knotenattributs mit `node['attribute_name']` direkt im Code referenzieren. Der Plattformwert wird beispielsweise mit `node['platform']` angegeben. Sie könnten z. B. das vorherige Beispiel wie folgt schreiben.

```
if node[:platform] == 'debian' or node[:platform] == 'ubuntu'
  directory "/srv/www/shared" do
    mode 0755
    owner 'root'
    group 'root'
    recursive true
    action :create
  end
else
  log "Unsupported system"
end
```

Mit der Einbindung der Bedingungslogik in ein Rezept wird häufig die Tatsache berücksichtigt, dass verschiedene Linux-Familien gelegentlich unterschiedliche Namen für Pakete, Verzeichnisse etc. verwenden. Beispielsweise lautet der Apache-Paketname auf CentOS-Systemen `httpd` und auf Ubuntu-Systemen `apache2`.

Falls Sie nur eine andere Zeichenfolge für verschiedene Systeme benötigen, ist die [http://docs.chef.io/dsl_recipe.html#value-for-platform](http://docs.chef.io/dsl_recipe.html#value-for-platform)-Methode von Chef eine einfachere Lösung als `if-elsif-else`. Mit dem folgenden Rezept wird das Verzeichnis `/srv/www/shared` auf CentOS-Systemen, das Verzeichnis `/srv/www/data` auf Ubuntu-Systemen und das Verzeichnis `/srv/www/config` auf allen anderen Systemen erstellt.

```
data_dir = value_for_platform(
  "centos" => { "default" => "/srv/www/shared" },
  "ubuntu" => { "default" => "/srv/www/data" },
  "default" => "/srv/www/config"
)
directory data_dir do
  mode 0755
  owner 'root'
  group 'root'
  recursive true
  action :create
end
```

`value_for_platform` weist den entsprechenden Pfad für `data_dir` zu und die `directory`-Ressource nutzt diesen Wert für die Verzeichniserstellung.

**So führen Sie das Beispielrezept aus**

1. Falls die Instance noch aktiv ist, fahren Sie sie mit `kitchen destroy` herunter.

1. Ersetzen Sie den Code in `default.rb` durch den Beispiel-Code.

1. Führen Sie `kitchen converge` aus und melden Sie sich anschließend an den einzelnen Instances an, um zu prüfen, ob die entsprechenden Verzeichnisse vorhanden sind.