Traffine I/O

Bahasa Indonesia

2023-02-16

Membangun Lingkungan AWS untuk Hosting dbt Docs menggunakan Terraform

Membangun Lingkungan AWS untuk Hosting dbt Docs menggunakan Terraform

Dalam artikel ini, saya akan memperkenalkan metode membangun lingkungan AWS untuk hosting dbt docs menggunakan Terraform. Tujuannya adalah membuat dokumen dbt yang diunggah ke S3 dapat diakses melalui CloudFront. Selain itu, saya akan mengimplementasikan autentikasi Dasar pada CloudFront menggunakan Lambda@Edge.

Kode Terraform

Anda dapat menemukan kode Terraform di repositori GitHub berikut:

https://github.com/ryuseikakujo/dbt-docs-terraform/tree/main

Struktur Direktori

Struktur direktori adalah sebagai berikut:

.
├── backend.tf
├── cloudfront.tf
├── iam.tf
├── lambda.tf
├── lambda_edge
│   └── index.py
├── lambda_edge_archive
├── provider.tf
├── s3.tf
└── variables.tf

Langkah-Langkah Konstruksi

Kita akan melanjutkan dengan membangun lingkungan untuk hosting dbt Docs di AWS dengan urutan berikut:

  1. Menulis fungsi Lambda@Edge untuk autentikasi Dasar.
  2. Membangun infrastruktur dengan Terraform.

Kode untuk fungsi Lambda@Edge, yang bertanggung jawab untuk autentikasi Dasar, ditulis di index.py seperti yang ditunjukkan di bawah ini:

lambda_edge/index.py
"""
Lambda@Edge for authentication
"""

import base64


def authenticate(user, password):
    return user == "admin" and password == "passW0rd"


def handler(event, context):
    request = event["Records"][0]["cf"]["request"]
    headers = request["headers"]

    error_response = {
        "status": "401",
        "statusDescription": "Unauthorized",
        "body": "Authentication Failed",
        "headers": {
            "www-authenticate": [
                {
                    "key": "WWW-Authenticate",
                    "value": 'Basic realm="Basic Authentication"',
                }
            ]
        },
    }

    if "authorization" not in headers:
        return error_response

    try:
        auth_values = headers["authorization"][0]["value"].split(" ")
        auth = base64.b64decode(auth_values[1]).decode().split(":")
        (user, password) = (auth[0], auth[1])
        return request if authenticate(user, password) else error_response
    except Exception:
        return error_response

Membangun Infrastruktur dengan Terraform

Kami akan menggunakan Terraform untuk membangun infrastruktur yang diperlukan.

Tulis kode Terraform untuk membuat infrastruktur. Anda dapat merujuk ke kode sumber di repositori berikut:

https://github.com/ryuseikakujo/dbt-docs-terraform/tree/main

Di sini, saya hanya akan menjelaskan poin-poin kunci.

Pengaturan Multi-Region

File provider.tf berisi konfigurasi penyedia AWS. Karena kami menggunakan Lambda@Edge, fungsi Lambda harus didistribusikan ke wilayah Virginia (us-east-1). Oleh karena itu, kami mendefinisikan penyedia untuk wilayah us-east-1 dan merujuknya saat mendefinisikan Lambda.

provider.tf
provider "aws" {
  region = "ap-northeast-1"

  default_tags {
    tags = {
      Env       = "dev"
      App       = "my-app"
      ManagedBy = "Terraform"
    }
  }
}

provider "aws" {
  alias  = "virginia"
  region = "us-east-1"

  default_tags {
    tags = {
      Env       = "dev"
      App       = "my-app"
      ManagedBy = "Terraform"
    }
  }
}
lambda.tf
resource "aws_lambda_function" "cloudfront_auth" {
  provider         = aws.virginia
  .
  .
  .
}

https://io.traffine.com/id/articles/terraform-aws-multi-regions

Mengompresi Lambda

Dengan menggunakan data source archive_file di lambda.tf, Anda dapat menghasilkan file Zip dari direktori yang ditentukan.

lambda.tf
data "archive_file" "function_source" {
  type        = "zip"
  source_dir  = "lambda_edge"
  output_path = "lambda_edge_archive/function.zip"
}

File Zip yang dihasilkan dirujuk saat mendefinisikan Lambda.

lambda.tf
resource "aws_lambda_function" "cloudfront_auth" {
  .
  .
  .
  filename         = data.archive_file.function_source.output_path
  source_code_hash = data.archive_file.function_source.output_base64sha256
}

Versi Lambda

CloudFront memerlukan penentuan versi fungsi Lambda. Untuk informasi tentang versi Lambda, silakan merujuk ke artikel berikut:

https://io.traffine.com/id/articles/version-and-alias-in-lambda

Dengan mengatur publish=true saat mendefinisikan Lambda, versi akan diaktifkan.

lambda
resource "aws_lambda_function" "cloudfront_auth" {
  .
  .
  .
  publish          = true
}

CloudFront akan merujuk versi Lambda yang ditentukan.

cloudfront.tf
resource "aws_cloudfront_distribution" "main" {
  .
  .
  .
    lambda_function_association {
      .
      .
      lambda_arn   = aws_lambda_function.cloudfront_auth.qualified_arn
    }
}

Terraform Apply

Jalankan terraform apply untuk membangun lingkungan.

Menyimpan dbt Docs di S3

Di direktori proyek dbt, unggah dokumen dbt ke S3 menggunakan perintah berikut:

bash
$ dbt docs generate
$ aws s3 cp target/manifest.json s3://<s3 bucket name created by terraform>/
$ aws s3 cp target/run_results.json s3://<s3 bucket name created by terraform>/
$ aws s3 cp target/index.html s3://<s3 bucket name created by terraform>/
$ aws s3 cp target/catalog.json s3://<s3 bucket name created by terraform>/

Verifikasi Dokumen

Mengakses domain distribusi CloudFront akan menunjukkan bahwa autentikasi Dasar diberlakukan.

CloudFront

Setelah autentikasi, Anda akan dapat melihat dokumen-dokumen tersebut.

Selain itu, mengakses S3 secara langsung akan mengakibatkan penolakan.

S3

Ryusei Kakujo

researchgatelinkedingithub

Focusing on data science for mobility

Bench Press 100kg!