Terraform을 사용하여 Amazon Redshift SQL 쿼리 실행 - AWS 권장 가이드

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

Terraform을 사용하여 Amazon Redshift SQL 쿼리 실행

작성자: Sylvia Qi(AWS) 및 Aditya Ambati(AWS)

코드 리포지토리: terraform-execute-redshift-sql

환경: PoC 또는 파일럿

기술: DevOps, 분석, 빅 데이터, 데이터 레이크

워크로드: 오픈 소스

AWS 서비스: Amazon Redshift AWS CLI

요약

Amazon Redshift의 배포 및 관리를 위해 인프라를 코드(IaC )로 사용하는 것은 내에서 널리 사용되는 관행입니다 DevOps. IaC는 클러스터, 스냅샷 및 파라미터 그룹과 같은 다양한 Amazon Redshift 리소스의 배포 및 구성을 용이하게 합니다. 그러나 IaC는 테이블, 스키마, 뷰 및 저장된 프로시저와 같은 데이터베이스 리소스의 관리로 확장되지 않습니다. 이러한 데이터베이스 요소는 SQL 쿼리를 통해 관리되며 IaC 도구에서 직접 지원되지 않습니다. 이러한 리소스를 관리하기 위한 솔루션과 도구가 있지만 기술 스택에 추가 도구를 도입하지 않는 것이 좋습니다.

이 패턴은 Terraform을 사용하여 테이블, 스키마, 뷰 및 저장된 프로시저를 포함한 Amazon Redshift 데이터베이스 리소스를 배포하는 방법론을 간략하게 설명합니다. 패턴은 두 가지 유형의 SQL 쿼리를 구분합니다.

  • 반복할 수 없는 쿼리 - 이러한 쿼리는 초기 Amazon Redshift 배포 중에 한 번 실행되어 필수 데이터베이스 구성 요소를 설정합니다.

  • 반복 가능한 쿼리 - 이러한 쿼리는 변경할 수 없으며 데이터베이스에 영향을 주지 않고 다시 실행할 수 있습니다. 이 솔루션은 Terraform을 사용하여 반복 가능한 쿼리의 변경 사항을 모니터링하고 그에 따라 적용합니다.

자세한 내용은 추가 정보솔루션 연습을 참조하세요.

사전 조건 및 제한 사항

사전 조건 

가 활성화되어 AWS 계정 있어야 하며 배포 시스템에 다음을 설치해야 합니다.

제한 사항

  • 이 솔루션은 단일 Amazon Redshift 데이터베이스를 지원합니다. Terraform은 클러스터 생성 중에 하나의 데이터베이스만 생성할 수 있기 때문입니다.

  • 이 패턴에는 반복 가능한 쿼리를 적용하기 전에 변경 사항을 검증하는 테스트가 포함되지 않습니다. 신뢰성 향상을 위해 이러한 테스트를 통합하는 것이 좋습니다.

  • 솔루션을 설명하기 위해 이 패턴은 로컬 Terraform 상태 redshift.tf 파일을 사용하는 샘플 파일을 제공합니다. 그러나 프로덕션 환경의 경우 안정성과 협업을 강화하기 위해 잠금 메커니즘이 있는 원격 상태 파일을 사용하는 것이 좋습니다.

  • 일부 AWS 서비스 는 일부 에서 사용할 수 없습니다 AWS 리전. 리전 가용성은 AWS 서비스 리전별 섹션을 참조하세요. 특정 엔드포인트는 서비스 엔드포인트 및 할당량 을 참조하고 서비스의 링크를 선택합니다.

제품 버전

이 솔루션은 Amazon Redshift 패치 179에서 개발 및 테스트됩니다.

코드 리포지토리

이 패턴의 코드는 GitHub amazon-redshift-sql-deploy-terraform 리포지토리에서 사용할 수 있습니다.

아키텍처

다음 다이어그램은 Terraform이 반복 불가능한 쿼리와 반복 가능한 SQL 쿼리를 모두 처리하여 Amazon Redshift 데이터베이스 리소스를 관리하는 방법을 보여줍니다.

Terraform이 SQL 쿼리를 사용하여 Amazon Redshift 데이터베이스 리소스를 관리하는 프로세스입니다.

이 다이어그램은 다음 단계를 보여 줍니다.

  1. Terraform은 초기 Amazon Redshift 클러스터 배포 중에 반복할 수 없는 SQL 쿼리를 적용합니다.

  2. 개발자는 반복 가능한 SQL 쿼리에 대한 변경 사항을 커밋합니다.

  3. Terraform은 반복 가능한 SQL 쿼리의 변경 사항을 모니터링합니다.

  4. Terraform은 Amazon Redshift 데이터베이스에 반복 가능한 SQL 쿼리를 적용합니다.

이 패턴에서 제공하는 솔루션은 Amazon Redshift용 Terraform 모듈을 기반으로 구축됩니다. Terraform 모듈은 Amazon Redshift 클러스터 및 데이터베이스를 프로비저닝합니다. 모듈을 개선하기 위해 Amazon Redshift ExecuteStatement API 작업을 사용하여 SQL 쿼리를 실행하기 위해 사용자 지정 Python 스크립트를 호출하는 terraform_data 리소스를 사용했습니다. 따라서 모듈은 다음을 수행할 수 있습니다.

  • 데이터베이스를 프로비저닝한 후 SQL 쿼리를 사용하여 원하는 수의 데이터베이스 리소스를 배포합니다.

  • 반복 가능한 SQL 쿼리의 변경 사항을 지속적으로 모니터링하고 Terraform을 사용하여 해당 변경 사항을 적용합니다.

자세한 내용은 추가 정보솔루션 연습을 참조하세요.

도구

AWS 서비스

  • Amazon Redshift는 의 완전 관리형 페타바이트 규모 데이터 웨어하우스 서비스입니다 AWS 클라우드.

기타 도구

  • Terraform은 의 코드형 인프라(IaC) 도구 HashiCorp 로, 클라우드 및 온프레미스 리소스를 생성하고 관리하는 데 도움이 됩니다.

  • Python은 이 패턴에서 SQL 쿼리를 실행하는 데 사용되는 범용 프로그래밍 언어입니다.

모범 사례

에픽

작업설명필요한 기술

리포지토리를 복제합니다.

Amazon Redshift 클러스터 프로비저닝을 위한 Terraform 코드가 포함된 Git 리포지토리를 복제하려면 다음 명령을 사용합니다.

git clone https://github.com/aws-samples/amazon-redshift-sql-deploy-terraform.git
DevOps 엔지니어

Terraform 변수를 업데이트합니다.

특정 요구 사항에 따라 Amazon Redshift 클러스터 배포를 사용자 지정하려면 terraform.tfvars 파일에서 다음 파라미터를 업데이트합니다.

region = "<AWS_REGION>" cluster_identifier = "<REDSHIFT_CLUSTER_IDENTIFIER>" node_type = "<REDSHIFT_NODE_TYPE>" number_of_nodes = "<REDSHIFT_NODE_COUNT>" database_name = "<REDSHIFT_DB_NAME>" subnet_ids = "<REDSHIFT_SUBNET_IDS>" vpc_security_group_ids = "<REDSHIFT_SECURITY_GROUP_IDS>" run_nonrepeatable_queries = true run_repeatable_queries = true sql_path_bootstrap = "<BOOTSTRAP_SQLS_PATH>" sql_path_nonrepeatable = "<NON-REPEATABLE_SQLS_PATH>" sql_path_repeatable = "<REPEATABLE_SQLS_PATH>" sql_path_finalize = "<FINALIZE_SQLS_PATH>" create_random_password = false master_username = "<REDSHIFT_MASTER_USERNAME>"
DevOps 엔지니어

Terraform을 사용하여 리소스를 배포합니다.

  1. 배포 프로세스를 준비하려면 다음 명령을 사용하여 복제된 리포지토리 내에서 Terraform을 초기화합니다.

    terraform init
  2. Terraform이 인프라에 적용할 변경 사항을 미리 보려면 다음 명령을 사용하여 실행 계획을 생성합니다.

    terraform plan -var-file terraform.tfvars
  3. Amazon Redshift 클러스터 및 관련 리소스를 프로비저닝하려면 다음 명령을 사용하여 Terraform 실행 계획을 적용합니다.

    terraform apply -var-file terraform.tfvars
DevOps 엔지니어

(선택 사항) 추가 SQL 쿼리를 실행합니다.

샘플 리포지토리는 데모 목적으로 여러 SQL 쿼리를 제공합니다. 자체 SQL 쿼리를 실행하려면 다음 폴더에 쿼리를 추가합니다.

/bootstrap

/nonrepeatable

/repeatable

/finalize

작업설명필요한 기술

SQL 문 배포를 모니터링합니다.

Amazon Redshift 클러스터에 대한 SQL 실행 결과를 모니터링할 수 있습니다. 실패 및 성공적인 SQL 실행을 보여주는 출력의 예는 추가 정보 예제 SQL 문을 참조하세요.

DBA, DevOps 엔지니어

리소스를 정리합니다.

Terraform에서 배포한 모든 리소스를 삭제하려면 다음 명령을 실행합니다.

terraform destroy
DevOps 엔지니어
작업설명필요한 기술

Amazon Redshift 클러스터의 데이터를 검증합니다.

  1. 에 로그인 AWS Management Console하고 Amazon Redshift 콘솔을 엽니다.

  2. 탐색 메뉴에서 클러스터(Clusters)를 선택합니다. 목록에서 관련 클러스터 이름을 선택합니다.

  3. Amazon Redshift 설명서의 Amazon Redshift 쿼리 편집기 v2를 사용하여 데이터베이스 쿼리의 지침을 따릅니다.

DBA, AWS DevOps

관련 리소스

AWS 설명서

기타 리소스

추가 정보

솔루션 연습

솔루션을 사용하려면 Amazon Redshift SQL 쿼리를 특정 방식으로 구성해야 합니다. 모든 SQL 쿼리는 .sql 확장자가 있는 파일에 저장해야 합니다.

이 패턴과 함께 제공된 코드 예제에서 SQL 쿼리는 다음 폴더 구조로 구성됩니다. 코드(sql-queries.tfsql-queries.py)를 수정하여 고유한 사용 사례에 맞는 모든 구조로 작업할 수 있습니다.

/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

이전 폴더 구조를 고려할 때 Amazon Redshift 클러스터 배포 중에 Terraform은 다음 순서로 쿼리를 실행합니다.

  1. /bootstrap

  2. /nonrepeatable

  3. /repeatable

  4. /finalize

/repeatable 폴더에는 /udf, , 및 의 4개의 하위 폴더/table/view가 있습니다/stored-procedure. 이러한 하위 폴더는 Terraform이 SQL 쿼리를 실행하는 순서를 나타냅니다.

SQL 쿼리를 실행하는 Python 스크립트는 입니다sql-queries.py. 먼저 스크립트는 sql_path_bootstrap 파라미터와 같은 특정 소스 디렉터리의 모든 파일과 하위 폴더를 읽습니다. 그런 다음 스크립트는 Amazon Redshift ExecuteStatement API 작업을 호출하여 쿼리를 실행합니다. 파일에 하나 이상의 SQL 쿼리가 있을 수 있습니다. 다음 코드 조각은 Amazon Redshift 클러스터에 대해 파일에 저장된 SQL 문을 실행하는 Python 함수를 보여줍니다.

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

Terraform 스크립트는 sql-queries.py 스크립트를 호출하는 terraform_data 리소스를 sql-queries.tf 생성합니다. , /bootstrap, 및 의 4개 폴더 각각에 대한 terraform_data 리소스가 있습니다/nonrepeatable/repeatable/finalize. 다음 코드 조각은 /bootstrap 폴더에서 SQL 쿼리를 실행하는 terraform_data 리소스를 보여줍니다.

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

다음 변수를 사용하여 이러한 쿼리를 실행할지 여부를 제어할 수 있습니다. sql_path_bootstrap, sql_path_nonrepeatablesql_path_repeatable, 또는 에서 쿼리를 실행하지 않으려면 해당 값을 로 sql_path_finalize설정합니다"".

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"

를 실행하면 terraform applyTerraform은 스크립트의 결과에 관계없이 스크립트가 완료된 후 추가된 terraform_data 리소스를 고려합니다. 일부 SQL 쿼리가 실패하여 다시 실행하려는 경우 Terraform 상태에서 리소스를 수동으로 제거하고 terraform apply 다시 실행할 수 있습니다. 예를 들어 다음 명령은 Terraform 상태에서 run_bootstrap_queries 리소스를 제거합니다.

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

다음 코드 예제는 run_repeatable_queries 리소스가 sha256 해시 를 사용하여 repeatable 폴더의 변경 사항을 모니터링하는 방법을 보여줍니다. 폴더 내의 파일이 업데이트되면 Terraform은 업데이트를 위해 전체 디렉터리를 표시합니다. 그런 다음 Terraform은 다음 에서 디렉터리의 쿼리를 다시 실행합니다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}" } }

코드를 구체화하기 위해 모든 파일에 무차별적으로 변경 사항을 적용하는 대신 repeatable 폴더 내에서 업데이트된 파일에만 변경 사항을 감지하고 적용하는 메커니즘을 구현할 수 있습니다.

예제 SQL 문

다음 출력은 오류 메시지와 함께 실패한 SQL 실행을 보여줍니다.

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]

다음 출력은 성공적인 SQL 실행을 보여줍니다.

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]