Cloud Run Functions์—์„œ ์—ฐ๊ฒฐ

์ด ํŽ˜์ด์ง€์—๋Š” Cloud Run Functions์—์„œ ์‹คํ–‰๋˜๋Š” ์„œ๋น„์Šค์—์„œ Cloud SQL ์ธ์Šคํ„ด์Šค์— ์—ฐ๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์ •๋ณด์™€ ์˜ˆ์‹œ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

Cloud SQL์— ์—ฐ๊ฒฐ๋œ Cloud Run Functions ์ƒ˜ํ”Œ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๋‹จ๊ณ„๋ณ„ ์•ˆ๋‚ด๋Š” ๋น ๋ฅธ ์‹œ์ž‘: Cloud Run Functions์—์„œ ์—ฐ๊ฒฐ์„ ์ฐธ์กฐํ•˜์„ธ์š”.

Cloud SQL์€ ํด๋ผ์šฐ๋“œ์—์„œ ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์„ค์ •, ์œ ์ง€, ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ์™„์ „ ๊ด€๋ฆฌํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„œ๋น„์Šค์ž…๋‹ˆ๋‹ค.

Cloud Run Functions๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ์„œ๋ฒ„๋‚˜ ๋Ÿฐํƒ€์ž„ ํ™˜๊ฒฝ์„ ๊ด€๋ฆฌํ•˜์ง€ ์•Š๊ณ ๋„ Cloud ์ด๋ฒคํŠธ์— ์‘๋‹ตํ•˜๋Š” ๋‹จ์ผ ์šฉ๋„์˜ ๋…๋ฆฝ ์‹คํ–‰ํ˜• ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ๊ฒฝ๋Ÿ‰ํ˜• ์ปดํ“จํŒ… ์†”๋ฃจ์…˜์ž…๋‹ˆ๋‹ค.

Cloud SQL ์ธ์Šคํ„ด์Šค ์„ค์ •

  1. ์•„์ง ์‚ฌ์šฉ ์„ค์ •ํ•˜์ง€ ์•Š์•˜์œผ๋ฉด ์—ฐ๊ฒฐ ์ค‘์ธ Google Cloud ํ”„๋กœ์ ํŠธ์—์„œ Cloud SQL Admin API๋ฅผ ์‚ฌ์šฉ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

    Enable the API

  2. PostgreSQL์šฉ Cloud SQL ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“œ์„ธ์š”. ์ง€์—ฐ ์‹œ๊ฐ„์„ ๊ฐœ์„ ํ•˜๊ณ , ์ผ๋ถ€ ๋„คํŠธ์›Œํ‚น ๋น„์šฉ ๋ฐœ์ƒ์„ ๋ฐฉ์ง€ํ•˜๊ณ , ๋ฆฌ์ „ ๊ฐ„ ์žฅ์•  ์œ„ํ—˜์„ ์ค„์ด๋ ค๋ฉด Cloud Run ์„œ๋น„์Šค์™€ ๋™์ผํ•œ ๋ฆฌ์ „์— ์žˆ๋Š” Cloud SQL ์ธ์Šคํ„ด์Šค ์œ„์น˜๋ฅผ ์„ ํƒํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

    ๊ธฐ๋ณธ์ ์œผ๋กœ Cloud SQL์€ ๊ณต๊ฐœ IP ์ฃผ์†Œ๋ฅผ ์ƒˆ ์ธ์Šคํ„ด์Šค์— ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค. ๋น„๊ณต๊ฐœ IP ์ฃผ์†Œ๋ฅผ ํ• ๋‹นํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‘ ์˜ต์…˜์˜ ์—ฐ๊ฒฐ ์˜ต์…˜์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์—ฐ๊ฒฐ ๊ฐœ์š” ํŽ˜์ด์ง€๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

  3. ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค ๋•Œ ์ธ์Šคํ„ด์Šค์˜ ์„œ๋ฒ„ ์ธ์ฆ์„œ(CA) ๊ณ„์ธต ๊ตฌ์กฐ๋ฅผ ์„ ํƒํ•œ ๋‹ค์Œ ๊ณ„์ธต ๊ตฌ์กฐ๋ฅผ ์ธ์Šคํ„ด์Šค์˜ serverCaMode๋กœ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์—ฐ๊ฒฐํ•  ์ธ์Šคํ„ด์Šค์˜ ์„œ๋ฒ„ CA ๋ชจ๋“œ๋กœ ์ธ์Šคํ„ด์Šค๋ณ„ CA ์˜ต์…˜(GOOGLE_MANAGED_INTERNAL_CA)์„ ์„ ํƒํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

Cloud Run Functions ๊ตฌ์„ฑ

Cloud Run Functions๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๋‹จ๊ณ„๋Š” Cloud SQL ์ธ์Šคํ„ด์Šค์— ํ• ๋‹น๋œ IP ์ฃผ์†Œ ์œ ํ˜•์— ๋”ฐ๋ผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.

๊ณต๊ฐœ IP(๊ธฐ๋ณธ๊ฐ’)

Cloud Run Functions๋ฅผ Cloud SQL ์ธ์Šคํ„ด์Šค์— ์—ฐ๊ฒฐํ•˜๋„๋ก ๊ตฌ์„ฑํ•˜๋ ค๋ฉด ๋‹ค์Œ ์•ˆ๋‚ด๋ฅผ ๋”ฐ๋ฅด์„ธ์š”.

  • ์œ„์—์„œ ๋งŒ๋“  ์ธ์Šคํ„ด์Šค์— ๊ณต๊ฐœ IP ์ฃผ์†Œ๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. Google Cloud ์ฝ˜์†”์—์„œ ์ธ์Šคํ„ด์Šค์˜ ๊ฐœ์š” ํŽ˜์ด์ง€์—์„œ ์ด๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ณต๊ฐœ IP ์ฃผ์†Œ๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ ๊ณต๊ฐœ IP ๊ตฌ์„ฑ์„ ์ฐธ๊ณ ํ•˜์„ธ์š”.
  • ์ธ์Šคํ„ด์Šค์˜ INSTANCE_CONNECTION_NAME์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ์ด ๊ฐ’์€ ๋‹ค์Œ์„ ํ†ตํ•ด ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค.
    • ์ธ์Šคํ„ด์Šค์˜ ๊ฐœ์š” ํŽ˜์ด์ง€, Google Cloud ์ฝ˜์†” ๋˜๋Š”
    • gcloud sql instances describe [INSTANCE_NAME] ๋ช…๋ น์–ด ์‹คํ–‰
  • ํ•จ์ˆ˜์˜ ์„œ๋น„์Šค ๊ณ„์ •์„ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์Šน์ธ ์„œ๋น„์Šค ๊ณ„์ •์ด Cloud SQL ์ธ์Šคํ„ด์Šค์™€ ๋‹ค๋ฅธ ํ”„๋กœ์ ํŠธ์— ์†ํ•˜๋Š” ๊ฒฝ์šฐ Cloud SQL Admin API๋ฅผ ์‚ฌ์šฉ ์„ค์ •ํ•˜๊ณ  ๋‘ ํ”„๋กœ์ ํŠธ์— Cloud SQL Client IAM ์—ญํ• ์„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ์„œ๋น„์Šค ๊ณ„์ •์— ์ด ์—ญํ• ์ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜์—ฌ ํ•ด๋‹น ๊ณ„์ •์ด Cloud SQL์— ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
  • Cloud Run Functions(1์„ธ๋Œ€)๊ฐ€ ์•„๋‹Œ Cloud Run Functions๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ๋‹ค์Œ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค(Cloud Run ๊ตฌ์„ฑ ์ฐธ์กฐ).
    1. ์ฒ˜์Œ์— ํ•จ์ˆ˜๋ฅผ ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค.
      Google Cloud ์ฝ˜์†”์—์„œ Cloud Run ํ•จ์ˆ˜๋ฅผ ์ฒ˜์Œ ๋งŒ๋“ค ๋•Œ๋Š” ๊ธฐ๋ณธ Cloud Run ์„œ๋น„์Šค๊ฐ€ ์•„์ง ์ƒ์„ฑ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Cloud run ํ•จ์ˆ˜๋ฅผ ๋ฐฐํฌํ•˜์—ฌ ์„œ๋น„์Šค๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ๊นŒ์ง€๋Š” Cloud SQL ์—ฐ๊ฒฐ์„ ๊ตฌ์„ฑํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
    2. Google Cloud ์ฝ˜์†”์˜ ํ•จ์ˆ˜ ์„ธ๋ถ€์ •๋ณด ํŽ˜์ด์ง€ ์˜ค๋ฅธ์ชฝ ์œ„์— ์žˆ๋Š” Cloud Run ์ œ๊ณต ์•„๋ž˜์—์„œ ๋งํฌ๋ฅผ ํด๋ฆญํ•˜์—ฌ ๊ธฐ๋ณธ Cloud Run ์„œ๋น„์Šค์— ์•ก์„ธ์Šคํ•ฉ๋‹ˆ๋‹ค.
    3. Cloud Run ์„œ๋น„์Šค ์„ธ๋ถ€์ •๋ณด ํŽ˜์ด์ง€์—์„œ ์ƒˆ ๋ฒ„์ „ ์ˆ˜์ • ๋ฐ ๋ฐฐํฌ ํƒญ์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.
    4. Cloud SQL ์—ฐ๊ฒฐ์˜ ์ƒˆ ๊ตฌ์„ฑ ์„ค์ •์„ ์œ„ํ•œ ํ‘œ์ค€ ๋‹จ๊ณ„๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค(๊ตฌ์„ฑ ๋ณ€๊ฒฝ ๋Œ€๋น„).
      ๊ทธ๋Ÿฌ๋ฉด ์ƒˆ Cloud Run ๋ฒ„์ „์ด ์ƒ์„ฑ๋˜๊ณ  ์ด๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๋Š” ํ•œ ์ดํ›„ ๋ฒ„์ „์— ์ด Cloud SQL ์—ฐ๊ฒฐ์ด ์ž๋™์œผ๋กœ ์ˆ˜์‹ ๋ฉ๋‹ˆ๋‹ค.

๋น„๊ณต๊ฐœ IP

์Šน์ธ ์„œ๋น„์Šค ๊ณ„์ •์ด Cloud SQL ์ธ์Šคํ„ด์Šค๋ฅผ ํฌํ•จํ•˜๋Š” ๊ฒƒ๊ณผ ๋‹ค๋ฅธ ํ”„๋กœ์ ํŠธ์— ์†ํ•˜๋Š” ๊ฒฝ์šฐ ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

  • ๋‘ ํ”„๋กœ์ ํŠธ ๋ชจ๋‘์—์„œ Cloud SQL Admin API๋ฅผ ์‚ฌ์šฉ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
  • Cloud SQL ์ธ์Šคํ„ด์Šค๊ฐ€ ํฌํ•จ๋œ ํ”„๋กœ์ ํŠธ์˜ ์„œ๋น„์Šค ๊ณ„์ •์— IAM ๊ถŒํ•œ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
์„œ๋ฒ„๋ฆฌ์Šค VPC ์•ก์„ธ์Šค ์ปค๋„ฅํ„ฐ๋Š” ๋น„๊ณต๊ฐœ IP ์ฃผ์†Œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ VPC ๋„คํŠธ์›Œํฌ์— ๋Œ€ํ•œ ํ†ต์‹ ์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ๋น„๊ณต๊ฐœ IP ์ฃผ์†Œ๋กœ ์ง์ ‘ ์—ฐ๊ฒฐํ•˜๋ ค๋ฉด ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  1. ์œ„์—์„œ ๋งŒ๋“  Cloud SQL ์ธ์Šคํ„ด์Šค์— ๋น„๊ณต๊ฐœ IP ์ฃผ์†Œ๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์ถ”๊ฐ€ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ ๋น„๊ณต๊ฐœ IP ๊ตฌ์„ฑ์˜ ์•ˆ๋‚ด๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.
  2. Cloud SQL ์ธ์Šคํ„ด์Šค์™€ ๋™์ผํ•œ VPC ๋„คํŠธ์›Œํฌ์— ์„œ๋ฒ„๋ฆฌ์Šค VPC ์•ก์„ธ์Šค ์ปค๋„ฅํ„ฐ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๋‹ค์Œ ์กฐ๊ฑด์„ ์ฐธ๊ณ ํ•˜์„ธ์š”.
    • ๊ณต์œ  VPC๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ํ•œ ์ปค๋„ฅํ„ฐ๋Š” ์ปค๋„ฅํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฆฌ์†Œ์Šค์™€ ๋™์ผํ•œ ํ”„๋กœ์ ํŠธ์™€ ๋ฆฌ์ „์— ์žˆ์–ด์•ผ ํ•˜์ง€๋งŒ ์ด ์ปค๋„ฅํ„ฐ๋Š” ์„œ๋กœ ๋‹ค๋ฅธ ๋ฆฌ์ „์˜ ๋ฆฌ์†Œ์Šค๋กœ ํŠธ๋ž˜ํ”ฝ์„ ์ „์†กํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ์„œ๋ฒ„๋ฆฌ์Šค VPC ์•ก์„ธ์Šค๋Š” Cloud VPN๊ณผ VPC ๋„คํŠธ์›Œํฌ ํ”ผ์–ด๋ง์„ ํ†ตํ•ด ์—ฐ๊ฒฐ๋œ VPC ๋„คํŠธ์›Œํฌ์™€์˜ ํ†ต์‹ ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.
    • ์„œ๋ฒ„๋ฆฌ์Šค VPC ์•ก์„ธ์Šค๋Š” ๊ธฐ์กด ๋„คํŠธ์›Œํฌ๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  3. Cloud Run Functions์—์„œ ์ปค๋„ฅํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  4. ์ธ์Šคํ„ด์Šค์˜ ๋น„๊ณต๊ฐœ IP ์ฃผ์†Œ์™€ ํฌํŠธ 5432๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค.

Cloud SQL์— ์—ฐ๊ฒฐ

Cloud Run Functions๋ฅผ ๊ตฌ์„ฑํ•œ ํ›„์— Cloud SQL ์ธ์Šคํ„ด์Šค์— ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ณต๊ฐœ IP(๊ธฐ๋ณธ๊ฐ’)

๊ณต๊ฐœ IP ๊ฒฝ๋กœ์˜ ๊ฒฝ์šฐ Cloud Run Functions๋Š” ์•”ํ˜ธํ™”๋ฅผ ์ œ๊ณตํ•˜๊ณ  ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์œผ๋กœ Cloud SQL ์ธ์ฆ ํ”„๋ก์‹œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค.

๋น„๊ณต๊ฐœ IP

๋น„๊ณต๊ฐœ IP ๊ฒฝ๋กœ์˜ ๊ฒฝ์šฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ VPC ๋„คํŠธ์›Œํฌ๋ฅผ ํ†ตํ•ด ์ธ์Šคํ„ด์Šค์— ์ง์ ‘ ์—ฐ๊ฒฐ๋ฉ๋‹ˆ๋‹ค. ์ด ๋ฉ”์„œ๋“œ๋Š” TCP๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Cloud SQL ์ธ์ฆ ํ”„๋ก์‹œ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  Cloud SQL ์ธ์Šคํ„ด์Šค์— ์ง์ ‘ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค.

TCP๋กœ ์—ฐ๊ฒฐ

Cloud SQL ์ธ์Šคํ„ด์Šค์˜ ๋น„๊ณต๊ฐœ IP ์ฃผ์†Œ๋ฅผ ํ˜ธ์ŠคํŠธ ๋ฐ ํฌํŠธ 5432๋กœ ์‚ฌ์šฉํ•˜์—ฌ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค.

Python

์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ปจํ…์ŠคํŠธ์—์„œ ์ด ์Šค๋‹ˆํŽซ์„ ๋ณด๋ ค๋ฉด GitHub์˜ README๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.

import os
import ssl

import sqlalchemy


def connect_tcp_socket() -> sqlalchemy.engine.base.Engine:
    """Initializes a TCP connection pool for a Cloud SQL instance of Postgres."""
    # Note: Saving credentials in environment variables is convenient, but not
    # secure - consider a more secure solution such as
    # Cloud Secret Manager (https://cloud.google.com/secret-manager) to help
    # keep secrets safe.
    db_host = os.environ[
        "INSTANCE_HOST"
    ]  # e.g. '127.0.0.1' ('172.17.0.1' if deployed to GAE Flex)
    db_user = os.environ["DB_USER"]  # e.g. 'my-db-user'
    db_pass = os.environ["DB_PASS"]  # e.g. 'my-db-password'
    db_name = os.environ["DB_NAME"]  # e.g. 'my-database'
    db_port = os.environ["DB_PORT"]  # e.g. 5432

    pool = sqlalchemy.create_engine(
        # Equivalent URL:
        # postgresql+pg8000://<db_user>:<db_pass>@<db_host>:<db_port>/<db_name>
        sqlalchemy.engine.url.URL.create(
            drivername="postgresql+pg8000",
            username=db_user,
            password=db_pass,
            host=db_host,
            port=db_port,
            database=db_name,
        ),
        # ...
    )
    return pool

Java

์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ปจํ…์ŠคํŠธ์—์„œ ์ด ์Šค๋‹ˆํŽซ์„ ๋ณด๋ ค๋ฉด GitHub์˜ README๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.

์ฐธ๊ณ :


import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import javax.sql.DataSource;

public class TcpConnectionPoolFactory extends ConnectionPoolFactory {

  // Note: Saving credentials in environment variables is convenient, but not
  // secure - consider a more secure solution such as
  // Cloud Secret Manager (https://cloud.google.com/secret-manager) to help
  // keep secrets safe.
  private static final String DB_USER = System.getenv("DB_USER");
  private static final String DB_PASS = System.getenv("DB_PASS");
  private static final String DB_NAME = System.getenv("DB_NAME");

  private static final String INSTANCE_HOST = System.getenv("INSTANCE_HOST");
  private static final String DB_PORT = System.getenv("DB_PORT");


  public static DataSource createConnectionPool() {
    // The configuration object specifies behaviors for the connection pool.
    HikariConfig config = new HikariConfig();

    // The following URL is equivalent to setting the config options below:
    // jdbc:postgresql://<INSTANCE_HOST>:<DB_PORT>/<DB_NAME>?user=<DB_USER>&password=<DB_PASS>
    // See the link below for more info on building a JDBC URL for the Cloud SQL JDBC Socket Factory
    // https://github.com/GoogleCloudPlatform/cloud-sql-jdbc-socket-factory#creating-the-jdbc-url

    // Configure which instance and what database user to connect with.
    config.setJdbcUrl(String.format("jdbc:postgresql://%s:%s/%s", INSTANCE_HOST, DB_PORT, DB_NAME));
    config.setUsername(DB_USER); // e.g. "root", "postgres"
    config.setPassword(DB_PASS); // e.g. "my-password"


    // ... Specify additional connection properties here.
    // ...

    // Initialize the connection pool using the configuration object.
    return new HikariDataSource(config);
  }
}

Node.js

์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ปจํ…์ŠคํŠธ์—์„œ ์ด ์Šค๋‹ˆํŽซ์„ ๋ณด๋ ค๋ฉด GitHub์˜ README๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.

const Knex = require('knex');
const fs = require('fs');

// createTcpPool initializes a TCP connection pool for a Cloud SQL
// instance of Postgres.
const createTcpPool = async config => {
  // Note: Saving credentials in environment variables is convenient, but not
  // secure - consider a more secure solution such as
  // Cloud Secret Manager (https://cloud.google.com/secret-manager) to help
  // keep secrets safe.
  const dbConfig = {
    client: 'pg',
    connection: {
      host: process.env.INSTANCE_HOST, // e.g. '127.0.0.1'
      port: process.env.DB_PORT, // e.g. '5432'
      user: process.env.DB_USER, // e.g. 'my-user'
      password: process.env.DB_PASS, // e.g. 'my-user-password'
      database: process.env.DB_NAME, // e.g. 'my-database'
    },
    // ... Specify additional properties here.
    ...config,
  };
  // Establish a connection to the database.
  return Knex(dbConfig);
};

Go

์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ปจํ…์ŠคํŠธ์—์„œ ์ด ์Šค๋‹ˆํŽซ์„ ๋ณด๋ ค๋ฉด GitHub์˜ README๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.

package cloudsql

import (
	"database/sql"
	"fmt"
	"log"
	"os"

	// Note: If connecting using the App Engine Flex Go runtime, use
	// "github.com/jackc/pgx/stdlib" instead, since v5 requires
	// Go modules which are not supported by App Engine Flex.
	_ "github.com/jackc/pgx/v5/stdlib"
)

// connectTCPSocket initializes a TCP connection pool for a Cloud SQL
// instance of Postgres.
func connectTCPSocket() (*sql.DB, error) {
	mustGetenv := func(k string) string {
		v := os.Getenv(k)
		if v == "" {
			log.Fatalf("Fatal Error in connect_tcp.go: %s environment variable not set.", k)
		}
		return v
	}
	// Note: Saving credentials in environment variables is convenient, but not
	// secure - consider a more secure solution such as
	// Cloud Secret Manager (https://cloud.google.com/secret-manager) to help
	// keep secrets safe.
	var (
		dbUser    = mustGetenv("DB_USER")       // e.g. 'my-db-user'
		dbPwd     = mustGetenv("DB_PASS")       // e.g. 'my-db-password'
		dbTCPHost = mustGetenv("INSTANCE_HOST") // e.g. '127.0.0.1' ('172.17.0.1' if deployed to GAE Flex)
		dbPort    = mustGetenv("DB_PORT")       // e.g. '5432'
		dbName    = mustGetenv("DB_NAME")       // e.g. 'my-database'
	)

	dbURI := fmt.Sprintf("host=%s user=%s password=%s port=%s database=%s",
		dbTCPHost, dbUser, dbPwd, dbPort, dbName)


	// dbPool is the pool of database connections.
	dbPool, err := sql.Open("pgx", dbURI)
	if err != nil {
		return nil, fmt.Errorf("sql.Open: %w", err)
	}

	// ...

	return dbPool, nil
}

PHP

์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ปจํ…์ŠคํŠธ์—์„œ ์ด ์Šค๋‹ˆํŽซ์„ ๋ณด๋ ค๋ฉด GitHub์˜ README๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.

namespace Google\Cloud\Samples\CloudSQL\Postgres;

use PDO;
use PDOException;
use RuntimeException;
use TypeError;

class DatabaseTcp
{
    public static function initTcpDatabaseConnection(): PDO
    {
        try {
            // Note: Saving credentials in environment variables is convenient, but not
            // secure - consider a more secure solution such as
            // Cloud Secret Manager (https://cloud.google.com/secret-manager) to help
            // keep secrets safe.
            $username = getenv('DB_USER'); // e.g. 'your_db_user'
            $password = getenv('DB_PASS'); // e.g. 'your_db_password'
            $dbName = getenv('DB_NAME'); // e.g. 'your_db_name'
            $instanceHost = getenv('INSTANCE_HOST'); // e.g. '127.0.0.1' ('172.17.0.1' for GAE Flex)

            // Connect using TCP
            $dsn = sprintf('pgsql:dbname=%s;host=%s', $dbName, $instanceHost);

            // Connect to the database
            $conn = new PDO(
                $dsn,
                $username,
                $password,
                # ...
            );
        } catch (TypeError $e) {
            throw new RuntimeException(
                sprintf(
                    'Invalid or missing configuration! Make sure you have set ' .
                        '$username, $password, $dbName, and $instanceHost (for TCP mode). ' .
                        'The PHP error was %s',
                    $e->getMessage()
                ),
                $e->getCode(),
                $e
            );
        } catch (PDOException $e) {
            throw new RuntimeException(
                sprintf(
                    'Could not connect to the Cloud SQL Database. Check that ' .
                        'your username and password are correct, that the Cloud SQL ' .
                        'proxy is running, and that the database exists and is ready ' .
                        'for use. For more assistance, refer to %s. The PDO error was %s',
                    'https://cloud.google.com/sql/docs/postgres/connect-external-app',
                    $e->getMessage()
                ),
                $e->getCode(),
                $e
            );
        }

        return $conn;
    }
}

๊ถŒ์žฅ์‚ฌํ•ญ ๋ฐ ๊ธฐํƒ€ ์ •๋ณด

๋กœ์ปฌ์—์„œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ํ…Œ์ŠคํŠธํ•  ๋•Œ Cloud SQL ์ธ์ฆ ํ”„๋ก์‹œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋น ๋ฅธ ์‹œ์ž‘: Cloud SQL ์ธ์ฆ ํ”„๋ก์‹œ ์‚ฌ์šฉ์„ ์ฐธ์กฐํ•˜์„ธ์š”.

์—ฐ๊ฒฐ ํ’€

๊ธฐ๋ณธ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋Œ€ํ•œ ์—ฐ๊ฒฐ์€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์„œ๋ฒ„ ์ž์ฒด์—์„œ ๋˜๋Š” Cloud Run Functions์˜ ๊ธฐ๋ฐ˜์ด ๋˜๋Š” ์ธํ”„๋ผ์—์„œ ์ค‘๋‹จ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ ์—ฐ๊ฒฐ์ด ์ค‘๋‹จ๋˜์—ˆ์„ ๋•Œ ์ž๋™์œผ๋กœ ๋‹ค์‹œ ์—ฐ๊ฒฐํ•˜๋Š” ์—ฐ๊ฒฐ ํ’€์„ ์ง€์›ํ•˜๋Š” ํด๋ผ์ด์–ธํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ํ•จ์ˆ˜์˜ ํ›„์† ํ˜ธ์ถœ์— ๊ฐ™์€ ์—ฐ๊ฒฐ์„ ๋‹ค์‹œ ์‚ฌ์šฉํ•  ๊ฐ€๋Šฅ์„ฑ์„ ๋†’์ด๊ณ  ์ธ์Šคํ„ด์Šค๊ฐ€ ์ œ๊ฑฐ๋  ๋•Œ ํ•ด๋‹น ์—ฐ๊ฒฐ์ด ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์ข…๋ฃŒ(์ž๋™ ์ถ•์†Œ)๋˜๋„๋ก ์ „์—ญ ๋ฒ”์œ„ ์—ฐ๊ฒฐ ํ’€์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ์—ฐ๊ฒฐ ํ’€ ์‚ฌ์šฉ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์ž์„ธํ•œ ์˜ˆ์‹œ๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ ๊ด€๋ฆฌ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

์—ฐ๊ฒฐ ํ•œ๋„

Cloud SQL์€ ๋™์‹œ ์—ฐ๊ฒฐ ์ˆ˜์— ์ตœ๋Œ€ ํ•œ๋„๋ฅผ ์ ์šฉํ•˜๋ฉฐ ์ด๋Ÿฌํ•œ ํ•œ๋„๋Š” ์„ ํƒํ•œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—”์ง„์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(Cloud SQL ํ• ๋‹น๋Ÿ‰ ๋ฐ ํ•œ๋„ ์ฐธ์กฐ). Cloud Run Functions์™€์˜ ์—ฐ๊ฒฐ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์ง€๋งŒ ์ตœ๋Œ€ ์—ฐ๊ฒฐ ์ˆ˜๋ฅผ 1๋กœ ์„ค์ •ํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.

๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์•ก์„ธ์Šคํ•ด์•ผ ํ•˜๋Š” ํ•จ์ˆ˜์˜ ์—ฐ๊ฒฐ ํ’€๋งŒ ์ดˆ๊ธฐํ™”ํ•˜๋„๋ก ์ฃผ์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ผ๋ถ€ ์—ฐ๊ฒฐ ํ’€์€ ์‚ฌ์ „์— ์—ฐ๊ฒฐ์„ ์ƒ์„ฑํ•˜๋ฏ€๋กœ ์ดˆ๊ณผ ๋ฆฌ์†Œ์Šค๋ฅผ ์†Œ๋น„ํ•˜๊ณ  ์—ฐ๊ฒฐ ์ œํ•œ์— ๋„๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ์ด์œ ๋กœ ์ง€์—ฐ๋œ ์ดˆ๊ธฐํ™”๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•„์š”ํ•  ๋•Œ๊นŒ์ง€ ์—ฐ๊ฒฐ ํ’€ ์ƒ์„ฑ์„ ์ง€์—ฐํ•˜๊ณ  ์‚ฌ์šฉ๋˜๋Š” ํ•จ์ˆ˜์—๋งŒ ์—ฐ๊ฒฐ ํ’€์„ ํฌํ•จํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

์—ฐ๊ฒฐ ์ˆ˜๋ฅผ ์ œํ•œํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์ž์„ธํ•œ ์˜ˆ์‹œ๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ ๊ด€๋ฆฌ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

API ํ• ๋‹น๋Ÿ‰ ํ•œ๋„

Cloud Run Functions๋Š” Cloud SQL Admin API๋ฅผ ์‚ฌ์šฉํ•˜๋Š” Cloud SQL ์ธ์ฆ ํ”„๋ก์‹œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—ฐ๊ฒฐํ•˜๋Š” ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. API ํ• ๋‹น๋Ÿ‰ ํ•œ๋„๊ฐ€ Cloud SQL ์ธ์ฆ ํ”„๋ก์‹œ์— ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ๋œ Cloud SQL Admin API ํ• ๋‹น๋Ÿ‰์€ ๋Œ€๋žต์ ์œผ๋กœ ๊ตฌ์„ฑ๋œ Cloud SQL ์ธ์Šคํ„ด์Šค ์ˆ˜์˜ 2๋ฐฐ์— ๋ฐฐํฌ๋œ ์ด ํ•จ์ˆ˜ ์ˆ˜๋ฅผ ๊ณฑํ•œ ๊ฐ’์ž…๋‹ˆ๋‹ค. ์˜ˆ์ƒ๋˜๋Š” API ํ• ๋‹น๋Ÿ‰์„ ์ˆ˜์ •ํ•˜๋ ค๋ฉด ์ตœ๋Œ€ ๋™์‹œ ํ˜ธ์ถœ ์ˆ˜๋ฅผ ์„ค์ •ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ Cloud Run Functions๋Š” 100์ดˆ๋งˆ๋‹ค ํ—ˆ์šฉ๋˜๋Š” API ํ˜ธ์ถœ ์ˆ˜์— ๋น„์œจ ์ œํ•œ์„ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ ๋‹จ๊ณ„