The gcp:sql/user:User resource, part of the Pulumi GCP provider, defines database users on Cloud SQL instances: their authentication method, privileges, and connection restrictions. This guide focuses on three capabilities: password-based authentication, database role assignment, and Cloud IAM authentication for users, service accounts, and groups.
Database users belong to Cloud SQL instances and may reference IAM identities or require specific database flags for IAM authentication. The examples are intentionally small. Combine them with your own instance configuration and access policies.
Create a user with password authentication
Most deployments start with traditional username/password authentication, where applications connect using credentials stored in configuration or secrets.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
import * as random from "@pulumi/random";
const dbNameSuffix = new random.index.Id("db_name_suffix", {byteLength: 4});
const main = new gcp.sql.DatabaseInstance("main", {
name: `main-instance-${dbNameSuffix.hex}`,
databaseVersion: "MYSQL_5_7",
settings: {
tier: "db-f1-micro",
},
});
const users = new gcp.sql.User("users", {
name: "me",
instance: main.name,
host: "me.com",
password: "changeme",
});
import pulumi
import pulumi_gcp as gcp
import pulumi_random as random
db_name_suffix = random.index.Id("db_name_suffix", byte_length=4)
main = gcp.sql.DatabaseInstance("main",
name=f"main-instance-{db_name_suffix['hex']}",
database_version="MYSQL_5_7",
settings={
"tier": "db-f1-micro",
})
users = gcp.sql.User("users",
name="me",
instance=main.name,
host="me.com",
password="changeme")
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/sql"
"github.com/pulumi/pulumi-random/sdk/v4/go/random"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
dbNameSuffix, err := random.NewId(ctx, "db_name_suffix", &random.IdArgs{
ByteLength: 4,
})
if err != nil {
return err
}
main, err := sql.NewDatabaseInstance(ctx, "main", &sql.DatabaseInstanceArgs{
Name: pulumi.Sprintf("main-instance-%v", dbNameSuffix.Hex),
DatabaseVersion: pulumi.String("MYSQL_5_7"),
Settings: &sql.DatabaseInstanceSettingsArgs{
Tier: pulumi.String("db-f1-micro"),
},
})
if err != nil {
return err
}
_, err = sql.NewUser(ctx, "users", &sql.UserArgs{
Name: pulumi.String("me"),
Instance: main.Name,
Host: pulumi.String("me.com"),
Password: pulumi.String("changeme"),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
using Random = Pulumi.Random;
return await Deployment.RunAsync(() =>
{
var dbNameSuffix = new Random.Index.Id("db_name_suffix", new()
{
ByteLength = 4,
});
var main = new Gcp.Sql.DatabaseInstance("main", new()
{
Name = $"main-instance-{dbNameSuffix.Hex}",
DatabaseVersion = "MYSQL_5_7",
Settings = new Gcp.Sql.Inputs.DatabaseInstanceSettingsArgs
{
Tier = "db-f1-micro",
},
});
var users = new Gcp.Sql.User("users", new()
{
Name = "me",
Instance = main.Name,
Host = "me.com",
Password = "changeme",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.random.Id;
import com.pulumi.random.IdArgs;
import com.pulumi.gcp.sql.DatabaseInstance;
import com.pulumi.gcp.sql.DatabaseInstanceArgs;
import com.pulumi.gcp.sql.inputs.DatabaseInstanceSettingsArgs;
import com.pulumi.gcp.sql.User;
import com.pulumi.gcp.sql.UserArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var dbNameSuffix = new Id("dbNameSuffix", IdArgs.builder()
.byteLength(4)
.build());
var main = new DatabaseInstance("main", DatabaseInstanceArgs.builder()
.name(String.format("main-instance-%s", dbNameSuffix.hex()))
.databaseVersion("MYSQL_5_7")
.settings(DatabaseInstanceSettingsArgs.builder()
.tier("db-f1-micro")
.build())
.build());
var users = new User("users", UserArgs.builder()
.name("me")
.instance(main.name())
.host("me.com")
.password("changeme")
.build());
}
}
resources:
dbNameSuffix:
type: random:Id
name: db_name_suffix
properties:
byteLength: 4
main:
type: gcp:sql:DatabaseInstance
properties:
name: main-instance-${dbNameSuffix.hex}
databaseVersion: MYSQL_5_7
settings:
tier: db-f1-micro
users:
type: gcp:sql:User
properties:
name: me
instance: ${main.name}
host: me.com
password: changeme
The name property sets the username, while password provides the credential. The host property restricts which IP addresses can connect (MySQL only; omit for PostgreSQL). The instance property links the user to a specific Cloud SQL instance.
Assign database roles for privilege management
PostgreSQL and MySQL 8+ support database roles that grant specific privileges without requiring manual GRANT statements after user creation.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
import * as random from "@pulumi/random";
const dbNameSuffix = new random.index.Id("db_name_suffix", {byteLength: 4});
const main = new gcp.sql.DatabaseInstance("main", {
name: `main-instance-${dbNameSuffix.hex}`,
databaseVersion: "POSTGRES_15",
settings: {
tier: "db-f1-micro",
},
});
const users = new gcp.sql.User("users", {
name: "me",
instance: main.name,
host: "me.com",
password: "changeme",
databaseRoles: ["cloudsqlsuperuser"],
});
import pulumi
import pulumi_gcp as gcp
import pulumi_random as random
db_name_suffix = random.index.Id("db_name_suffix", byte_length=4)
main = gcp.sql.DatabaseInstance("main",
name=f"main-instance-{db_name_suffix['hex']}",
database_version="POSTGRES_15",
settings={
"tier": "db-f1-micro",
})
users = gcp.sql.User("users",
name="me",
instance=main.name,
host="me.com",
password="changeme",
database_roles=["cloudsqlsuperuser"])
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/sql"
"github.com/pulumi/pulumi-random/sdk/v4/go/random"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
dbNameSuffix, err := random.NewId(ctx, "db_name_suffix", &random.IdArgs{
ByteLength: 4,
})
if err != nil {
return err
}
main, err := sql.NewDatabaseInstance(ctx, "main", &sql.DatabaseInstanceArgs{
Name: pulumi.Sprintf("main-instance-%v", dbNameSuffix.Hex),
DatabaseVersion: pulumi.String("POSTGRES_15"),
Settings: &sql.DatabaseInstanceSettingsArgs{
Tier: pulumi.String("db-f1-micro"),
},
})
if err != nil {
return err
}
_, err = sql.NewUser(ctx, "users", &sql.UserArgs{
Name: pulumi.String("me"),
Instance: main.Name,
Host: pulumi.String("me.com"),
Password: pulumi.String("changeme"),
DatabaseRoles: pulumi.StringArray{
pulumi.String("cloudsqlsuperuser"),
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
using Random = Pulumi.Random;
return await Deployment.RunAsync(() =>
{
var dbNameSuffix = new Random.Index.Id("db_name_suffix", new()
{
ByteLength = 4,
});
var main = new Gcp.Sql.DatabaseInstance("main", new()
{
Name = $"main-instance-{dbNameSuffix.Hex}",
DatabaseVersion = "POSTGRES_15",
Settings = new Gcp.Sql.Inputs.DatabaseInstanceSettingsArgs
{
Tier = "db-f1-micro",
},
});
var users = new Gcp.Sql.User("users", new()
{
Name = "me",
Instance = main.Name,
Host = "me.com",
Password = "changeme",
DatabaseRoles = new[]
{
"cloudsqlsuperuser",
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.random.Id;
import com.pulumi.random.IdArgs;
import com.pulumi.gcp.sql.DatabaseInstance;
import com.pulumi.gcp.sql.DatabaseInstanceArgs;
import com.pulumi.gcp.sql.inputs.DatabaseInstanceSettingsArgs;
import com.pulumi.gcp.sql.User;
import com.pulumi.gcp.sql.UserArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var dbNameSuffix = new Id("dbNameSuffix", IdArgs.builder()
.byteLength(4)
.build());
var main = new DatabaseInstance("main", DatabaseInstanceArgs.builder()
.name(String.format("main-instance-%s", dbNameSuffix.hex()))
.databaseVersion("POSTGRES_15")
.settings(DatabaseInstanceSettingsArgs.builder()
.tier("db-f1-micro")
.build())
.build());
var users = new User("users", UserArgs.builder()
.name("me")
.instance(main.name())
.host("me.com")
.password("changeme")
.databaseRoles("cloudsqlsuperuser")
.build());
}
}
resources:
dbNameSuffix:
type: random:Id
name: db_name_suffix
properties:
byteLength: 4
main:
type: gcp:sql:DatabaseInstance
properties:
name: main-instance-${dbNameSuffix.hex}
databaseVersion: POSTGRES_15
settings:
tier: db-f1-micro
users:
type: gcp:sql:User
properties:
name: me
instance: ${main.name}
host: me.com
password: changeme
databaseRoles:
- cloudsqlsuperuser
The databaseRoles property assigns predefined roles like cloudsqlsuperuser or custom roles you’ve created in the database. This extends basic password authentication with role-based access control, eliminating the need to run separate GRANT commands.
Authenticate with Cloud IAM identities
Cloud SQL IAM authentication eliminates password management by letting users and service accounts authenticate using their Google Cloud identities.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
import * as random from "@pulumi/random";
import * as std from "@pulumi/std";
const dbNameSuffix = new random.index.Id("db_name_suffix", {byteLength: 4});
const main = new gcp.sql.DatabaseInstance("main", {
name: `main-instance-${dbNameSuffix.hex}`,
databaseVersion: "POSTGRES_15",
settings: {
tier: "db-f1-micro",
databaseFlags: [{
name: "cloudsql.iam_authentication",
value: "on",
}],
},
});
const iamUser = new gcp.sql.User("iam_user", {
name: "me@example.com",
instance: main.name,
type: "CLOUD_IAM_USER",
});
const iamServiceAccountUser = new gcp.sql.User("iam_service_account_user", {
name: std.trimsuffix({
input: serviceAccount.email,
suffix: ".gserviceaccount.com",
}).then(invoke => invoke.result),
instance: main.name,
type: "CLOUD_IAM_SERVICE_ACCOUNT",
});
import pulumi
import pulumi_gcp as gcp
import pulumi_random as random
import pulumi_std as std
db_name_suffix = random.index.Id("db_name_suffix", byte_length=4)
main = gcp.sql.DatabaseInstance("main",
name=f"main-instance-{db_name_suffix['hex']}",
database_version="POSTGRES_15",
settings={
"tier": "db-f1-micro",
"database_flags": [{
"name": "cloudsql.iam_authentication",
"value": "on",
}],
})
iam_user = gcp.sql.User("iam_user",
name="me@example.com",
instance=main.name,
type="CLOUD_IAM_USER")
iam_service_account_user = gcp.sql.User("iam_service_account_user",
name=std.trimsuffix(input=service_account["email"],
suffix=".gserviceaccount.com").result,
instance=main.name,
type="CLOUD_IAM_SERVICE_ACCOUNT")
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/sql"
"github.com/pulumi/pulumi-random/sdk/v4/go/random"
"github.com/pulumi/pulumi-std/sdk/go/std"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
dbNameSuffix, err := random.NewId(ctx, "db_name_suffix", &random.IdArgs{
ByteLength: 4,
})
if err != nil {
return err
}
main, err := sql.NewDatabaseInstance(ctx, "main", &sql.DatabaseInstanceArgs{
Name: pulumi.Sprintf("main-instance-%v", dbNameSuffix.Hex),
DatabaseVersion: pulumi.String("POSTGRES_15"),
Settings: &sql.DatabaseInstanceSettingsArgs{
Tier: pulumi.String("db-f1-micro"),
DatabaseFlags: sql.DatabaseInstanceSettingsDatabaseFlagArray{
&sql.DatabaseInstanceSettingsDatabaseFlagArgs{
Name: pulumi.String("cloudsql.iam_authentication"),
Value: pulumi.String("on"),
},
},
},
})
if err != nil {
return err
}
_, err = sql.NewUser(ctx, "iam_user", &sql.UserArgs{
Name: pulumi.String("me@example.com"),
Instance: main.Name,
Type: pulumi.String("CLOUD_IAM_USER"),
})
if err != nil {
return err
}
invokeTrimsuffix, err := std.Trimsuffix(ctx, &std.TrimsuffixArgs{
Input: serviceAccount.Email,
Suffix: ".gserviceaccount.com",
}, nil)
if err != nil {
return err
}
_, err = sql.NewUser(ctx, "iam_service_account_user", &sql.UserArgs{
Name: pulumi.String(invokeTrimsuffix.Result),
Instance: main.Name,
Type: pulumi.String("CLOUD_IAM_SERVICE_ACCOUNT"),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
using Random = Pulumi.Random;
using Std = Pulumi.Std;
return await Deployment.RunAsync(() =>
{
var dbNameSuffix = new Random.Index.Id("db_name_suffix", new()
{
ByteLength = 4,
});
var main = new Gcp.Sql.DatabaseInstance("main", new()
{
Name = $"main-instance-{dbNameSuffix.Hex}",
DatabaseVersion = "POSTGRES_15",
Settings = new Gcp.Sql.Inputs.DatabaseInstanceSettingsArgs
{
Tier = "db-f1-micro",
DatabaseFlags = new[]
{
new Gcp.Sql.Inputs.DatabaseInstanceSettingsDatabaseFlagArgs
{
Name = "cloudsql.iam_authentication",
Value = "on",
},
},
},
});
var iamUser = new Gcp.Sql.User("iam_user", new()
{
Name = "me@example.com",
Instance = main.Name,
Type = "CLOUD_IAM_USER",
});
var iamServiceAccountUser = new Gcp.Sql.User("iam_service_account_user", new()
{
Name = Std.Trimsuffix.Invoke(new()
{
Input = serviceAccount.Email,
Suffix = ".gserviceaccount.com",
}).Apply(invoke => invoke.Result),
Instance = main.Name,
Type = "CLOUD_IAM_SERVICE_ACCOUNT",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.random.Id;
import com.pulumi.random.IdArgs;
import com.pulumi.gcp.sql.DatabaseInstance;
import com.pulumi.gcp.sql.DatabaseInstanceArgs;
import com.pulumi.gcp.sql.inputs.DatabaseInstanceSettingsArgs;
import com.pulumi.gcp.sql.User;
import com.pulumi.gcp.sql.UserArgs;
import com.pulumi.std.StdFunctions;
import com.pulumi.std.inputs.TrimsuffixArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var dbNameSuffix = new Id("dbNameSuffix", IdArgs.builder()
.byteLength(4)
.build());
var main = new DatabaseInstance("main", DatabaseInstanceArgs.builder()
.name(String.format("main-instance-%s", dbNameSuffix.hex()))
.databaseVersion("POSTGRES_15")
.settings(DatabaseInstanceSettingsArgs.builder()
.tier("db-f1-micro")
.databaseFlags(DatabaseInstanceSettingsDatabaseFlagArgs.builder()
.name("cloudsql.iam_authentication")
.value("on")
.build())
.build())
.build());
var iamUser = new User("iamUser", UserArgs.builder()
.name("me@example.com")
.instance(main.name())
.type("CLOUD_IAM_USER")
.build());
var iamServiceAccountUser = new User("iamServiceAccountUser", UserArgs.builder()
.name(StdFunctions.trimsuffix(TrimsuffixArgs.builder()
.input(serviceAccount.email())
.suffix(".gserviceaccount.com")
.build()).result())
.instance(main.name())
.type("CLOUD_IAM_SERVICE_ACCOUNT")
.build());
}
}
resources:
dbNameSuffix:
type: random:Id
name: db_name_suffix
properties:
byteLength: 4
main:
type: gcp:sql:DatabaseInstance
properties:
name: main-instance-${dbNameSuffix.hex}
databaseVersion: POSTGRES_15
settings:
tier: db-f1-micro
databaseFlags:
- name: cloudsql.iam_authentication
value: on
iamUser:
type: gcp:sql:User
name: iam_user
properties:
name: me@example.com
instance: ${main.name}
type: CLOUD_IAM_USER
iamServiceAccountUser:
type: gcp:sql:User
name: iam_service_account_user
properties:
name:
fn::invoke:
function: std:trimsuffix
arguments:
input: ${serviceAccount.email}
suffix: .gserviceaccount.com
return: result
instance: ${main.name}
type: CLOUD_IAM_SERVICE_ACCOUNT
When type is set to CLOUD_IAM_USER or CLOUD_IAM_SERVICE_ACCOUNT, users authenticate with their Google Cloud credentials instead of passwords. The database instance must have the cloudsql.iam_authentication flag enabled. For service accounts, the name must match the account identifier without the .gserviceaccount.com suffix.
Authenticate IAM groups for team access
IAM group authentication allows entire Google Groups to access databases, simplifying access management for teams.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
import * as random from "@pulumi/random";
const dbNameSuffix = new random.index.Id("db_name_suffix", {byteLength: 4});
const main = new gcp.sql.DatabaseInstance("main", {
name: `main-instance-${dbNameSuffix.hex}`,
databaseVersion: "MYSQL_8_0",
settings: {
tier: "db-f1-micro",
databaseFlags: [{
name: "cloudsql_iam_authentication",
value: "on",
}],
},
});
const iamGroupUser = new gcp.sql.User("iam_group_user", {
name: "iam_group@example.com",
instance: main.name,
type: "CLOUD_IAM_GROUP",
});
import pulumi
import pulumi_gcp as gcp
import pulumi_random as random
db_name_suffix = random.index.Id("db_name_suffix", byte_length=4)
main = gcp.sql.DatabaseInstance("main",
name=f"main-instance-{db_name_suffix['hex']}",
database_version="MYSQL_8_0",
settings={
"tier": "db-f1-micro",
"database_flags": [{
"name": "cloudsql_iam_authentication",
"value": "on",
}],
})
iam_group_user = gcp.sql.User("iam_group_user",
name="iam_group@example.com",
instance=main.name,
type="CLOUD_IAM_GROUP")
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/sql"
"github.com/pulumi/pulumi-random/sdk/v4/go/random"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
dbNameSuffix, err := random.NewId(ctx, "db_name_suffix", &random.IdArgs{
ByteLength: 4,
})
if err != nil {
return err
}
main, err := sql.NewDatabaseInstance(ctx, "main", &sql.DatabaseInstanceArgs{
Name: pulumi.Sprintf("main-instance-%v", dbNameSuffix.Hex),
DatabaseVersion: pulumi.String("MYSQL_8_0"),
Settings: &sql.DatabaseInstanceSettingsArgs{
Tier: pulumi.String("db-f1-micro"),
DatabaseFlags: sql.DatabaseInstanceSettingsDatabaseFlagArray{
&sql.DatabaseInstanceSettingsDatabaseFlagArgs{
Name: pulumi.String("cloudsql_iam_authentication"),
Value: pulumi.String("on"),
},
},
},
})
if err != nil {
return err
}
_, err = sql.NewUser(ctx, "iam_group_user", &sql.UserArgs{
Name: pulumi.String("iam_group@example.com"),
Instance: main.Name,
Type: pulumi.String("CLOUD_IAM_GROUP"),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
using Random = Pulumi.Random;
return await Deployment.RunAsync(() =>
{
var dbNameSuffix = new Random.Index.Id("db_name_suffix", new()
{
ByteLength = 4,
});
var main = new Gcp.Sql.DatabaseInstance("main", new()
{
Name = $"main-instance-{dbNameSuffix.Hex}",
DatabaseVersion = "MYSQL_8_0",
Settings = new Gcp.Sql.Inputs.DatabaseInstanceSettingsArgs
{
Tier = "db-f1-micro",
DatabaseFlags = new[]
{
new Gcp.Sql.Inputs.DatabaseInstanceSettingsDatabaseFlagArgs
{
Name = "cloudsql_iam_authentication",
Value = "on",
},
},
},
});
var iamGroupUser = new Gcp.Sql.User("iam_group_user", new()
{
Name = "iam_group@example.com",
Instance = main.Name,
Type = "CLOUD_IAM_GROUP",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.random.Id;
import com.pulumi.random.IdArgs;
import com.pulumi.gcp.sql.DatabaseInstance;
import com.pulumi.gcp.sql.DatabaseInstanceArgs;
import com.pulumi.gcp.sql.inputs.DatabaseInstanceSettingsArgs;
import com.pulumi.gcp.sql.User;
import com.pulumi.gcp.sql.UserArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var dbNameSuffix = new Id("dbNameSuffix", IdArgs.builder()
.byteLength(4)
.build());
var main = new DatabaseInstance("main", DatabaseInstanceArgs.builder()
.name(String.format("main-instance-%s", dbNameSuffix.hex()))
.databaseVersion("MYSQL_8_0")
.settings(DatabaseInstanceSettingsArgs.builder()
.tier("db-f1-micro")
.databaseFlags(DatabaseInstanceSettingsDatabaseFlagArgs.builder()
.name("cloudsql_iam_authentication")
.value("on")
.build())
.build())
.build());
var iamGroupUser = new User("iamGroupUser", UserArgs.builder()
.name("iam_group@example.com")
.instance(main.name())
.type("CLOUD_IAM_GROUP")
.build());
}
}
resources:
dbNameSuffix:
type: random:Id
name: db_name_suffix
properties:
byteLength: 4
main:
type: gcp:sql:DatabaseInstance
properties:
name: main-instance-${dbNameSuffix.hex}
databaseVersion: MYSQL_8_0
settings:
tier: db-f1-micro
databaseFlags:
- name: cloudsql_iam_authentication
value: on
iamGroupUser:
type: gcp:sql:User
name: iam_group_user
properties:
name: iam_group@example.com
instance: ${main.name}
type: CLOUD_IAM_GROUP
Setting type to CLOUD_IAM_GROUP grants database access to all members of a Google Group. The database instance must have the cloudsql_iam_authentication flag enabled. This approach centralizes access control in Google Groups rather than managing individual database users.
Beyond these examples
These snippets focus on specific user-level features: password and IAM-based authentication, database role assignment, and user and group identity types. They’re intentionally minimal rather than full access management solutions.
The examples may reference pre-existing infrastructure such as Cloud SQL database instances, and IAM service accounts and Google Groups for IAM examples. They focus on configuring the user rather than provisioning the surrounding infrastructure.
To keep things focused, common user patterns are omitted, including:
- Password policies (passwordPolicy)
- Deletion policies for role-granted users (deletionPolicy)
- Write-only password handling (passwordWo)
- Host restrictions for MySQL (host property nuances)
These omissions are intentional: the goal is to illustrate how each user authentication method is wired, not provide drop-in access management modules. See the Cloud SQL User resource reference for all available configuration options.
Let's create GCP Cloud SQL Users
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Authentication & IAM
type to CLOUD_IAM_USER or CLOUD_IAM_SERVICE_ACCOUNT, enable the cloudsql.iam_authentication database flag on your instance, and omit the password field entirely.password or passwordWo for CLOUD_IAM_USER or CLOUD_IAM_SERVICE_ACCOUNT user types, as these authenticate via IAM credentials instead.passwordWo is write-only and won’t appear in state or read operations. Use passwordWo when you want to avoid storing passwords in state.type to CLOUD_IAM_GROUP, enable the appropriate IAM authentication flag (cloudsql_iam_authentication for MySQL or cloudsql.iam_authentication for Postgres), and use the group email as the name.CLOUD_IAM_SERVICE_ACCOUNT type, remove the .gserviceaccount.com suffix from the service account email using a function like trimsuffix.Database-Specific Behavior
host field is only supported for BUILT_IN users in MySQL instances. Don’t set it for PostgreSQL or SQL Server.databaseRoles property with role names like cloudsqlsuperuser (MySQL 8+ and PostgreSQL only). Custom roles must be created in the database first using the CREATE ROLE statement.User Management & Lifecycle
deletionPolicy to ABANDON to allow Pulumi to abandon the resource instead of attempting deletion.host, instance, name, project, and type properties are immutable and require resource replacement if changed.databaseRoles property is write-only and won’t be read from the API or appear in state after creation.