

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Jalankan kueri Amazon Redshift SQL dengan menggunakan Terraform
<a name="execute-redshift-sql-queries-using-terraform"></a>

*Sylvia Qi dan Aditya Ambati, Amazon Web Services*

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

Menggunakan infrastruktur sebagai kode (IAc) untuk penyebaran dan pengelolaan Amazon Redshift adalah praktik umum di dalamnya. DevOps IAc memfasilitasi penyebaran dan konfigurasi berbagai sumber daya Amazon Redshift, seperti cluster, snapshot, dan grup parameter. Namun, IAc tidak meluas ke pengelolaan sumber daya database seperti tabel, skema, tampilan, dan prosedur tersimpan. Elemen-elemen database ini dikelola melalui query SQL dan tidak secara langsung didukung oleh alat IAC. Meskipun ada solusi dan alat untuk mengelola sumber daya ini, Anda mungkin memilih untuk tidak memperkenalkan alat tambahan ke dalam tumpukan teknologi Anda.

Pola ini menguraikan metodologi yang menggunakan Terraform untuk menyebarkan sumber daya database Amazon Redshift, termasuk tabel, skema, tampilan, dan prosedur tersimpan. Pola membedakan antara dua jenis query SQL:
+ **Kueri yang tidak dapat diulang** — Kueri ini dijalankan satu kali selama penerapan Amazon Redshift awal untuk membuat komponen basis data penting. 
+ **Kueri berulang** — Kueri ini tidak dapat diubah dan dapat dijalankan kembali tanpa memengaruhi database. Solusinya menggunakan Terraform untuk memantau perubahan dalam kueri yang dapat diulang dan menerapkannya sesuai dengan itu.

Untuk detail selengkapnya, lihat *Panduan solusi* di Informasi [tambahan](#execute-redshift-sql-queries-using-terraform-additional).

## Prasyarat dan batasan
<a name="execute-redshift-sql-queries-using-terraform-prereqs"></a>

**Prasyarat**

Anda harus memiliki yang aktif Akun AWS dan menginstal yang berikut ini pada mesin penyebaran Anda:
+ [AWS Command Line Interface](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) (AWS CLI)
+ [AWS CLI Profil](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html) yang dikonfigurasi dengan izin Amazon Redshift read/write 
+ [Terraform](https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli) versi 1.6.2 atau yang lebih baru
+ [Python3](https://www.python.org/downloads/)
+ [Boto3](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/quickstart.html)

**Batasan**
+ Solusi ini mendukung satu database Amazon Redshift karena Terraform hanya memungkinkan pembuatan satu database selama pembuatan cluster.
+ Pola ini tidak menyertakan pengujian untuk memvalidasi perubahan pada kueri berulang sebelum menerapkannya. Kami menyarankan Anda memasukkan tes tersebut untuk meningkatkan keandalan.
+ Untuk mengilustrasikan solusinya, pola ini menyediakan `redshift.tf` file contoh yang menggunakan file status Terraform lokal. Namun, untuk lingkungan produksi, kami sangat menyarankan Anda menggunakan file status jarak jauh dengan mekanisme penguncian untuk meningkatkan stabilitas dan kolaborasi.
+ Beberapa Layanan AWS tidak tersedia di semua Wilayah AWS. Untuk ketersediaan Wilayah, lihat [Layanan AWS berdasarkan Wilayah](https://aws.amazon.com/about-aws/global-infrastructure/regional-product-services/). Untuk titik akhir tertentu, lihat [Titik akhir dan kuota layanan](https://docs.aws.amazon.com/general/latest/gr/aws-service-information.html), dan pilih tautan untuk layanan.

**Versi produk**

Solusi ini dikembangkan dan diuji pada [Amazon Redshift patch](https://docs.aws.amazon.com/redshift/latest/mgmt/cluster-versions.html#cluster-version-179) 179.

**Repositori kode**

Kode untuk pola ini tersedia di repositori GitHub [amazon-redshift-sql-deploy-terraform](https://github.com/aws-samples/amazon-redshift-sql-deploy-terraform).

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

Diagram berikut mengilustrasikan cara Terraform mengelola sumber daya database Amazon Redshift dengan menangani kueri SQL yang tidak dapat diulang dan yang dapat diulang.

![\[Proses Terraform untuk mengelola sumber daya database Amazon Redshift menggunakan kueri SQL.\]](http://docs.aws.amazon.com/id_id/prescriptive-guidance/latest/patterns/images/pattern-img/0f4467ac-761b-4b6b-a32f-e18a2ca2245d/images/3b6ff9e8-e3d1-48ed-9fa1-4b14f7d3d65b.png)


Diagram menunjukkan langkah-langkah berikut:

1. Terraform menerapkan kueri SQL yang tidak dapat diulang selama penerapan klaster Amazon Redshift awal.

1. Pengembang melakukan perubahan pada kueri SQL berulang.

1. Terraform memantau perubahan dalam kueri SQL yang dapat diulang.

1. Terraform menerapkan kueri SQL yang dapat diulang ke database Amazon Redshift.

Solusi yang disediakan oleh pola ini dibuat berdasarkan [modul Terraform untuk Amazon Redshift](https://registry.terraform.io/modules/terraform-aws-modules/redshift/aws/latest). Modul Terraform menyediakan cluster dan database Amazon Redshift. Untuk menyempurnakan modul, kami menggunakan `terraform_data` sumber daya, yang memanggil skrip Python khusus untuk menjalankan kueri SQL menggunakan operasi Amazon Redshift API. [ExecuteStatement](https://docs.aws.amazon.com/redshift-data/latest/APIReference/API_ExecuteStatement.html) Akibatnya, modul dapat melakukan hal berikut:
+ Menyebarkan sejumlah sumber daya database dengan menggunakan kueri SQL setelah database disediakan.
+ Pantau terus menerus untuk perubahan dalam kueri SQL yang dapat diulang dan terapkan perubahan tersebut menggunakan Terraform.

Untuk detail selengkapnya, lihat *Panduan solusi* di Informasi [tambahan](#execute-redshift-sql-queries-using-terraform-additional).

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

**Layanan AWS**
+ [Amazon Redshift adalah layanan](https://docs.aws.amazon.com/redshift/latest/mgmt/welcome.html) gudang data skala petabyte yang dikelola sepenuhnya di. AWS Cloud

**Alat-alat lainnya**
+ [Terraform](https://www.terraform.io/) adalah alat infrastruktur sebagai kode (IAc) HashiCorp yang membantu Anda membuat dan mengelola sumber daya cloud dan lokal.
+ [Python](https://www.python.org/) adalah bahasa pemrograman tujuan umum yang digunakan dalam pola ini untuk mengeksekusi query SQL. 

## Praktik terbaik
<a name="execute-redshift-sql-queries-using-terraform-best-practices"></a>
+ [Praktik terbaik Amazon Redshift](https://docs.aws.amazon.com/redshift/latest/dg/best-practices.html)
+ [Menggunakan Amazon Redshift Data API untuk berinteraksi dengan klaster Amazon Redshift](https://aws.amazon.com/blogs/big-data/using-the-amazon-redshift-data-api-to-interact-with-amazon-redshift-clusters/)

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

### Terapkan solusi menggunakan Terraform
<a name="deploy-the-solution-using-terraform"></a>


| Tugas | Deskripsi | Keterampilan yang dibutuhkan | 
| --- | --- | --- | 
| **Kloning repositori.** | Untuk mengkloning repositori Git yang berisi kode Terraform untuk menyediakan cluster Amazon Redshift, gunakan perintah berikut.<pre>git clone https://github.com/aws-samples/amazon-redshift-sql-deploy-terraform.git</pre> | DevOps insinyur | 
| **Perbarui variabel Terraform.** | Untuk menyesuaikan penerapan klaster Amazon Redshift sesuai dengan kebutuhan spesifik Anda, perbarui parameter berikut dalam file. `terraform.tfvars`<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 insinyur | 
| Terapkan sumber daya menggunakan Terraform. | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/id_id/prescriptive-guidance/latest/patterns/execute-redshift-sql-queries-using-terraform.html) | DevOps insinyur | 
| (Opsional) Jalankan kueri SQL tambahan. | Repositori sampel menyediakan beberapa kueri SQL untuk tujuan demo. Untuk menjalankan kueri SQL Anda sendiri, tambahkan ke folder berikut:`/bootstrap` `/nonrepeatable` `/repeatable` `/finalize` |  | 

### Memantau eksekusi pernyataan SQL
<a name="monitor-the-execution-of-sql-statements"></a>


| Tugas | Deskripsi | Keterampilan yang dibutuhkan | 
| --- | --- | --- | 
| Memantau penyebaran pernyataan SQL. | Anda dapat memantau hasil eksekusi SQL ke cluster Amazon Redshift. Untuk contoh output yang menunjukkan eksekusi SQL yang gagal dan berhasil, lihat *Contoh pernyataan SQL dalam Informasi* [tambahan](#execute-redshift-sql-queries-using-terraform-additional).  | DBA, DevOps insinyur | 
| Pembersihan sumber daya  | Untuk menghapus semua sumber daya yang digunakan oleh Terraform, jalankan perintah berikut.<pre>terraform destroy</pre> | DevOps insinyur | 

### Validasi hasilnya
<a name="validate-the-results"></a>


| Tugas | Deskripsi | Keterampilan yang dibutuhkan | 
| --- | --- | --- | 
| Validasi data di cluster Amazon Redshift. | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/id_id/prescriptive-guidance/latest/patterns/execute-redshift-sql-queries-using-terraform.html) | DBA, AWS DevOps | 

## Sumber daya terkait
<a name="execute-redshift-sql-queries-using-terraform-resources"></a>

**AWS dokumentasi**
+ [Cluster yang disediakan Amazon Redshift](https://docs.aws.amazon.com/redshift/latest/mgmt/working-with-clusters.html)
+ [Memecahkan masalah untuk Amazon Redshift Data API](https://docs.aws.amazon.com/redshift/latest/mgmt/data-api-troubleshooting.html)

**Sumber daya lainnya**
+ [Perintah: terapkan](https://developer.hashicorp.com/terraform/cli/commands/apply) (dokumentasi Terraform)

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

**Panduan solusi**

Untuk menggunakan solusinya, Anda harus mengatur kueri Amazon Redshift SQL Anda dengan cara tertentu. Semua kueri SQL harus disimpan dalam file dengan ekstensi. `.sql`

Dalam contoh kode yang disediakan dengan pola ini, query SQL diatur dalam struktur folder berikut. Anda dapat memodifikasi kode (`sql-queries.tf`dan`sql-queries.py`) untuk bekerja dengan struktur apa pun yang sesuai dengan kasus penggunaan unik Anda.

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

Mengingat struktur folder sebelumnya, selama penerapan klaster Amazon Redshift, Terraform mengeksekusi kueri dengan urutan berikut:

1. `/bootstrap`

1. `/nonrepeatable`

1. `/repeatable`

1. `/finalize`

`/repeatable`Folder berisi empat subfolder:`/udf`,, `/table``/view`, dan`/stored-procedure`. Subfolder ini menunjukkan urutan di mana Terraform mengeksekusi kueri SQL.

Script Python yang mengeksekusi query SQL adalah. `sql-queries.py` Pertama, skrip membaca semua file dan subfolder dari direktori sumber tertentu, misalnya, `sql_path_bootstrap` parameter. Kemudian skrip mengeksekusi kueri dengan memanggil operasi Amazon [ExecuteStatement](https://docs.aws.amazon.com/redshift-data/latest/APIReference/API_ExecuteStatement.html)Redshift API. Anda mungkin memiliki satu atau lebih kueri SQL dalam sebuah file. Cuplikan kode berikut menunjukkan fungsi Python yang mengeksekusi pernyataan SQL yang disimpan dalam file terhadap 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
    )
    ...
```

Skrip Terraform `sql-queries.tf` membuat sumber daya [terraform\$1data](https://developer.hashicorp.com/terraform/language/resources/terraform-data) yang memanggil skrip. `sql-queries.py` Ada `terraform_data` sumber daya untuk masing-masing dari empat folder:`/bootstrap`,`/nonrepeatable`,`/repeatable`, dan`/finalize`. Cuplikan kode berikut menunjukkan `terraform_data` sumber daya yang mengeksekusi query SQL dalam folder. `/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}"
  }
}
```

Anda dapat mengontrol apakah akan menjalankan query ini dengan menggunakan variabel berikut. Jika Anda tidak ingin menjalankan kueri di`sql_path_bootstrap`,,`sql_path_nonrepeatable`, atau `sql_path_repeatable``sql_path_finalize`, setel nilainya. `""`

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

Saat Anda menjalankan`terraform apply`, Terraform mempertimbangkan `terraform_data` sumber daya yang ditambahkan setelah skrip selesai, terlepas dari hasil skripnya. Jika beberapa kueri SQL gagal, dan Anda ingin menjalankannya kembali, Anda dapat menghapus sumber daya secara manual dari status Terraform, dan menjalankannya lagi. `terraform apply` Misalnya, perintah berikut menghapus `run_bootstrap_queries` sumber daya dari status Terraform.

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

Contoh kode berikut menunjukkan bagaimana `run_repeatable_queries` sumber daya memantau perubahan dalam `repeatable` folder dengan menggunakan [hash sha256](https://developer.hashicorp.com/terraform/language/functions/sha256). Jika ada file di dalam folder yang diperbarui, Terraform menandai seluruh direktori untuk pembaruan. Kemudian, Terraform menjalankan kueri di direktori lagi selama berikutnya. `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}"
  }
}
```

Untuk memperbaiki kode, Anda dapat menerapkan mekanisme untuk mendeteksi dan menerapkan perubahan hanya pada file yang telah diperbarui dalam `repeatable` folder, daripada menerapkan perubahan ke semua file tanpa pandang bulu.

**Contoh pernyataan SQL**

Output berikut menunjukkan eksekusi SQL gagal, bersama dengan pesan kesalahan.

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

Output berikut menunjukkan eksekusi SQL yang sukses.

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