

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

# Exécutez des requêtes SQL Amazon Redshift à l'aide de Terraform
<a name="execute-redshift-sql-queries-using-terraform"></a>

*Sylvia Qi et Aditya Ambati, Amazon Web Services*

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

L'utilisation de l'infrastructure en tant que code (IaC) pour le déploiement et la gestion d'Amazon Redshift est une pratique courante au sein de l'entreprise. DevOps IaC facilite le déploiement et la configuration de diverses ressources Amazon Redshift, telles que les clusters, les instantanés et les groupes de paramètres. Cependant, IaC ne s'étend pas à la gestion des ressources de base de données telles que les tables, les schémas, les vues et les procédures stockées. Ces éléments de base de données sont gérés par le biais de requêtes SQL et ne sont pas directement pris en charge par les outils IaC. Bien qu'il existe des solutions et des outils pour gérer ces ressources, vous préférerez peut-être ne pas ajouter d'outils supplémentaires à votre infrastructure technologique.

Ce modèle décrit une méthodologie qui utilise Terraform pour déployer les ressources de base de données Amazon Redshift, notamment les tables, les schémas, les vues et les procédures stockées. Le modèle distingue deux types de requêtes SQL :
+ **Requêtes non répétables** : ces requêtes sont exécutées une seule fois lors du déploiement initial d'Amazon Redshift afin d'établir les composants essentiels de la base de données. 
+ **Requêtes répétables** : ces requêtes sont immuables et peuvent être réexécutées sans affecter la base de données. La solution utilise Terraform pour surveiller les modifications des requêtes répétables et les appliquer en conséquence.

Pour plus de détails, consultez la section Présentation *de la solution* dans [Informations supplémentaires](#execute-redshift-sql-queries-using-terraform-additional).

## Conditions préalables et limitations
<a name="execute-redshift-sql-queries-using-terraform-prereqs"></a>

**Conditions préalables**

Vous devez avoir un système actif Compte AWS et installer ce qui suit sur votre machine de déploiement :
+ [AWS Command Line Interface](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) (AWS CLI)
+ Un [AWS CLI profil](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html) configuré avec les autorisations Amazon Redshift read/write 
+ [Terraform](https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli) version 1.6.2 ou ultérieure
+ [Python 3](https://www.python.org/downloads/)
+ [Boto3](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/quickstart.html)

**Limites**
+ Cette solution prend en charge une seule base de données Amazon Redshift car Terraform n'autorise la création d'une seule base de données lors de la création du cluster.
+ Ce modèle n'inclut pas de tests pour valider les modifications apportées aux requêtes répétables avant de les appliquer. Nous vous recommandons d'intégrer de tels tests pour une fiabilité accrue.
+ Pour illustrer la solution, ce modèle fournit un exemple de `redshift.tf` fichier qui utilise un fichier d'état Terraform local. Toutefois, pour les environnements de production, nous vous recommandons vivement d'utiliser un fichier d'état distant doté d'un mécanisme de verrouillage pour améliorer la stabilité et la collaboration.
+ Certains Services AWS ne sont pas disponibles du tout Régions AWS. Pour connaître la disponibilité par région, voir [Services AWS par région](https://aws.amazon.com/about-aws/global-infrastructure/regional-product-services/). Pour des points de terminaison spécifiques, consultez [Points de terminaison de service et quotas](https://docs.aws.amazon.com/general/latest/gr/aws-service-information.html), puis choisissez le lien correspondant au service.

**Versions du produit**

Cette solution est développée et testée sur le [correctif 179 d'Amazon Redshift](https://docs.aws.amazon.com/redshift/latest/mgmt/cluster-versions.html#cluster-version-179).

**Référentiel de code**

Le code de ce modèle est disponible dans le référentiel GitHub [amazon-redshift-sql-deploy-terraform](https://github.com/aws-samples/amazon-redshift-sql-deploy-terraform).

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

Le schéma suivant illustre comment Terraform gère les ressources de base de données Amazon Redshift en gérant à la fois les requêtes SQL non répétables et répétables.

![\[Processus permettant à Terraform de gérer les ressources de base de données Amazon Redshift à l'aide de requêtes SQL.\]](http://docs.aws.amazon.com/fr_fr/prescriptive-guidance/latest/patterns/images/pattern-img/0f4467ac-761b-4b6b-a32f-e18a2ca2245d/images/3b6ff9e8-e3d1-48ed-9fa1-4b14f7d3d65b.png)


Le schéma montre les étapes suivantes :

1. Terraform applique des requêtes SQL non répétables lors du déploiement initial du cluster Amazon Redshift.

1. Le développeur valide les modifications apportées aux requêtes SQL répétables.

1. Terraform surveille les modifications apportées aux requêtes SQL répétables.

1. Terraform applique des requêtes SQL répétables à la base de données Amazon Redshift.

La solution fournie par ce modèle est basée sur le [module Terraform pour Amazon Redshift](https://registry.terraform.io/modules/terraform-aws-modules/redshift/aws/latest). Le module Terraform fournit un cluster et une base de données Amazon Redshift. Pour améliorer le module, nous avons utilisé `terraform_data` des ressources qui invoquent un script Python personnalisé pour exécuter des requêtes SQL à l'aide de l'opération d'API Amazon [ExecuteStatement](https://docs.aws.amazon.com/redshift-data/latest/APIReference/API_ExecuteStatement.html)Redshift. Par conséquent, le module peut effectuer les opérations suivantes :
+ Déployez autant de ressources de base de données que vous le souhaitez à l'aide de requêtes SQL après le provisionnement de la base de données.
+ Surveillez en permanence les modifications apportées aux requêtes SQL répétables et appliquez ces modifications à l'aide de Terraform.

Pour plus de détails, consultez la section Présentation *de la solution* dans [Informations supplémentaires](#execute-redshift-sql-queries-using-terraform-additional).

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

**Services AWS**
+ [Amazon Redshift](https://docs.aws.amazon.com/redshift/latest/mgmt/welcome.html) est un service d'entrepôt de données entièrement géré à l'échelle du pétaoctet situé dans le. AWS Cloud

**Autres outils**
+ [Terraform](https://www.terraform.io/) est un outil d'infrastructure en tant que code (IaC) HashiCorp qui vous aide à créer et à gérer des ressources cloud et sur site.
+ [Python](https://www.python.org/) est un langage de programmation polyvalent utilisé dans ce modèle pour exécuter des requêtes SQL. 

## Bonnes pratiques
<a name="execute-redshift-sql-queries-using-terraform-best-practices"></a>
+ [Bonnes pratiques relatives à Amazon Redshift](https://docs.aws.amazon.com/redshift/latest/dg/best-practices.html)
+ [Utilisation de l'API Amazon Redshift Data pour interagir avec les clusters Amazon Redshift](https://aws.amazon.com/blogs/big-data/using-the-amazon-redshift-data-api-to-interact-with-amazon-redshift-clusters/)

## Épopées
<a name="execute-redshift-sql-queries-using-terraform-epics"></a>

### Déployez la solution à l'aide de Terraform
<a name="deploy-the-solution-using-terraform"></a>


| Sous-tâche | Description | Compétences requises | 
| --- | --- | --- | 
| **Clonez le dépôt.** | Pour cloner le référentiel Git contenant le code Terraform pour le provisionnement d'un cluster Amazon Redshift, utilisez la commande suivante.<pre>git clone https://github.com/aws-samples/amazon-redshift-sql-deploy-terraform.git</pre> | DevOps ingénieur | 
| **Mettez à jour les variables Terraform.** | Pour personnaliser le déploiement du cluster Amazon Redshift en fonction de vos besoins spécifiques, mettez à jour les paramètres suivants dans le `terraform.tfvars` fichier.<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 ingénieur | 
| Déployez les ressources à l'aide de Terraform. | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/fr_fr/prescriptive-guidance/latest/patterns/execute-redshift-sql-queries-using-terraform.html) | DevOps ingénieur | 
| (Facultatif) Exécutez des requêtes SQL supplémentaires. | Le référentiel d'exemples fournit plusieurs requêtes SQL à des fins de démonstration. Pour exécuter vos propres requêtes SQL, ajoutez-les dans les dossiers suivants :`/bootstrap` `/nonrepeatable` `/repeatable` `/finalize` |  | 

### Surveiller l'exécution des instructions SQL
<a name="monitor-the-execution-of-sql-statements"></a>


| Sous-tâche | Description | Compétences requises | 
| --- | --- | --- | 
| Surveillez le déploiement des instructions SQL. | Vous pouvez surveiller les résultats des exécutions SQL sur un cluster Amazon Redshift. Pour obtenir des exemples de résultats illustrant un échec ou une exécution réussie de SQL, reportez-vous à la section *Exemples d'instructions SQL* dans [Informations supplémentaires](#execute-redshift-sql-queries-using-terraform-additional).  | DBA, ingénieur DevOps  | 
| nettoyer les ressources. | Pour supprimer toutes les ressources déployées par Terraform, exécutez la commande suivante.<pre>terraform destroy</pre> | DevOps ingénieur | 

### Valider les résultats
<a name="validate-the-results"></a>


| Sous-tâche | Description | Compétences requises | 
| --- | --- | --- | 
| Validez les données dans le cluster Amazon Redshift. | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/fr_fr/prescriptive-guidance/latest/patterns/execute-redshift-sql-queries-using-terraform.html) | ADMINISTRATEUR DE BASES DE DONNÉES, AWS DevOps | 

## Ressources connexes
<a name="execute-redshift-sql-queries-using-terraform-resources"></a>

**AWS documentation**
+ [Clusters provisionnés par Amazon Redshift](https://docs.aws.amazon.com/redshift/latest/mgmt/working-with-clusters.html)
+ [Résolution des problèmes liés à l'API Amazon Redshift Data](https://docs.aws.amazon.com/redshift/latest/mgmt/data-api-troubleshooting.html)

**Autres ressources**
+ [Commande : appliquer](https://developer.hashicorp.com/terraform/cli/commands/apply) (documentation Terraform)

## Informations supplémentaires
<a name="execute-redshift-sql-queries-using-terraform-additional"></a>

**Présentation de la solution**

Pour utiliser la solution, vous devez organiser vos requêtes SQL Amazon Redshift de manière spécifique. Toutes les requêtes SQL doivent être stockées dans des fichiers dotés d'une `.sql` extension.

Dans l'exemple de code fourni avec ce modèle, les requêtes SQL sont organisées dans la structure de dossiers suivante. Vous pouvez modifier le code (`sql-queries.tf`et`sql-queries.py`) pour qu'il fonctionne avec n'importe quelle structure adaptée à votre cas d'utilisation unique.

```
/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
```

Compte tenu de la structure de dossiers précédente, lors du déploiement du cluster Amazon Redshift, Terraform exécute les requêtes dans l'ordre suivant :

1. `/bootstrap`

1. `/nonrepeatable`

1. `/repeatable`

1. `/finalize`

Le `/repeatable` dossier contient quatre sous-dossiers :`/udf`, `/table``/view`, et`/stored-procedure`. Ces sous-dossiers indiquent l'ordre dans lequel Terraform exécute les requêtes SQL.

Le script Python qui exécute les requêtes SQL est`sql-queries.py`. Tout d'abord, le script lit tous les fichiers et sous-dossiers d'un répertoire source spécifique, par exemple le `sql_path_bootstrap` paramètre. Le script exécute ensuite les requêtes en appelant l'opération d'API Amazon [ExecuteStatement](https://docs.aws.amazon.com/redshift-data/latest/APIReference/API_ExecuteStatement.html)Redshift. Un fichier contient peut-être une ou plusieurs requêtes SQL. L'extrait de code suivant montre la fonction Python qui exécute les instructions SQL stockées dans un fichier sur un cluster Amazon Redshift.

```
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
    )
    ...
```

Le script Terraform `sql-queries.tf` crée les ressources [terraform\$1data](https://developer.hashicorp.com/terraform/language/resources/terraform-data) qui appellent le script. `sql-queries.py` Il existe une `terraform_data` ressource pour chacun des quatre dossiers : `/bootstrap``/nonrepeatable`,`/repeatable`, et`/finalize`. L'extrait de code suivant montre la `terraform_data` ressource qui exécute les requêtes SQL dans le `/bootstrap` dossier.

```
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}"
  }
}
```

Vous pouvez contrôler l'exécution de ces requêtes à l'aide des variables suivantes. Si vous ne souhaitez pas exécuter de requêtes dans `sql_path_bootstrap``sql_path_nonrepeatable`, `sql_path_repeatable``sql_path_finalize`, ou définir leurs valeurs sur`""`.

```
  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"
```

Lorsque vous exécutez`terraform apply`, Terraform prend en compte la `terraform_data` ressource ajoutée une fois le script terminé, quels que soient les résultats du script. Si certaines requêtes SQL ont échoué et que vous souhaitez les exécuter à nouveau, vous pouvez supprimer manuellement la ressource de l'état Terraform et l'exécuter à nouveau. `terraform apply` Par exemple, la commande suivante supprime la `run_bootstrap_queries` ressource de l'état Terraform.

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

L'exemple de code suivant montre comment la `run_repeatable_queries` ressource surveille les modifications dans le `repeatable` dossier à l'aide du [hachage sha256](https://developer.hashicorp.com/terraform/language/functions/sha256). Si un fichier du dossier est mis à jour, Terraform marque l'ensemble du répertoire pour une mise à jour. Ensuite, Terraform exécute à nouveau les requêtes dans le répertoire lors de la suivante. `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}"
  }
}
```

Pour affiner le code, vous pouvez implémenter un mécanisme permettant de détecter et d'appliquer des modifications uniquement aux fichiers qui ont été mis à jour dans le `repeatable` dossier, plutôt que d'appliquer les modifications à tous les fichiers sans distinction.

**Exemples d'instructions SQL**

La sortie suivante montre un échec de l'exécution de SQL, ainsi qu'un message d'erreur.

```
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]
```

Le résultat suivant montre une exécution SQL réussie.

```
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]
```