Skip to content

Commit bcb2b27

Browse files
feat(cloudsql): add MySQL Auto IAM AuthN sample (GoogleCloudPlatform#8526)
1 parent 2be381f commit bcb2b27

File tree

5 files changed

+87
-4
lines changed

5 files changed

+87
-4
lines changed

cloud-sql/mysql/sqlalchemy/app.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import sqlalchemy
2323

2424
from connect_connector import connect_with_connector
25+
from connect_connector_auto_iam_authn import connect_with_connector_auto_iam_authn
2526
from connect_tcp import connect_tcp_socket
2627
from connect_unix import connect_unix_socket
2728

@@ -41,7 +42,9 @@ def init_connection_pool() -> sqlalchemy.engine.base.Engine:
4142

4243
# use the connector when INSTANCE_CONNECTION_NAME (e.g. project:region:instance) is defined
4344
if os.environ.get("INSTANCE_CONNECTION_NAME"):
44-
return connect_with_connector()
45+
# Either a DB_USER or a DB_IAM_USER should be defined. If both are
46+
# defined, DB_IAM_USER takes precedence.
47+
return connect_with_connector_auto_iam_authn() if os.environ.get("DB_IAM_USER") else connect_with_connector()
4548

4649
raise ValueError(
4750
"Missing database connection type. Please define one of INSTANCE_HOST, INSTANCE_UNIX_SOCKET, or INSTANCE_CONNECTION_NAME"
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# Copyright 2022 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# [START cloud_sql_mysql_sqlalchemy_auto_iam_authn]
16+
import os
17+
18+
from google.cloud.sql.connector import Connector, IPTypes
19+
import pymysql
20+
21+
import sqlalchemy
22+
23+
24+
# connect_with_connector_auto_iam_authn initializes a connection pool for
25+
# a Cloud SQL instance of MySQL using the Cloud SQL Python Connector
26+
# with Automatic IAM Database Authentication.
27+
def connect_with_connector_auto_iam_authn() -> sqlalchemy.engine.base.Engine:
28+
# Note: Saving credentials in environment variables is convenient, but not
29+
# secure - consider a more secure solution such as
30+
# Cloud Secret Manager (https://cloud.google.com/secret-manager) to help
31+
# keep secrets safe.
32+
instance_connection_name = os.environ["INSTANCE_CONNECTION_NAME"] # e.g. 'project:region:instance'
33+
db_iam_user = os.environ["DB_IAM_USER"] # e.g. 'sa-name@project-id.iam'
34+
db_name = os.environ["DB_NAME"] # e.g. 'my-database'
35+
36+
ip_type = IPTypes.PRIVATE if os.environ.get("PRIVATE_IP") else IPTypes.PUBLIC
37+
38+
# initialize Cloud SQL Python Connector object
39+
connector = Connector()
40+
41+
def getconn() -> pymysql.connections.Connection:
42+
conn: pymysql.connections.Connection = connector.connect(
43+
instance_connection_name,
44+
"pymysql",
45+
user=db_iam_user,
46+
db=db_name,
47+
enable_iam_auth=True,
48+
ip_type=ip_type,
49+
)
50+
return conn
51+
52+
# The Cloud SQL Python Connector can be used with SQLAlchemy
53+
# using the 'creator' argument to 'create_engine'
54+
pool = sqlalchemy.create_engine(
55+
"mysql+pymysql://",
56+
creator=getconn,
57+
# [START_EXCLUDE]
58+
# Pool size is the maximum number of permanent connections to keep.
59+
pool_size=5,
60+
61+
# Temporarily exceeds the set pool_size if no connections are available.
62+
max_overflow=2,
63+
64+
# The total number of concurrent connections for your application will be
65+
# a total of pool_size and max_overflow.
66+
67+
# 'pool_timeout' is the maximum number of seconds to wait when retrieving a
68+
# new connection from the pool. After the specified amount of time, an
69+
# exception will be thrown.
70+
pool_timeout=30, # 30 seconds
71+
72+
# 'pool_recycle' is the maximum number of seconds a connection can persist.
73+
# Connections that live longer than the specified amount of time will be
74+
# re-established
75+
pool_recycle=1800, # 30 minutes
76+
# [END_EXCLUDE]
77+
)
78+
return pool
79+
80+
# [END cloud_sql_mysql_sqlalchemy_auto_iam_authn]

cloud-sql/mysql/sqlalchemy/requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ Flask==2.1.0
22
SQLAlchemy==1.4.38
33
PyMySQL==1.0.2
44
gunicorn==20.1.0
5-
cloud-sql-python-connector==0.6.0
5+
cloud-sql-python-connector==1.0.0
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
Flask==2.1.0
22
pg8000==1.24.2
33
SQLAlchemy==1.4.38
4-
cloud-sql-python-connector==0.6.1
4+
cloud-sql-python-connector==1.0.0
55
gunicorn==20.1.0

cloud-sql/sql-server/sqlalchemy/requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ gunicorn==20.1.0
33
python-tds==1.11.0
44
pyopenssl==22.1.0
55
SQLAlchemy==1.4.38
6-
cloud-sql-python-connector==0.6.1
6+
cloud-sql-python-connector==1.0.0
77
sqlalchemy-pytds==0.3.4

0 commit comments

Comments
 (0)