

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.

# Führen Sie Amazon Redshift SQL-Abfragen mithilfe von Terraform aus
<a name="execute-redshift-sql-queries-using-terraform"></a>

*Sylvia Qi und Aditya Ambati, Amazon Web Services*

## Zusammenfassung
<a name="execute-redshift-sql-queries-using-terraform-summary"></a>

Die Verwendung von Infrastructure as Code (IaC) für die Bereitstellung und Verwaltung von Amazon Redshift ist in diesem Bereich weit verbreitet. DevOps IaC erleichtert die Bereitstellung und Konfiguration verschiedener Amazon Redshift Redshift-Ressourcen wie Cluster, Snapshots und Parametergruppen. IaC erstreckt sich jedoch nicht auf die Verwaltung von Datenbankressourcen wie Tabellen, Schemas, Ansichten und gespeicherten Prozeduren. Diese Datenbankelemente werden über SQL-Abfragen verwaltet und nicht direkt von IaC-Tools unterstützt. Obwohl es Lösungen und Tools für die Verwaltung dieser Ressourcen gibt, ziehen Sie es möglicherweise vor, keine zusätzlichen Tools in Ihren Technologie-Stack aufzunehmen.

Dieses Muster beschreibt eine Methode, die Terraform verwendet, um Amazon Redshift Redshift-Datenbankressourcen wie Tabellen, Schemas, Ansichten und gespeicherte Prozeduren bereitzustellen. Das Muster unterscheidet zwischen zwei Arten von SQL-Abfragen:
+ **Nicht wiederholbare Abfragen** — Diese Abfragen werden einmal während der ersten Amazon Redshift Redshift-Bereitstellung ausgeführt, um die wesentlichen Datenbankkomponenten einzurichten. 
+ **Wiederholbare Abfragen — Diese Abfragen** sind unveränderlich und können erneut ausgeführt werden, ohne die Datenbank zu beeinträchtigen. Die Lösung verwendet Terraform, um Änderungen an wiederholbaren Abfragen zu überwachen und sie entsprechend anzuwenden.

[Weitere Informationen finden Sie unter *Exemplarische Vorgehensweise zur Lösung* unter Zusätzliche Informationen.](#execute-redshift-sql-queries-using-terraform-additional)

## Voraussetzungen und Einschränkungen
<a name="execute-redshift-sql-queries-using-terraform-prereqs"></a>

**Voraussetzungen**

Sie müssen über ein aktives System verfügen AWS-Konto und Folgendes auf Ihrem Bereitstellungscomputer installieren:
+ [AWS Command Line Interface](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) (AWS CLI)
+ Ein mit Amazon Redshift read/write Redshift-Berechtigungen konfiguriertes [AWS CLI Profil](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html)
+ [Terraform](https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli) Version 1.6.2 oder höher
+ [Python 3](https://www.python.org/downloads/)
+ [Boto3](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/quickstart.html)

**Einschränkungen**
+ Diese Lösung unterstützt eine einzelne Amazon Redshift Redshift-Datenbank, da Terraform bei der Clustererstellung nur die Erstellung einer Datenbank ermöglicht.
+ Dieses Muster beinhaltet keine Tests zur Validierung von Änderungen an den wiederholbaren Abfragen, bevor sie angewendet werden. Wir empfehlen, solche Tests zu integrieren, um die Zuverlässigkeit zu erhöhen.
+ Zur Veranschaulichung der Lösung enthält dieses Muster eine `redshift.tf` Beispieldatei, die eine lokale Terraform-Statusdatei verwendet. Für Produktionsumgebungen empfehlen wir jedoch dringend, eine Remote-Statusdatei mit einem Sperrmechanismus zu verwenden, um die Stabilität und Zusammenarbeit zu verbessern.
+ Einige AWS-Services sind nicht in allen verfügbar AWS-Regionen. Informationen zur Verfügbarkeit in den einzelnen Regionen finden Sie [AWS-Services unter Nach Regionen](https://aws.amazon.com/about-aws/global-infrastructure/regional-product-services/). Informationen zu bestimmten Endpunkten finden Sie unter [Dienstendpunkte und Kontingente](https://docs.aws.amazon.com/general/latest/gr/aws-service-information.html). Wählen Sie dort den Link für den Dienst aus.

**Produktversionen**

Diese Lösung wurde auf [Amazon Redshift Patch 179](https://docs.aws.amazon.com/redshift/latest/mgmt/cluster-versions.html#cluster-version-179) entwickelt und getestet.

**Code-Repository**

Der Code für dieses Muster ist im Repository GitHub [amazon-redshift-sql-deploy-terraform](https://github.com/aws-samples/amazon-redshift-sql-deploy-terraform) verfügbar.

## Architektur
<a name="execute-redshift-sql-queries-using-terraform-architecture"></a>

Das folgende Diagramm zeigt, wie Terraform die Amazon Redshift Redshift-Datenbankressourcen verwaltet, indem es sowohl nicht wiederholbare als auch wiederholbare SQL-Abfragen verarbeitet.

![\[Prozess für Terraform zur Verwaltung von Amazon Redshift Redshift-Datenbankressourcen mithilfe von SQL-Abfragen.\]](http://docs.aws.amazon.com/de_de/prescriptive-guidance/latest/patterns/images/pattern-img/0f4467ac-761b-4b6b-a32f-e18a2ca2245d/images/3b6ff9e8-e3d1-48ed-9fa1-4b14f7d3d65b.png)


Das Diagramm zeigt die folgenden Schritte:

1. Terraform wendet während der ersten Bereitstellung des Amazon Redshift Redshift-Clusters nicht wiederholbare SQL-Abfragen an.

1. Der Entwickler überträgt Änderungen an den wiederholbaren SQL-Abfragen.

1. Terraform überwacht Änderungen in den wiederholbaren SQL-Abfragen.

1. Terraform wendet wiederholbare SQL-Abfragen auf die Amazon Redshift Redshift-Datenbank an.

Die durch dieses Muster bereitgestellte Lösung basiert auf dem [Terraform-Modul für Amazon](https://registry.terraform.io/modules/terraform-aws-modules/redshift/aws/latest) Redshift. Das Terraform-Modul stellt einen Amazon Redshift Redshift-Cluster und eine Datenbank bereit. Um das Modul zu verbessern, haben wir `terraform_data` Ressourcen verwendet, die ein benutzerdefiniertes Python-Skript aufrufen, um SQL-Abfragen mithilfe der Amazon Redshift [ExecuteStatement](https://docs.aws.amazon.com/redshift-data/latest/APIReference/API_ExecuteStatement.html)Redshift-API-Operation auszuführen. Infolgedessen kann das Modul Folgendes tun:
+ Stellen Sie eine beliebige Anzahl von Datenbankressourcen mithilfe von SQL-Abfragen bereit, nachdem die Datenbank bereitgestellt wurde.
+ Überwachen Sie kontinuierlich die wiederholbaren SQL-Abfragen auf Änderungen und wenden Sie diese Änderungen mithilfe von Terraform an.

[Weitere Informationen finden Sie unter *Exemplarische Vorgehensweise zur Lösung* unter Zusätzliche Informationen.](#execute-redshift-sql-queries-using-terraform-additional)

## Tools
<a name="execute-redshift-sql-queries-using-terraform-tools"></a>

**AWS-Services**
+ [Amazon Redshift](https://docs.aws.amazon.com/redshift/latest/mgmt/welcome.html) ist ein vollständig verwalteter Data-Warehouse-Service im Petabyte-Bereich in der. AWS Cloud

**Andere Tools**
+ [Terraform](https://www.terraform.io/) ist ein IaC-Tool (Infrastructure as Code) HashiCorp , mit dem Sie Cloud- und lokale Ressourcen erstellen und verwalten können.
+ [Python](https://www.python.org/) ist eine Allzweck-Programmiersprache, die in diesem Muster zur Ausführung von SQL-Abfragen verwendet wird. 

## Best Practices
<a name="execute-redshift-sql-queries-using-terraform-best-practices"></a>
+ [Bewährte Methoden für Amazon Redshift](https://docs.aws.amazon.com/redshift/latest/dg/best-practices.html)
+ [Verwenden der Amazon Redshift Data API zur Interaktion mit Amazon Redshift Redshift-Clustern](https://aws.amazon.com/blogs/big-data/using-the-amazon-redshift-data-api-to-interact-with-amazon-redshift-clusters/)

## Epen
<a name="execute-redshift-sql-queries-using-terraform-epics"></a>

### Stellen Sie die Lösung mit Terraform bereit
<a name="deploy-the-solution-using-terraform"></a>


| Aufgabe | Description | Erforderliche Fähigkeiten | 
| --- | --- | --- | 
| **Klonen Sie das Repository.** | Verwenden Sie den folgenden Befehl, um das Git-Repository zu klonen, das den Terraform-Code für die Bereitstellung eines Amazon Redshift Redshift-Clusters enthält.<pre>git clone https://github.com/aws-samples/amazon-redshift-sql-deploy-terraform.git</pre> | DevOps Ingenieur | 
| **Aktualisieren Sie die Terraform-Variablen.** | Um die Amazon Redshift Redshift-Cluster-Bereitstellung an Ihre spezifischen Anforderungen anzupassen, aktualisieren Sie die folgenden Parameter in der `terraform.tfvars` Datei.<pre>region                    = "<AWS_REGION>"<br />cluster_identifier        = "<REDSHIFT_CLUSTER_IDENTIFIER>"<br />node_type                 = "<REDSHIFT_NODE_TYPE>"<br />number_of_nodes           = "<REDSHIFT_NODE_COUNT>"<br />database_name             = "<REDSHIFT_DB_NAME>"<br />subnet_ids                = "<REDSHIFT_SUBNET_IDS>"<br />vpc_security_group_ids    = "<REDSHIFT_SECURITY_GROUP_IDS>"<br />run_nonrepeatable_queries = true<br />run_repeatable_queries    = true<br />sql_path_bootstrap        = "<BOOTSTRAP_SQLS_PATH>"<br />sql_path_nonrepeatable    = "<NON-REPEATABLE_SQLS_PATH>"<br />sql_path_repeatable       = "<REPEATABLE_SQLS_PATH>"<br />sql_path_finalize         = "<FINALIZE_SQLS_PATH>"<br />create_random_password    = false<br />master_username           = "<REDSHIFT_MASTER_USERNAME>"</pre> | DevOps Ingenieur | 
| Stellen Sie die Ressourcen mithilfe von Terraform bereit. | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/de_de/prescriptive-guidance/latest/patterns/execute-redshift-sql-queries-using-terraform.html) | DevOps Ingenieur | 
| (Optional) Führen Sie zusätzliche SQL-Abfragen aus. | Das Beispiel-Repository bietet mehrere SQL-Abfragen für Demo-Zwecke. Um Ihre eigenen SQL-Abfragen auszuführen, fügen Sie sie den folgenden Ordnern hinzu:`/bootstrap` `/nonrepeatable` `/repeatable` `/finalize` |  | 

### Überwachen Sie die Ausführung von SQL-Anweisungen
<a name="monitor-the-execution-of-sql-statements"></a>


| Aufgabe | Description | Erforderliche Fähigkeiten | 
| --- | --- | --- | 
| Überwachen Sie die Bereitstellung von SQL-Anweisungen. | Sie können die Ergebnisse der SQL-Ausführungen in einem Amazon Redshift Redshift-Cluster überwachen. Beispiele für Ausgaben, die eine fehlgeschlagene und eine erfolgreiche SQL-Ausführung zeigen, finden Sie unter *Beispiel-SQL-Anweisungen* unter [Zusätzliche](#execute-redshift-sql-queries-using-terraform-additional) Informationen.  | DBA, Ingenieur DevOps  | 
| Bereinigen Sie die Ressourcen. | Führen Sie den folgenden Befehl aus, um alle von Terraform bereitgestellten Ressourcen zu löschen.<pre>terraform destroy</pre> | DevOps Ingenieur | 

### Validieren Sie die Ergebnisse
<a name="validate-the-results"></a>


| Aufgabe | Description | Erforderliche Fähigkeiten | 
| --- | --- | --- | 
| Überprüfen Sie die Daten im Amazon Redshift Redshift-Cluster. | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/de_de/prescriptive-guidance/latest/patterns/execute-redshift-sql-queries-using-terraform.html) | DBA, AWS DevOps | 

## Zugehörige Ressourcen
<a name="execute-redshift-sql-queries-using-terraform-resources"></a>

**AWS Dokumentation**
+ [Von Amazon Redshift bereitgestellte Cluster](https://docs.aws.amazon.com/redshift/latest/mgmt/working-with-clusters.html)
+ [Behebung von Problemen mit der Amazon Redshift Data API](https://docs.aws.amazon.com/redshift/latest/mgmt/data-api-troubleshooting.html)

**Sonstige Ressourcen**
+ [Befehl: apply](https://developer.hashicorp.com/terraform/cli/commands/apply) (Terraform-Dokumentation)

## Zusätzliche Informationen
<a name="execute-redshift-sql-queries-using-terraform-additional"></a>

**Exemplarische Vorgehensweise zur Lösung**

Um die Lösung verwenden zu können, müssen Sie Ihre Amazon Redshift SQL-Abfragen auf eine bestimmte Weise organisieren. Alle SQL-Abfragen müssen in Dateien mit einer `.sql` Erweiterung gespeichert werden.

In dem mit diesem Muster bereitgestellten Codebeispiel sind die SQL-Abfragen in der folgenden Ordnerstruktur organisiert. Sie können den Code (`sql-queries.tf`und`sql-queries.py`) so ändern, dass er mit jeder Struktur funktioniert, die Ihrem individuellen Anwendungsfall entspricht.

```
/bootstrap
     |- Any # of files
     |- Any # of sub-folders
/nonrepeatable
     |- Any # of files
     |- Any # of sub-folders
/repeatable
     /udf
          |- Any # of files
          |- Any # of sub-folders
     /table
          |- Any # of files
          |- Any # of sub-folders
     /view
          |- Any # of files
          |- Any # of sub-folders
     /stored-procedure
          |- Any # of files
          |- Any # of sub-folders
/finalize
     |- Any # of files
     |- Any # of sub-folders
```

Angesichts der obigen Ordnerstruktur führt Terraform während der Bereitstellung von Amazon Redshift Redshift-Clustern die Abfragen in der folgenden Reihenfolge aus:

1. `/bootstrap`

1. `/nonrepeatable`

1. `/repeatable`

1. `/finalize`

Der `/repeatable` Ordner enthält vier Unterordner:`/udf`,, und. `/table` `/view` `/stored-procedure` Diese Unterordner geben die Reihenfolge an, in der Terraform die SQL-Abfragen ausführt.

Das Python-Skript, das die SQL-Abfragen ausführt, ist`sql-queries.py`. Zunächst liest das Skript alle Dateien und Unterordner eines bestimmten Quellverzeichnisses, z. B. den `sql_path_bootstrap` Parameter. Anschließend führt das Skript die Abfragen aus, indem es den Amazon Redshift [ExecuteStatement](https://docs.aws.amazon.com/redshift-data/latest/APIReference/API_ExecuteStatement.html)Redshift-API-Vorgang aufruft. Möglicherweise haben Sie eine oder mehrere SQL-Abfragen in einer Datei. Der folgende Codeausschnitt zeigt die Python-Funktion, die in einer Datei gespeicherte SQL-Anweisungen für einen Amazon Redshift Redshift-Cluster ausführt.

```
def execute_sql_statement(filename, cluster_id, db_name, secret_arn, aws_region):
    """Execute SQL statements in a file"""
    redshift_client = boto3.client(
        'redshift-data', region_name=aws_region)
    contents = get_contents_from_file(filename),
    response = redshift_client.execute_statement(
        Sql=contents[0],
        ClusterIdentifier=cluster_id,
        Database=db_name,
        WithEvent=True,
        StatementName=filename,
        SecretArn=secret_arn
    )
    ...
```

Das Terraform-Skript `sql-queries.tf` erstellt die terraform\$1data-Ressourcen, die das Skript [aufrufen](https://developer.hashicorp.com/terraform/language/resources/terraform-data). `sql-queries.py` Für jeden der vier Ordner gibt es eine `terraform_data` Ressource:,, und. `/bootstrap` `/nonrepeatable` `/repeatable` `/finalize` Der folgende Codeausschnitt zeigt die `terraform_data` Ressource, die die SQL-Abfragen im `/bootstrap` Ordner ausführt.

```
locals {
  program               = "${path.module}/sql-queries.py"
  redshift_cluster_name = try(aws_redshift_cluster.this[0].id, null)
}

resource "terraform_data" "run_bootstrap_queries" {
  count      = var.create && var.run_nonrepeatable_queries && (var.sql_path_bootstrap != "") && (var.snapshot_identifier == null) ? 1 : 0
  depends_on = [aws_redshift_cluster.this[0]]

  provisioner "local-exec" {
    command = "python3 ${local.program} ${var.sql_path_bootstrap} ${local.redshift_cluster_name} ${var.database_name} ${var.redshift_secret_arn} ${local.aws_region}"
  }
}
```

Mithilfe der folgenden Variablen können Sie steuern, ob diese Abfragen ausgeführt werden sollen. Wenn Sie keine Abfragen in`sql_path_bootstrap`,, oder ausführen möchten `sql_path_nonrepeatable` `sql_path_repeatable``sql_path_finalize`, legen Sie deren Werte auf fest`""`.

```
  run_nonrepeatable_queries = true
  run_repeatable_queries    = true
  sql_path_bootstrap        = "src/redshift/bootstrap"
  sql_path_nonrepeatable    = "src/redshift/nonrepeatable"
  sql_path_repeatable       = "src/redshift/repeatable"
  sql_path_finalize         = "src/redshift/finalize"
```

Bei der Ausführung berücksichtigt Terraform die `terraform_data` Ressource`terraform apply`, die nach Abschluss des Skripts hinzugefügt wurde, unabhängig von den Ergebnissen des Skripts. Wenn einige SQL-Abfragen fehlgeschlagen sind und Sie sie erneut ausführen möchten, können Sie die Ressource manuell aus dem Terraform-Status entfernen und erneut ausführen. `terraform apply` Mit dem folgenden Befehl wird die `run_bootstrap_queries` Ressource beispielsweise aus dem Terraform-Status entfernt.

`terraform state rm module.redshift.terraform_data.run_bootstrap_queries[0]`

Das folgende Codebeispiel zeigt, wie die `run_repeatable_queries` Ressource Änderungen im `repeatable` Ordner mithilfe des [sha256-Hashs](https://developer.hashicorp.com/terraform/language/functions/sha256) überwacht. Wenn eine Datei innerhalb des Ordners aktualisiert wird, markiert Terraform das gesamte Verzeichnis für ein Update. Dann führt Terraform die Abfragen im Verzeichnis im nächsten Schritt erneut aus. `terraform apply`

```
resource "terraform_data" "run_repeatable_queries" {
  count      = var.create_redshift && var.run_repeatable_queries && (var.sql_path_repeatable != "") ? 1 : 0
  depends_on = [terraform_data.run_nonrepeatable_queries]

  # Continuously monitor and apply changes in the repeatable folder
  triggers_replace = {
    dir_sha256 = sha256(join("", [for f in fileset("${var.sql_path_repeatable}", "**") : filesha256("${var.sql_path_repeatable}/${f}")]))
  }

  provisioner "local-exec" {
    command = "python3 ${local.sql_queries} ${var.sql_path_repeatable} ${local.redshift_cluster_name} ${var.database_name} ${var.redshift_secret_arn}"
  }
}
```

Um den Code zu verfeinern, können Sie einen Mechanismus implementieren, mit dem Änderungen nur an den Dateien erkannt und angewendet werden, die innerhalb des `repeatable` Ordners aktualisiert wurden, anstatt Änderungen wahllos auf alle Dateien anzuwenden.

**Beispiel für SQL-Anweisungen**

Die folgende Ausgabe zeigt eine fehlgeschlagene SQL-Ausführung zusammen mit einer Fehlermeldung.

```
module.redshift.terraform_data.run_nonrepeatable_queries[0] (local-exec): Executing: ["/bin/sh" "-c" "python3 modules/redshift/sql-queries.py src/redshift/nonrepeatable testcluster-1 db1 arn:aws:secretsmanager:us-east-1:XXXXXXXXXXXX:secret:/redshift/master_user/password-8RapGH us-east-1"]
module.redshift.terraform_data.run_nonrepeatable_queries[0] (local-exec): -------------------------------------------------------------------
module.redshift.terraform_data.run_nonrepeatable_queries[0] (local-exec): src/redshift/nonrepeatable/table/admin/admin.application_family.sql
module.redshift.terraform_data.run_nonrepeatable_queries[0] (local-exec): -------------------------------------------------------------------
module.redshift.terraform_data.run_nonrepeatable_queries[0] (local-exec): Status: FAILED
module.redshift.terraform_data.run_nonrepeatable_queries[0] (local-exec): SQL execution failed.
module.redshift.terraform_data.run_nonrepeatable_queries[0] (local-exec): Error message: ERROR: syntax error at or near ")"
module.redshift.terraform_data.run_nonrepeatable_queries[0] (local-exec):   Position: 244
module.redshift.terraform_data.run_nonrepeatable_queries[0]: Creation complete after 3s [id=ee50ba6c-11ae-5b64-7e2f-86fd8caa8b76]
```

Die folgende Ausgabe zeigt eine erfolgreiche SQL-Ausführung.

```
module.redshift.terraform_data.run_bootstrap_queries[0]: Provisioning with 'local-exec'...
module.redshift.terraform_data.run_bootstrap_queries[0] (local-exec): Executing: ["/bin/sh" "-c" "python3 modules/redshift/sql-queries.py src/redshift/bootstrap testcluster-1 db1 arn:aws:secretsmanager:us-east-1:XXXXXXXXXXXX:secret:/redshift/master_user/password-8RapGH us-east-1"]
module.redshift.terraform_data.run_bootstrap_queries[0] (local-exec): -------------------------------------------------------------------
module.redshift.terraform_data.run_bootstrap_queries[0] (local-exec): src/redshift/bootstrap/db.sql
module.redshift.terraform_data.run_bootstrap_queries[0] (local-exec): -------------------------------------------------------------------
module.redshift.terraform_data.run_bootstrap_queries[0] (local-exec): Status: FINISHED
module.redshift.terraform_data.run_bootstrap_queries[0] (local-exec): SQL execution successful.
module.redshift.terraform_data.run_bootstrap_queries[0]: Creation complete after 2s [id=d565ef6d-be86-8afd-8e90-111e5ea4a1be]
```