admin管理员组文章数量:1122832
I am trying to connect to a PostgreSQL database instance in Google Cloud (with a private IP connection) using the SQL Connector library in Go. However, I am encountering the following error:
ERROR Failed to dial instance {"error": "failed to get instance: Refresh error: failed to get instance metadata (connection name = \"<connection-string>\"): Get \"/\/instances/postgres/connectSettings?alt=json&prettyPrint=false\": compute: Received 403 `Unable to generate access token; IAM returned 403 Forbidden: Permission 'iam.serviceAccounts.getAccessToken' denied on resource (or it may not exist).
This error could be caused by a missing IAM policy binding on the target IAM service account.
For more information, refer to the Workload Identity documentation:
Environment Details:
Google Cloud: PostgreSQL instance with private IP connection enabled
Service Account Permissions:
- Cloud SQL Admin
- Cloud SQL Client
- Compute Network Admin
- Project IAM Admin
- Service Account Admin
- Service Account Token Creator
- Storage Admin
- Workload Identity User
Go Environment: Running the code in a VM instance that is part of the GKE cluster in the same VPC.
Here’s the relevant portion of my Go code:
func connectDB() error {
user := "postgres"
password := "password"
connectionName := "connectionName"
sslmode := "require"
dbName := "databaseName"
config, err := pgx.ParseConfig(connStr)
if err != nil {
return err
}
opts := append([]cloudsqlconn.Option{},
cloudsqlconn.WithDefaultDialOptions(cloudsqlconn.WithPrivateIP()),
)
d, err := cloudsqlconn.NewDialer(context.Background(), opts...)
if err != nil {
return err
}
config.DialFunc = func(ctx context.Context, network, instance string) (net.Conn, error) {
log.FromContext(ctx).Info(fmt.Sprintf("Dialing instance: %s", instance))
conn, err := d.Dial(ctx, connectionName)
if err != nil {
log.FromContext(ctx).Error(err, "Failed to dial instance")
}
return conn, err
}
dbURI := stdlib.RegisterConnConfig(config)
dbPool, err := sql.Open("pgx", dbURI)
if err != nil {
return err
}
err = dbPool.Ping()
if err != nil {
return err
}
return nil
}
Troubleshooting Attempts:
Verified that the database instance has a private IP and is reachable within the same VPC. Checked and ensured that the service account has the following permissions: Cloud SQL Admin Cloud SQL Client Service Account Token Creator Workload Identity User, among others. Ensured that the Go application is running inside a VM that has access to the private VPC.
I am trying to connect to a PostgreSQL database instance in Google Cloud (with a private IP connection) using the SQL Connector library in Go. However, I am encountering the following error:
ERROR Failed to dial instance {"error": "failed to get instance: Refresh error: failed to get instance metadata (connection name = \"<connection-string>\"): Get \"https://sqladmin.googleapis.com/sql/v1beta4/projects/\/instances/postgres/connectSettings?alt=json&prettyPrint=false\": compute: Received 403 `Unable to generate access token; IAM returned 403 Forbidden: Permission 'iam.serviceAccounts.getAccessToken' denied on resource (or it may not exist).
This error could be caused by a missing IAM policy binding on the target IAM service account.
For more information, refer to the Workload Identity documentation:
Environment Details:
Google Cloud: PostgreSQL instance with private IP connection enabled
Service Account Permissions:
- Cloud SQL Admin
- Cloud SQL Client
- Compute Network Admin
- Project IAM Admin
- Service Account Admin
- Service Account Token Creator
- Storage Admin
- Workload Identity User
Go Environment: Running the code in a VM instance that is part of the GKE cluster in the same VPC.
Here’s the relevant portion of my Go code:
func connectDB() error {
user := "postgres"
password := "password"
connectionName := "connectionName"
sslmode := "require"
dbName := "databaseName"
config, err := pgx.ParseConfig(connStr)
if err != nil {
return err
}
opts := append([]cloudsqlconn.Option{},
cloudsqlconn.WithDefaultDialOptions(cloudsqlconn.WithPrivateIP()),
)
d, err := cloudsqlconn.NewDialer(context.Background(), opts...)
if err != nil {
return err
}
config.DialFunc = func(ctx context.Context, network, instance string) (net.Conn, error) {
log.FromContext(ctx).Info(fmt.Sprintf("Dialing instance: %s", instance))
conn, err := d.Dial(ctx, connectionName)
if err != nil {
log.FromContext(ctx).Error(err, "Failed to dial instance")
}
return conn, err
}
dbURI := stdlib.RegisterConnConfig(config)
dbPool, err := sql.Open("pgx", dbURI)
if err != nil {
return err
}
err = dbPool.Ping()
if err != nil {
return err
}
return nil
}
Troubleshooting Attempts:
Verified that the database instance has a private IP and is reachable within the same VPC. Checked and ensured that the service account has the following permissions: Cloud SQL Admin Cloud SQL Client Service Account Token Creator Workload Identity User, among others. Ensured that the Go application is running inside a VM that has access to the private VPC.
Share Improve this question asked Nov 22, 2024 at 12:39 piyushpiyush 531 silver badge3 bronze badges 5 |1 Answer
Reset to default 0Notice this part of the error you linked: "Permission 'iam.serviceAccounts.getAccessToken' denied on resource (or it may not exist)". The only two roles that you mentioned that have that particular permissions are
- Service Account Token Creator
- Workload Identity User
In the documentation, only workload identity user is mentioned, so I would to try to troubleshoot where that role is mentioned:
- Follow this best practice if you did not
- Make sure you complete all the steps as per the doc. Tips: make sure you complete all the required steps, 1 to 6 ( from namespace creation to policy to impersonation to annotation). For step 5, do you get
The member name must include the namespace and Kubernetes ServiceAccount name. For example, serviceAccount:example-project.svc.id.goog[example-namespace/example-serviceaccount].
Other troubleshooting steps you can take for Workload Identity Federation for GKE
Check step 5 (Check that the IAM service account is configured correctly)
gcloud iam service-accounts get-iam-policy \
GSA_NAME@GSA_PROJECT.iam.gserviceaccount.com
Expected:
- members:
- serviceAccount:PROJECT_ID.svc.id.goog[NAMESPACE/KSA_NAME]
role: roles/iam.workloadIdentityUser
本文标签:
版权声明:本文标题:Unable to connect to Google Cloud SQL PostgreSQL instance (private IP) using Go SQL Connector: iam.serviceAccounts.getAccessToke 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736303742a1931991.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
Service Account Token Creator
role instead of the Workload Identity service account. – Jack Wotherspoon Commented Nov 28, 2024 at 15:41