

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

# Esegui le query SQL di Amazon Redshift utilizzando Terraform
<a name="execute-redshift-sql-queries-using-terraform"></a>

*Sylvia Qi e Aditya Ambati, Amazon Web Services*

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

L'uso dell'infrastruttura come codice (IaC) per la distribuzione e la gestione di Amazon Redshift è una pratica prevalente all'interno. DevOps IaC facilita l'implementazione e la configurazione di varie risorse Amazon Redshift, come cluster, snapshot e gruppi di parametri. Tuttavia, IaC non si estende alla gestione di risorse di database come tabelle, schemi, viste e stored procedure. Questi elementi del database sono gestiti tramite query SQL e non sono supportati direttamente dagli strumenti IaC. Sebbene esistano soluzioni e strumenti per la gestione di queste risorse, potresti preferire non introdurre strumenti aggiuntivi nel tuo stack tecnologico.

Questo modello delinea una metodologia che utilizza Terraform per distribuire le risorse del database Amazon Redshift, tra cui tabelle, schemi, viste e stored procedure. Il modello distingue tra due tipi di query SQL:
+ Query **non ripetibili: queste query** vengono eseguite una sola volta durante la distribuzione iniziale di Amazon Redshift per stabilire i componenti essenziali del database. 
+ Query **ripetibili: queste query** sono immutabili e possono essere rieseguite senza influire sul database. La soluzione utilizza Terraform per monitorare le modifiche nelle query ripetibili e applicarle di conseguenza.

[Per maggiori dettagli, consulta la *procedura dettagliata della soluzione* in Informazioni aggiuntive.](#execute-redshift-sql-queries-using-terraform-additional)

## Prerequisiti e limitazioni
<a name="execute-redshift-sql-queries-using-terraform-prereqs"></a>

**Prerequisiti**

È necessario disporre di un dispositivo attivo Account AWS e installare quanto segue sul computer di distribuzione:
+ [AWS Command Line Interface](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) (AWS CLI)
+ Un [AWS CLI profilo](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html) configurato con le autorizzazioni di Amazon Redshift read/write 
+ [Terraform versione 1.6.2](https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli) o successiva
+ [Python 3](https://www.python.org/downloads/)
+ [Boto3](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/quickstart.html)

**Limitazioni**
+ Questa soluzione supporta un singolo database Amazon Redshift perché Terraform consente la creazione di un solo database durante la creazione del cluster.
+ Questo modello non include test per convalidare le modifiche alle query ripetibili prima di applicarle. Si consiglia di incorporare tali test per una maggiore affidabilità.
+ Per illustrare la soluzione, questo modello fornisce un file di esempio che utilizza un `redshift.tf` file di stato Terraform locale. Tuttavia, per gli ambienti di produzione, si consiglia vivamente di utilizzare un file di stato remoto con un meccanismo di blocco per una maggiore stabilità e collaborazione.
+ Alcuni Servizi AWS non sono disponibili in tutti. Regioni AWS Per la disponibilità per regione, vedi [Servizi AWS per regione](https://aws.amazon.com/about-aws/global-infrastructure/regional-product-services/). Per endpoint specifici, consulta [Endpoints and quotas del servizio](https://docs.aws.amazon.com/general/latest/gr/aws-service-information.html) e scegli il link relativo al servizio.

**Versioni del prodotto**

Questa soluzione è stata sviluppata e testata sulla [patch 179 di Amazon Redshift](https://docs.aws.amazon.com/redshift/latest/mgmt/cluster-versions.html#cluster-version-179).

**Repository di codice**

Il codice per questo modello è disponibile nel repository 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>

Il diagramma seguente illustra come Terraform gestisce le risorse del database Amazon Redshift gestendo query SQL sia non ripetibili che ripetibili.

![\[Processo per Terraform per gestire le risorse del database Amazon Redshift utilizzando query SQL.\]](http://docs.aws.amazon.com/it_it/prescriptive-guidance/latest/patterns/images/pattern-img/0f4467ac-761b-4b6b-a32f-e18a2ca2245d/images/3b6ff9e8-e3d1-48ed-9fa1-4b14f7d3d65b.png)


Il diagramma mostra i seguenti passaggi:

1. Terraform applica query SQL non ripetibili durante la distribuzione iniziale del cluster Amazon Redshift.

1. Lo sviluppatore apporta modifiche alle query SQL ripetibili.

1. Terraform monitora le modifiche nelle query SQL ripetibili.

1. Terraform applica query SQL ripetibili al database Amazon Redshift.

La soluzione fornita da questo modello è costruita sulla base del [modulo Terraform per Amazon Redshift](https://registry.terraform.io/modules/terraform-aws-modules/redshift/aws/latest). Il modulo Terraform fornisce un cluster e un database Amazon Redshift. Per migliorare il modulo, abbiamo utilizzato `terraform_data` risorse, che richiamano uno script Python personalizzato per eseguire query SQL utilizzando l'operazione API Amazon Redshift. [ExecuteStatement](https://docs.aws.amazon.com/redshift-data/latest/APIReference/API_ExecuteStatement.html) Di conseguenza, il modulo può eseguire le seguenti operazioni:
+ Distribuisci un numero qualsiasi di risorse del database utilizzando le query SQL dopo il provisioning del database.
+ Monitora continuamente le modifiche nelle query SQL ripetibili e applica tali modifiche utilizzando Terraform.

[Per maggiori dettagli, consulta la *procedura dettagliata della soluzione* in Informazioni aggiuntive.](#execute-redshift-sql-queries-using-terraform-additional)

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

**Servizi AWS**
+ [Amazon Redshift](https://docs.aws.amazon.com/redshift/latest/mgmt/welcome.html) è un servizio di data warehouse su scala petabyte completamente gestito in. Cloud AWS

**Altri strumenti**
+ [Terraform](https://www.terraform.io/) è uno strumento di infrastruttura come codice (IaC) HashiCorp che ti aiuta a creare e gestire risorse cloud e locali.
+ [Python](https://www.python.org/) è un linguaggio di programmazione generico utilizzato in questo modello per eseguire query SQL. 

## Best practice
<a name="execute-redshift-sql-queries-using-terraform-best-practices"></a>
+ [Best practice di Amazon Redshift](https://docs.aws.amazon.com/redshift/latest/dg/best-practices.html)
+ [Utilizzo dell'API Amazon Redshift Data per interagire con i cluster Amazon Redshift](https://aws.amazon.com/blogs/big-data/using-the-amazon-redshift-data-api-to-interact-with-amazon-redshift-clusters/)

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

### Implementa la soluzione utilizzando Terraform
<a name="deploy-the-solution-using-terraform"></a>


| Operazione | Description | Competenze richieste | 
| --- | --- | --- | 
| **Clona il repository.** | Per clonare il repository Git contenente il codice Terraform per il provisioning di un cluster Amazon Redshift, usa il seguente comando.<pre>git clone https://github.com/aws-samples/amazon-redshift-sql-deploy-terraform.git</pre> | DevOps ingegnere | 
| **Aggiorna le variabili Terraform.** | Per personalizzare la distribuzione del cluster Amazon Redshift in base ai tuoi requisiti specifici, aggiorna i seguenti parametri nel `terraform.tfvars` file.<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 ingegnere | 
| Distribuisci le risorse utilizzando Terraform. | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/it_it/prescriptive-guidance/latest/patterns/execute-redshift-sql-queries-using-terraform.html) | DevOps ingegnere | 
| (Facoltativo) Esegui query SQL aggiuntive. | Il repository di esempio fornisce diverse query SQL a scopo dimostrativo. Per eseguire le tue query SQL, aggiungile alle seguenti cartelle:`/bootstrap` `/nonrepeatable` `/repeatable` `/finalize` |  | 

### Monitora l'esecuzione delle istruzioni SQL
<a name="monitor-the-execution-of-sql-statements"></a>


| Operazione | Description | Competenze richieste | 
| --- | --- | --- | 
| Monitora la distribuzione delle istruzioni SQL. | Puoi monitorare i risultati delle esecuzioni SQL su un cluster Amazon Redshift. Per esempi di output che mostrano un'esecuzione SQL non riuscita e riuscita, consulta *Esempi di istruzioni SQL in Informazioni* [aggiuntive](#execute-redshift-sql-queries-using-terraform-additional).  | DBA, ingegnere DevOps  | 
| Eliminare le risorse. | Per eliminare tutte le risorse distribuite da Terraform, esegui il seguente comando.<pre>terraform destroy</pre> | DevOps ingegnere | 

### Convalida i risultati
<a name="validate-the-results"></a>


| Operazione | Description | Competenze richieste | 
| --- | --- | --- | 
| Convalida i dati nel cluster Amazon Redshift. | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/it_it/prescriptive-guidance/latest/patterns/execute-redshift-sql-queries-using-terraform.html) | DBA, AWS DevOps | 

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

**AWS documentazione**
+ [Cluster forniti da Amazon Redshift](https://docs.aws.amazon.com/redshift/latest/mgmt/working-with-clusters.html)
+ [Risoluzione dei problemi per Amazon Redshift Data API](https://docs.aws.amazon.com/redshift/latest/mgmt/data-api-troubleshooting.html)

**Altre risorse**
+ [Comando: apply](https://developer.hashicorp.com/terraform/cli/commands/apply) (documentazione Terraform)

## Informazioni aggiuntive
<a name="execute-redshift-sql-queries-using-terraform-additional"></a>

**Procedura dettagliata della soluzione**

Per utilizzare la soluzione, è necessario organizzare le query SQL di Amazon Redshift in un modo specifico. Tutte le query SQL devono essere archiviate in file con estensione. `.sql`

Nell'esempio di codice fornito con questo modello, le query SQL sono organizzate nella seguente struttura di cartelle. È possibile modificare il codice (`sql-queries.tf`e`sql-queries.py`) per utilizzarlo con qualsiasi struttura adatta al proprio caso d'uso specifico.

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

Data la struttura delle cartelle precedente, durante la distribuzione del cluster Amazon Redshift, Terraform esegue le query nel seguente ordine:

1. `/bootstrap`

1. `/nonrepeatable`

1. `/repeatable`

1. `/finalize`

La `/repeatable` cartella contiene quattro sottocartelle:,, e. `/udf` `/table` `/view` `/stored-procedure` Queste sottocartelle indicano l'ordine in cui Terraform esegue le query SQL.

Lo script Python che esegue le query SQL è. `sql-queries.py` Innanzitutto, lo script legge tutti i file e le sottocartelle di una specifica directory di origine, ad esempio il parametro. `sql_path_bootstrap` Quindi lo script esegue le query richiamando l'operazione dell'API Amazon [ExecuteStatement](https://docs.aws.amazon.com/redshift-data/latest/APIReference/API_ExecuteStatement.html)Redshift. Potresti avere una o più query SQL in un file. Il seguente frammento di codice mostra la funzione Python che esegue istruzioni SQL archiviate in un file su 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
    )
    ...
```

[Lo script Terraform `sql-queries.tf` crea le risorse terraform\$1data che richiamano lo script.](https://developer.hashicorp.com/terraform/language/resources/terraform-data) `sql-queries.py` Esiste una `terraform_data` risorsa per ciascuna delle quattro cartelle:`/bootstrap`,, e. `/nonrepeatable` `/repeatable` `/finalize` Il seguente frammento di codice mostra la `terraform_data` risorsa che esegue le query SQL nella cartella. `/bootstrap`

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

È possibile controllare se eseguire queste query utilizzando le seguenti variabili. Se non desideri eseguire query in`sql_path_bootstrap`,, o `sql_path_nonrepeatable` `sql_path_repeatable``sql_path_finalize`, imposta i relativi valori su. `""`

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

Durante l'esecuzione`terraform apply`, Terraform considera la `terraform_data` risorsa aggiunta dopo il completamento dello script, indipendentemente dai risultati dello script. Se alcune query SQL hanno avuto esito negativo e desideri eseguirle nuovamente, puoi rimuovere manualmente la risorsa dallo stato Terraform ed eseguirle di nuovo. `terraform apply` Ad esempio, il comando seguente rimuove la `run_bootstrap_queries` risorsa dallo stato Terraform.

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

Il seguente esempio di codice mostra come la `run_repeatable_queries` risorsa monitora le modifiche nella `repeatable` cartella utilizzando l'[hash sha256](https://developer.hashicorp.com/terraform/language/functions/sha256). Se un file all'interno della cartella viene aggiornato, Terraform contrassegna l'intera directory per un aggiornamento. Quindi, Terraform esegue nuovamente le query nella directory successiva. `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}"
  }
}
```

Per perfezionare il codice, puoi implementare un meccanismo per rilevare e applicare le modifiche solo ai file che sono stati aggiornati all'interno della `repeatable` cartella, anziché applicare le modifiche a tutti i file indiscriminatamente.

**Esempi di istruzioni SQL**

L'output seguente mostra un'esecuzione SQL non riuscita, insieme a un messaggio di errore.

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

L'output seguente mostra un'esecuzione SQL riuscita.

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