Private key เจ้าปัญหา กับ env_var ใน dbt


จากบล็อก วิธีใส่ Private Key หรือ Secret ที่มี Special Char ใน AWS Secrets Manager ที่พี่ @zkan เขียนไว้ จะเห็นได้ว่าเจ้า private key ชอบมีเรื่องมีราวให้ได้เห็นอยู่บ่อย ๆ

การใช้ private key ผ่าน env_var บน dbt ก็มีเรื่องให้ได้ปะทะเช่นเดียวกันครับ :boom:

ตัวอย่างเช่น การตั้งค่า authentication ของ BigQuery แบบ service-account-json โดยใช้ค่า private_key จาก environment variable

# profiles.yml
my_project:
  outputs:
    develop:
      dataset: my_dataset
      method: service-account-json
      keyfile_json:
        type: service_account
        private_key: "{{ env_var('DBT_ENV_SECRET_BIGQUERY_PRIVATE_KEY') }}"

แต่เมื่อลอง debug ดู dbt กลับฟ้องว่าไม่พบ private key ของเราซะงั้น!

# macOS bash
$ DBT_ENV_SECRET_BIGQUERY_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nABC...XYZ\n-----END PRIVATE KEY-----\n" \
dbt debug

# result
Connection:
  Connection test: [ERROR]
  ...

  No key could be detected.

ที่เป็นแบบนี้เพราะว่า private key ที่ dbt เห็น ไม่เหมือนกับที่เราต้องการ …แล้ว dbt เห็นอะไร?

จาก code บน dbt-core repository จะเห็นว่า dbt อ่าน environment variable ด้วย os.environ[...]

ถ้าลอง export private key เช่นเดียวกับตอน debug แล้วดูผลลัพธ์ของ os.environ[...] จะพบว่าค่าที่อ่านได้มีการ escape backslash (\) ของ \n เพิ่มเข้าไปเป็น \\n :scream:

$ export DBT_ENV_SECRET_BIGQUERY_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nABC...XYZ\n-----END PRIVATE KEY-----\n"
$ python
>>> import os 
>>> os.environ["DBT_ENV_SECRET_BIGQUERY_PRIVATE_KEY"]
'-----BEGIN PRIVATE KEY-----\\nABC...XYZ\\n-----END PRIVATE KEY-----\\n'

Make it work!

เพื่อให้ dbt เห็น private key ตามที่เราต้องการ ตอนนี้ผมใช้วิธี echo ก่อนแล้วจึงใช้ค่าจาก standard output ของ echo อีกที วิธีช่วยให้ \n ถูกแปลงเป็นการขึ้นบรรทัดใหม่และตอน dbt อ่านค่าก็จะเห็นบรรทัดใหม่เป็น \n นั่นเอง

$ DBT_ENV_SECRET_BIGQUERY_PRIVATE_KEY=$(echo "-----BEGIN PRIVATE KEY-----\nABC...XYZ\n-----END PRIVATE KEY-----\n") \
dbt debug

พี่ ๆ เพื่อน ๆ ใช้วิธีไหนอยู่ หรือมีวิธีเจ๋ง ๆ มาแชร์กันได้นะครับ :pray:t2:


References

2 Likes