This document describes how to set up private IP connections to your
Cloud SQL instance by using [private services access](https://docs.cloud.google.com/sql/docs/mysql/about-private-services-access.md.txt).

## Before you begin

Cloud SQL requires **private services access** for each
VPC network that's used for private IP connections.

### Enable required APIs

Enable the Service Networking API (`servicenetworking.googleapis.com`)
and the Compute Engine API (`compute.googleapis.com`) in the project
that hosts your Cloud SQL instance.

If you're using a [Shared VPC network](https://docs.cloud.google.com/vpc/docs/shared-vpc.md.txt),
then you must also enable these APIs in the Shared VPC host project.

You can enable the APIs using the following command:

```bash
gcloud services enable servicenetworking.googleapis.com compute.googleapis.com --project=PROJECT_ID
```

Replace `PROJECT_ID` with your project ID (or the Shared VPC host project ID).

If the Service Networking API isn't enabled, then when you create the Cloud SQL
instance with a private IP address, the operation fails with a `SERVICE_NETWORKING_NOT_ENABLED` error.

### Required roles and permissions


To get the permissions that
you need to create and manage a private services access connection,

ask your administrator to grant you the
[Compute Network Admin](https://docs.cloud.google.com/iam/docs/roles-permissions/compute.md.txt#compute.networkAdmin) (`roles/compute.networkAdmin`) IAM role on on the project that hosts your Cloud SQL instance.


For more information about granting roles, see [Manage access to projects, folders, and organizations](https://docs.cloud.google.com/iam/docs/granting-changing-revoking-access.md.txt).


This predefined role contains

the permissions required to create and manage a private services access connection. To see the exact permissions that are
required, expand the **Required permissions** section:


#### Required permissions

The following permissions are required to create and manage a private services access connection:

- `compute.addresses.create`
- `compute.addresses.list`
- `compute.globalAddresses.create`
- `compute.globalAddresses.createInternal`
- `compute.globalAddresses.list`
- `compute.networks.list`
- `compute.networks.use`
- `servicenetworking.services.addPeering`
- `serviceusage.services.list`


You might also be able to get
these permissions
with [custom roles](https://docs.cloud.google.com/iam/docs/creating-custom-roles.md.txt) or
other [predefined roles](https://docs.cloud.google.com/iam/docs/roles-overview.md.txt#predefined).

If you're using a [Shared VPC network](https://docs.cloud.google.com/vpc/docs/shared-vpc.md.txt), you must also grant the Compute Network Admin (`roles/compute.networkAdmin`) role to the user in the Shared VPC host project.

## Configure private services access for Cloud SQL

> [!IMPORTANT]
> **Important:** When you create a private connection between your VPC network and the Cloud SQL service, it becomes available for use by any Google service that supports private services access. If you later delete the private connection, you remove private connectivity to your Cloud SQL instances and *any other service that is using
> that connection*. Removing the private connection does not delete or deprovision any resources.

There are two parts to the private services access configuration process:

- Select an existing, or allocate a new IP address range.

  If you create your Cloud SQL instance in the Google Cloud console,
  then you also have the option of letting Google
  allocate an IP address range for you. In this case, Google will
  allocate an IP range of prefix-length `/24` automatically and
  use the name **default-ip-range**.

  If you plan to create Cloud SQL instances in multiple regions or
  for different database types, then you must have a minimum `/24` range of
  IP addresses available for each region or database type. This includes
  other applications such as [Filestore](https://docs.cloud.google.com/filestore/docs.md.txt)
  or [Memorystore](https://docs.cloud.google.com/memorystore/docs.md.txt).
  For a new region or database type, Cloud SQL must have a free `/24` range.
- Create the private services connection from your VPC network to the underlying service producer network.

For information about the network and application environment
requirements and the IAM permissions needed for private services
access, see [Requirements for private IP connections](https://docs.cloud.google.com/sql/docs/mysql/private-ip.md.txt#reqs).

### Allocate an IP address range

### Console

1. In the Google Cloud console, go to the **VPC networks** page.

   [Go to VPC networks](https://console.cloud.google.com/networking/networks)
2. Select the VPC network that you want to use.
3. Select the **Private services access** tab.
4. Select the **Allocated IP ranges for services** tab.
5. Click **Allocate IP range**.
6. For the **Name** of the allocated range, specify `google-managed-services-VPC_NETWORK_NAME`, where `VPC_NETWORK_NAME` is the name of the VPC network you are connecting (for example, `google-managed-services-default`). The **Description** is optional.
7. Select the **Custom** option, then enter the IP address range to allocate, in CIDR notation.
8. Click **Allocate** to create the allocated range.

### gcloud

Do one of the following:

- To specify an address range and a prefix length (subnet mask), use the `addresses` and `prefix-length` flags. For example, to allocate the CIDR block `192.168.0.0/16`, specify `192.168.0.0` for the address and `16` for the prefix length.

```bash
    gcloud compute addresses create google-managed-services-VPC_NETWORK_NAME \
       --global \
       --purpose=VPC_PEERING \
       --addresses=192.168.0.0 \
       --prefix-length=16 \
       --network=projects/PROJECT_ID/global/networks/VPC_NETWORK_NAME
    
```
- To specify a prefix length (subnet mask) only, use the `prefix-length` flag. When you omit the address range, Google Cloud automatically selects an unused address range in your VPC network. The following example selects an unused IP address range with a `16` bit prefix length.

```bash
  gcloud compute addresses create google-managed-services-VPC_NETWORK_NAME \
    --global \
    --purpose=VPC_PEERING \
    --prefix-length=16 \
    --network=projects/PROJECT_ID/global/networks/VPC_NETWORK_NAME
  
```

Replace `VPC_NETWORK_NAME` with the name of your VPC
network, such as `my-vpc-network`.

The following example allocates an IP range that allows resources in the
VPC network `my-vpc-network` to connect to Cloud SQL
instances using private IP.

```bash
  gcloud compute addresses create google-managed-services-my-vpc-network \
    --global \
    --purpose=VPC_PEERING \
    --prefix-length=16 \
    --network=projects/myprojectid/global/networks/myvpcnetwork \
    --project=my-project
    
```

### Terraform

To allocate an IP address range,
use a [Terraform resource](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_global_address).

```terraform
resource "google_compute_global_address" "private_ip_address" {
  name          = "private-ip-address"
  purpose       = "VPC_PEERING"
  address_type  = "INTERNAL"
  prefix_length = 16
  network       = google_compute_network.peering_network.id
}
```

#### Apply the changes

To apply your Terraform configuration in a Google Cloud project, complete the steps in the
following sections.

## Prepare Cloud Shell

1. Launch [Cloud Shell](https://shell.cloud.google.com/).
2. Set the default Google Cloud project
   where you want to apply your Terraform configurations.

   You only need to run this command once per project, and you can run it in any directory.

   ```
   export GOOGLE_CLOUD_PROJECT=PROJECT_ID
   ```

   Environment variables are overridden if you set explicit values in the Terraform
   configuration file.

## Prepare the directory

Each Terraform configuration file must have its own directory (also
called a *root module*).

1. In [Cloud Shell](https://shell.cloud.google.com/), create a directory and a new file within that directory. The filename must have the `.tf` extension---for example `main.tf`. In this tutorial, the file is referred to as `main.tf`.

   ```
   mkdir DIRECTORY && cd DIRECTORY && touch main.tf
   ```
2. If you are following a tutorial, you can copy the sample code in each section or step.

   Copy the sample code into the newly created `main.tf`.

   Optionally, copy the code from GitHub. This is recommended
   when the Terraform snippet is part of an end-to-end solution.
3. Review and modify the sample parameters to apply to your environment.
4. Save your changes.
5. Initialize Terraform. You only need to do this once per directory.

   ```
   terraform init
   ```

   Optionally, to use the latest Google provider version, include the `-upgrade`
   option:

   ```
   terraform init -upgrade
   ```

## Apply the changes

1. Review the configuration and verify that the resources that Terraform is going to create or update match your expectations:

   ```
   terraform plan
   ```

   Make corrections to the configuration as necessary.
2. Apply the Terraform configuration by running the following command and entering `yes` at the prompt:

   ```
   terraform apply
   ```

   Wait until Terraform displays the "Apply complete!" message.
3. [Open your Google Cloud project](https://console.cloud.google.com/) to view the results. In the Google Cloud console, navigate to your resources in the UI to make sure that Terraform has created or updated them.

> [!NOTE]
> **Note:** Terraform samples typically assume that the required APIs are enabled in your Google Cloud project.

#### Delete the changes

Remove resources previously applied with your Terraform configuration by running the following
command and entering `yes` at the prompt:

```
terraform destroy
```

### Create a private connection

### Console

1. In the Google Cloud console, go to the **VPC networks** page.

   [Go to VPC networks](https://console.cloud.google.com/networking/networks)
2. Select the VPC network that you want to use.
3. Select the **Private service connection** tab.
4. Select the **Private connections to services** tab.
5. Click **Create connection** to create a private connection between your network and a service producer.
6. For the **Assigned allocation**, select one or more existing allocated ranges that are not being used by other service producers.
7. Click **Connect** to create the connection.

### gcloud

1. Create a private services access connection for the VPC
   network in your project.

   ```bash
   gcloud services vpc-peerings connect \
   --service=servicenetworking.googleapis.com \
   --ranges=google-managed-services-VPC_NETWORK_NAME \
   --network=VPC_NETWORK_NAME \
   --project=PROJECT_ID
   ```

   The command initiates a long-running Cloud SQL instance operation,
   returning an operation ID.
2. Check whether the operation was successful.

   ```bash
   gcloud services vpc-peerings operations describe \
   --name=OPERATION_ID
   ```

You can specify more than one allocated range when you create a private
connection. For example, if a range has been exhausted, you can assign
additional allocated ranges. The service uses IP addresses from all the
provided ranges in the order that you specified.

### Terraform

To create a private connection, use a [Terraform resource](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/service_networking_connection).


```terraform
resource "google_service_networking_connection" "default" {
  network                 = google_compute_network.peering_network.id
  service                 = "servicenetworking.googleapis.com"
  reserved_peering_ranges = [google_compute_global_address.private_ip_address.name]
}
```

<br />

<br />

<br />

A service account in the `service-HOST_PROJECT_NUMBER@service-networking.iam.gserviceaccount.com` format is granted the `servicenetworking.serviceAgent` role
while the private connection is created because the account is provisioned [just-in-time](https://docs.cloud.google.com/service-infrastructure/docs/service-networking/getting-started.md.txt#enabling_the_service).

If you see an error about either the `compute.globalAddresses.list` permission or
the `compute.projects.get` permission for the project, run this `gcloud` command:

```bash
gcloud projects add-iam-policy-binding HOST_PROJECT_NAME \
    --member=serviceAccount:service-HOST_PROJECT_NUMBER@service-networking.iam.gserviceaccount.com \
    --role=roles/servicenetworking.serviceAgent
```

> [!NOTE]
> **Troubleshooting:** If you experience connection timeouts or errors connecting to your instance over private IP or VPC Network Peering, then see [Diagnose VPC network and private IP connection failures](https://docs.cloud.google.com/sql/docs/mysql/debugging-connectivity.md.txt#diagnose-vpc-connectivity).

## Configure an instance for private IP using private services access

You can configure private services access for new instances and existing
instances.

### Configure private IP for a new instance

### Console

1. In the Google Cloud console, go to the **Cloud SQL Instances** page.

   [Go to Cloud SQL Instances](https://console.cloud.google.com/sql)
2. Click **Create instance**.
3. In the **Customize your instance** section, expand **Show
   configuration options**.
4. Expand **Connections**.
5. Select **Private IP**.
6. Select **Private Service Access (PSA)** .

   A drop-down list shows the available VPC networks in
   your project. If your project is the service project of a
   [Shared VPC](https://docs.cloud.google.com/vpc/docs/shared-vpc.md.txt),
   then VPC networks from the host project are also shown.
7. Select the VPC network you want to use.
8. If you see a message indicating that you need to set up a private service connection, do the following:
   1. Click **Set up connection**.
   2. In the **Allocate an IP range** section, select one of the following options:
      - Select one or more existing IP ranges or create a new one from the drop-down. The drop-down includes previously allocated ranges, if there are any, or you can select **Allocate a new IP range** and enter a new range and name.
      - **Use an automatically allocated IP range in your network**.

      > [!NOTE]
      > **Note:**You can specify an address range only for a primary instance, not for a read replica or clone.

   3. Click **Continue**.
   4. Click **Create connection**.
   5. Verify that you see the message: `Private service connection for
      network VPC_NETWORK_NAME has been successfully created`.
9. Optionally, you can specify an allocated IP range for your instances to use for connections.
   1. Expand **Show allocated IP range option**.
   2. Select an IP range from the drop-down menu.
10. Optional. If you want to allow other Google Cloud services, such as BigQuery, to access data in Cloud SQL and make queries against this data over a private IP connection, then select **Enable
    private path**.
11. Finish configuring your instance.
12. Click **Create instance**.

### gcloud

Before you create an instance using a private IP address, ensure that your
project is configured for
[private
services access](https://docs.cloud.google.com/sql/docs/mysql/about-private-services-access).

> [!CAUTION]
> **Prerequisites for Private IP using private services access on new projects:**
>
> If you are creating a private IP instance in a new or empty project, then
> you must first enable the Service Networking API. Next, establish VPC Network Peering with Google Cloud services. Otherwise, instance creation will fail with `SERVICE_NETWORKING_NOT_ENABLED` or `NETWORK_NOT_PEERED`.

Run the following [gcloud CLI](https://docs.cloud.google.com/sdk/gcloud.md.txt) commands to set up private services access networking for Cloud SQL:

1. **Enable the required APIs:**

   ```bash
   gcloud services enable \
       sqladmin.googleapis.com \
       compute.googleapis.com \
       servicenetworking.googleapis.com \
       --project=PROJECT_ID
       
   ```
2. **Allocate an IP address range for VPC Network Peering:**

   ```bash
   gcloud compute addresses create google-managed-services-VPC_NETWORK_NAME \
       --global \
       --purpose=VPC_PEERING \
       --prefix-length=16 \
       --network=projects/NETWORK_PROJECT_ID/global/networks/VPC_NETWORK_NAME \
       --project=PROJECT_ID
       
   ```
3. **Establish the VPC Network Peering connection:**

   ```bash
   gcloud services vpc-peerings connect \
       --service=servicenetworking.googleapis.com \
       --ranges=google-managed-services-VPC_NETWORK_NAME \
       --network=VPC_NETWORK_NAME \
       --project=PROJECT_ID
       
   ```

Before using any of the request data, make the following replacements:

- `INSTANCE_ID`: The instance ID
- `PROJECT_ID`: The project ID
- `NETWORK_PROJECT_ID`: The project ID of the VPC network

  > [!NOTE]
  > **Note:** If the VPC network is a Shared VPC, then `PROJECT_ID` must be the ID of the Shared VPC service project, and `NETWORK_PROJECT_ID` must be the ID of the Shared VPC host project.

- `VPC_NETWORK_NAME`: The name of the VPC network
- `RANGE_NAME`: *Optional.* If specified, sets a range name for which an IP range is allocated. The range name must comply with [`RFC-1035`](https://datatracker.ietf.org/doc/html/rfc1035) and contain 1-63 characters.
- `REGION_NAME`: The region name

To specify the name of your VPC network, use the `--network` parameter. To disable public IP, use the `--no-assign-ip` flag.


Also, optionally, use the `--enable-google-private-path` parameter
to allow other Google Cloud services such as BigQuery to
access data in Cloud SQL and make queries against this data over a
private IP connection. This parameter is valid only if:

- You use the `--no-assign-ip` parameter.
- You use the `--network` parameter to specify the name of the VPC network that you want to use to create a private connection.

To enforce the use of the new network architecture for the instance, use the [`--enforce-new-sql-network-architecture`](https://docs.cloud.google.com/sdk/gcloud/reference/beta/sql/instances/create.md.txt#--enforce-new-sql-network-architecture) flag. Make sure that you have allocated enough IP addresses. When you use new network architecture enforcement before a project is fully upgraded, you might experience instance creation failure if sufficient IP address space isn't available. For more information, see [Upgrade
an instance to the new network architecture](https://docs.cloud.google.com/sql/docs/mysql/upgrade-cloud-sql-instance-new-network-architecture) and [Allocate an IP address range](https://docs.cloud.google.com/sql/docs/mysql/configure-private-services-access.md.txt#allocate-ip-address-range).

> [!NOTE]
> **Note:** After you create an instance, you can't assign an allocated range name for that instance. After you assign a range to an instance, you can't modify the range.

```bash
gcloud beta sql instances create INSTANCE_ID \
  --project=PROJECT_ID \
  --network=projects/NETWORK_PROJECT_ID/global/networks/VPC_NETWORK_NAME \
  --no-assign-ip \
  --allocated-ip-range-name=RANGE_NAME \
  --enable-google-private-path \
  --enforce-new-sql-network-architecture
```

### Terraform

To configure private IP for a new instance, use the following Terraform resources:

- [`google_compute_network`](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_network)
- [`google_compute_global_address`](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_global_address)
- [`google_service_networking_connection`](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/service_networking_connection)
- [`google_sql_database_instance`](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/sql_database_instance)

```terraform

resource "google_compute_network" "peering_network" {
  name                    = "private-network"
  auto_create_subnetworks = "false"
}

resource "google_compute_global_address" "private_ip_address" {
  name          = "private-ip-address"
  purpose       = "VPC_PEERING"
  address_type  = "INTERNAL"
  prefix_length = 16
  network       = google_compute_network.peering_network.id
}

resource "google_service_networking_connection" "default" {
  network                 = google_compute_network.peering_network.id
  service                 = "servicenetworking.googleapis.com"
  reserved_peering_ranges = [google_compute_global_address.private_ip_address.name]
}

resource "google_sql_database_instance" "instance" {
  name             = "private-ip-sql-instance"
  region           = "us-central1"
  database_version = "MYSQL_8_0"

  depends_on = [google_service_networking_connection.default]

  settings {
    tier = "db-f1-micro"
    ip_configuration {
      ipv4_enabled    = "false"
      private_network = google_compute_network.peering_network.id
    }
  }
  # set `deletion_protection` to true, will ensure that one cannot accidentally delete this instance by
  # use of Terraform whereas `deletion_protection_enabled` flag protects this instance at the GCP level.
  deletion_protection = false
}

resource "google_compute_network_peering_routes_config" "peering_routes" {
  peering              = google_service_networking_connection.default.peering
  network              = google_compute_network.peering_network.name
  import_custom_routes = true
  export_custom_routes = true
}


## Uncomment this block after adding a valid DNS suffix

# resource "google_service_networking_peered_dns_domain" "default" {
#   name       = "example-com"
#   network    = google_compute_network.peering_network.name
#   dns_suffix = "example.com."
#   service    = "servicenetworking.googleapis.com"
# }

```

#### Apply the changes

To apply your Terraform configuration in a Google Cloud project, complete the steps in the
following sections.

## Prepare Cloud Shell

1. Launch [Cloud Shell](https://shell.cloud.google.com/).
2. Set the default Google Cloud project
   where you want to apply your Terraform configurations.

   You only need to run this command once per project, and you can run it in any directory.

   ```
   export GOOGLE_CLOUD_PROJECT=PROJECT_ID
   ```

   Environment variables are overridden if you set explicit values in the Terraform
   configuration file.

## Prepare the directory

Each Terraform configuration file must have its own directory (also
called a *root module*).

1. In [Cloud Shell](https://shell.cloud.google.com/), create a directory and a new file within that directory. The filename must have the `.tf` extension---for example `main.tf`. In this tutorial, the file is referred to as `main.tf`.

   ```
   mkdir DIRECTORY && cd DIRECTORY && touch main.tf
   ```
2. If you are following a tutorial, you can copy the sample code in each section or step.

   Copy the sample code into the newly created `main.tf`.

   Optionally, copy the code from GitHub. This is recommended
   when the Terraform snippet is part of an end-to-end solution.
3. Review and modify the sample parameters to apply to your environment.
4. Save your changes.
5. Initialize Terraform. You only need to do this once per directory.

   ```
   terraform init
   ```

   Optionally, to use the latest Google provider version, include the `-upgrade`
   option:

   ```
   terraform init -upgrade
   ```

## Apply the changes

1. Review the configuration and verify that the resources that Terraform is going to create or update match your expectations:

   ```
   terraform plan
   ```

   Make corrections to the configuration as necessary.
2. Apply the Terraform configuration by running the following command and entering `yes` at the prompt:

   ```
   terraform apply
   ```

   Wait until Terraform displays the "Apply complete!" message.
3. [Open your Google Cloud project](https://console.cloud.google.com/) to view the results. In the Google Cloud console, navigate to your resources in the UI to make sure that Terraform has created or updated them.

> [!NOTE]
> **Note:** Terraform samples typically assume that the required APIs are enabled in your Google Cloud project.

#### Delete the changes

To delete your changes, do the following:

1. To disable deletion protection, in your Terraform configuration file set the `deletion_protection` argument to `false`.

   ```
   deletion_protection =  "false"
   ```
2. Apply the updated Terraform configuration by running the following command and entering `yes` at the prompt:

   ```
   terraform apply
   ```

<!-- -->

3. Remove resources previously applied with your Terraform configuration by running the following
   command and entering `yes` at the prompt:

   ```
   terraform destroy
   ```

### REST v1

Create a new instance with a private IP address:


Before using any of the request data,
make the following replacements:

- <var translate="no">PROJECT_ID:</var> The project ID
- <var translate="no">INSTANCE_ID:</var> The instance ID
- <var translate="no">VPC_NETWORK_NAME:</var> Specify the name of the Virtual Private Cloud (VPC) network that you want to use for this instance. Private services access must already be configured for the network.
- <var translate="no">RANGE_NAME:</var> *Optional.* If specified, sets a range name for which an IP range is allocated. The range name must comply with [`RFC-1035`](https://tools.ietf.org/html/rfc1035) and contain 1-63 characters.
- <var translate="no">AUTHORIZED_NETWORKS:</var> For public IP connections, specify the connections from authorized networks that can connect to your instance.

For the `ipv4Enabled` parameter, set the value to `true`
if you're using a public IP address for your instance or `false` if your instance has a
private IP address.

If you set the `enablePrivatePathForGoogleCloudServices` parameter to `true`,
then you allow other Google Cloud services, such as BigQuery, to access data in
Cloud SQL and make queries against this data over a private IP connection. By setting this parameter to
`false`, other Google Cloud services can't access data in Cloud SQL over a private IP connection.

You can use the `sqlNetworkArchitecture` field to enforce the use of the new network
architecture for the instance upon creation, even if the project isn't fully upgraded.
For more details about the new network architecture and its implications, see
[Upgrade an instance to the new network architecture](https://docs.cloud.google.com/sql/docs/mysql/upgrade-cloud-sql-instance-new-network-architecture.md.txt) and [Allocate an IP address range](https://docs.cloud.google.com/sql/docs/mysql/private-ip.md.txt#allocated-ip).


HTTP method and URL:

```
POST https://sqladmin.googleapis.com/v1/projects/PROJECT_ID/instances
```


Request JSON body:

```
{
  "name": "INSTANCE_ID",
  "region": "region",
  "databaseVersion": "database-version",
  "settings": {
    "tier": "machine-type",
    "ipConfiguration": {
      "ipv4Enabled": false,
      "privateNetwork": "projects/PROJECT_ID/global/networks/VPC_NETWORK_NAME",
      "allocatedIpRange": "RANGE_NAME"
      "authorizedNetworks": [AUTHORIZED_NETWORKS],
      
      "enablePrivatePathForGoogleCloudServices": true
      
    }
  },
  "sqlNetworkArchitecture": "NEW_NETWORK_ARCHITECTURE"
}
```

To send your request, expand one of these options:

#### curl (Linux, macOS, or Cloud Shell)

> [!NOTE]
> **Note:** The following command assumes that you have logged in to the `gcloud` CLI with your user account by running [`gcloud init`](https://docs.cloud.google.com/sdk/gcloud/reference/init) or [`gcloud auth login`](https://docs.cloud.google.com/sdk/gcloud/reference/auth/login.md.txt) , or by using [Cloud Shell](https://docs.cloud.google.com/shell/docs.md.txt), which automatically logs you into the `gcloud` CLI . You can check the currently active account by running [`gcloud auth list`](https://docs.cloud.google.com/sdk/gcloud/reference/auth/list.md.txt).


Save the request body in a file named `request.json`,
and execute the following command:

```
curl -X POST \
     -H "Authorization: Bearer $(gcloud auth print-access-token)" \
     -H "Content-Type: application/json; charset=utf-8" \
     -d @request.json \
     "https://sqladmin.googleapis.com/v1/projects/PROJECT_ID/instances"
```

#### PowerShell (Windows)

> [!NOTE]
> **Note:** The following command assumes that you have logged in to the `gcloud` CLI with your user account by running [`gcloud init`](https://docs.cloud.google.com/sdk/gcloud/reference/init) or [`gcloud auth login`](https://docs.cloud.google.com/sdk/gcloud/reference/auth/login.md.txt) . You can check the currently active account by running [`gcloud auth list`](https://docs.cloud.google.com/sdk/gcloud/reference/auth/list.md.txt).


Save the request body in a file named `request.json`,
and execute the following command:

```
$cred = gcloud auth print-access-token
$headers = @{ "Authorization" = "Bearer $cred" }

Invoke-WebRequest `
    -Method POST `
    -Headers $headers `
    -ContentType: "application/json; charset=utf-8" `
    -InFile request.json `
    -Uri "https://sqladmin.googleapis.com/v1/projects/PROJECT_ID/instances" | Select-Object -Expand Content
```

You should receive a JSON response similar to the following:

#### Response

```
{
  "kind": "sql#operation",
  "targetLink": "https://sqladmin.googleapis.com/v1/projects/PROJECT_ID/instances/INSTANCE_ID",
  "status": "PENDING",
  "user": "user@example.com",
  "insertTime": "2020-01-21T22:43:37.981Z",
  "operationType": "CREATE",
  "name": "OPERATION_ID",
  "targetId": "INSTANCE_ID",
  "selfLink": "https://sqladmin.googleapis.com/v1/projects/PROJECT_ID/operations/OPERATION_ID",
  "targetProject": "PROJECT_ID"
}
```

### REST v1beta4

Create a new instance with a private IP address:


Before using any of the request data,
make the following replacements:

- <var translate="no">PROJECT_ID:</var> The project ID
- <var translate="no">INSTANCE_ID:</var> The instance ID
- <var translate="no">VPC_NETWORK_NAME:</var> Specify the name of the Virtual Private Cloud (VPC) network that you want to use for this instance. Private services access must already be configured for the network.
- <var translate="no">RANGE_NAME:</var> *Optional.* If specified, sets a range name for which an IP range is allocated. The range name must comply with [`RFC-1035`](https://tools.ietf.org/html/rfc1035) and contain 1-63 characters.
- <var translate="no">AUTHORIZED_NETWORKS:</var> For public IP connections, specify the connections from authorized networks that can connect to your instance.

For the `ipv4Enabled` parameter, set the value to `true`
if you're using a public IP address for your instance or `false` if your instance has a
private IP address.

If you set the `enablePrivatePathForGoogleCloudServices` parameter to `true`,
then you allow other Google Cloud services, such as BigQuery, to access data in
Cloud SQL and make queries against this data over a private IP connection. By setting this parameter to
`false`, other Google Cloud services can't access data in Cloud SQL over a private IP connection.

You can use the `sqlNetworkArchitecture` field to enforce the use of the new network
architecture for the instance upon creation, even if the project isn't fully upgraded.
For more details about the new network architecture and its implications, see
[Upgrade an instance to the new network architecture](https://docs.cloud.google.com/sql/docs/mysql/upgrade-cloud-sql-instance-new-network-architecture.md.txt) and [Allocate an IP address range](https://docs.cloud.google.com/sql/docs/mysql/private-ip.md.txt#allocated-ip).


HTTP method and URL:

```
POST https://sqladmin.googleapis.com/sql/v1beta4/projects/PROJECT_ID/instances
```


Request JSON body:

```
{
  "name": "INSTANCE_ID",
  "region": "region",
  "databaseVersion": "database-version",
  "settings": {
    "tier": "machine-type",
    "ipConfiguration": {
      "ipv4Enabled": false,
      "privateNetwork": "projects/PROJECT_ID/global/networks/VPC_NETWORK_NAME",
      "allocatedIpRange": "RANGE_NAME"
      "authorizedNetworks": [AUTHORIZED_NETWORKS],
      
      "enablePrivatePathForGoogleCloudServices": true
      
    }
  },
  "sqlNetworkArchitecture": "NEW_NETWORK_ARCHITECTURE"
}
```

To send your request, expand one of these options:

#### curl (Linux, macOS, or Cloud Shell)

> [!NOTE]
> **Note:** The following command assumes that you have logged in to the `gcloud` CLI with your user account by running [`gcloud init`](https://docs.cloud.google.com/sdk/gcloud/reference/init) or [`gcloud auth login`](https://docs.cloud.google.com/sdk/gcloud/reference/auth/login.md.txt) , or by using [Cloud Shell](https://docs.cloud.google.com/shell/docs.md.txt), which automatically logs you into the `gcloud` CLI . You can check the currently active account by running [`gcloud auth list`](https://docs.cloud.google.com/sdk/gcloud/reference/auth/list.md.txt).


Save the request body in a file named `request.json`,
and execute the following command:

```
curl -X POST \
     -H "Authorization: Bearer $(gcloud auth print-access-token)" \
     -H "Content-Type: application/json; charset=utf-8" \
     -d @request.json \
     "https://sqladmin.googleapis.com/sql/v1beta4/projects/PROJECT_ID/instances"
```

#### PowerShell (Windows)

> [!NOTE]
> **Note:** The following command assumes that you have logged in to the `gcloud` CLI with your user account by running [`gcloud init`](https://docs.cloud.google.com/sdk/gcloud/reference/init) or [`gcloud auth login`](https://docs.cloud.google.com/sdk/gcloud/reference/auth/login.md.txt) . You can check the currently active account by running [`gcloud auth list`](https://docs.cloud.google.com/sdk/gcloud/reference/auth/list.md.txt).


Save the request body in a file named `request.json`,
and execute the following command:

```
$cred = gcloud auth print-access-token
$headers = @{ "Authorization" = "Bearer $cred" }

Invoke-WebRequest `
    -Method POST `
    -Headers $headers `
    -ContentType: "application/json; charset=utf-8" `
    -InFile request.json `
    -Uri "https://sqladmin.googleapis.com/sql/v1beta4/projects/PROJECT_ID/instances" | Select-Object -Expand Content
```

You should receive a JSON response similar to the following:

#### Response

```
{
  "kind": "sql#operation",
  "targetLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/PROJECT_ID/instances/INSTANCE_ID",
  "status": "PENDING",
  "user": "user@example.com",
  "insertTime": "2020-01-21T22:43:37.981Z",
  "operationType": "CREATE",
  "name": "OPERATION_ID",
  "targetId": "INSTANCE_ID",
  "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/PROJECT_ID/operations/OPERATION_ID",
  "targetProject": "PROJECT_ID"
}
```

### Configure private IP for an existing instance

Configuring an existing Cloud SQL instance to use private IP
causes the instance to restart, resulting in downtime.

> [!NOTE]
> **Note:** You can't assign a private IP address for an existing Cloud SQL instance in a Shared VPC network. You also can't assign an allocated range name for an existing instance.

To configure an existing instance to use private IP:

### Console

1. In the Google Cloud console, go to the **Cloud SQL Instances** page.

   [Go to Cloud SQL Instances](https://console.cloud.google.com/sql)
2. To open the **Overview** page of an instance, click the instance name.
3. Select **Connections** from the Cloud SQL navigation menu.
4. On the **Networking** tab, select the **Private IP** checkbox.


   A drop-down list shows the available networks in your project.
5. Select the VPC network you want to use:
6. If you see **Private service connection required**:
   1. Click **Set up connection**.
   2. In the **Allocate an IP range** section, choose one of the following options:
      - Select one or more existing IP ranges or create a new one from the drop-down. The drop-down includes previously allocated ranges, if there are any, or you can select **Allocate a new IP range** and enter a new range and name.
      - Use an automatically allocated IP range in your network.

      > [!NOTE]
      > **Note:**You can specify an address range only for a primary instance, not for a read replica or clone.

   3. Click **Continue**.
   4. Click **Create connection**.
   5. Verify that you see the **Private service connection for
      network `VPC_NETWORK_NAME` has been successfully created** status.
7. Optional. If you want to allow other Google Cloud services, such as BigQuery, to access data in Cloud SQL and make queries against this data over a private IP connection, then select the **Enable private
   path** checkbox.
8. Click **Save**.

### gcloud


Ensure your project is configured for
[private services access](https://docs.cloud.google.com/sql/docs/mysql/configure-private-services-access.md.txt).


Update your Cloud SQL instance by using the
`--network` parameter
to specify the name of your selected VPC network.

To enforce the use of the new network
architecture for the instance when you add a private IP network
configuration, use the [`--enforce-new-sql-network-architecture`](https://docs.cloud.google.com/sdk/gcloud/reference/beta/sql/instances/patch.md.txt#--enforce-new-sql-network-architecture) flag.
Make sure that you have allocated enough
IP address space in your IP range.
When you use new network architecture enforcement before
a project is fully upgraded, you might experience instance
creation failure if sufficient IP address space isn't available.

For more information, see
[Upgrade an instance to the new network architecture](https://docs.cloud.google.com/sql/docs/mysql/upgrade-cloud-sql-instance-new-network-architecture.md.txt) and [Allocate an IP address range](https://docs.cloud.google.com/sql/docs/mysql/private-ip.md.txt#allocated-ip).

```bash
gcloud beta sql instances patch INSTANCE_ID \
--project=PROJECT_ID \
--network=projects/NETWORK_PROJECT_ID/global/networks/VPC_NETWORK_NAME \
--no-assign-ip \
--enable-google-private-path \
--enforce-new-sql-network-architecture
```

### REST v1

Create a new instance with a private IP address:


Before using any of the request data,
make the following replacements:

- <var translate="no">PROJECT_ID:</var> The project ID
- <var translate="no">INSTANCE_ID:</var> The instance ID
- <var translate="no">VPC_NETWORK_NAME:</var> Specify the name of the Virtual Private Cloud (VPC) network that you want to use for this instance. Private services access must already be configured for the network.
- <var translate="no">RANGE_NAME:</var> *Optional.* If specified, sets a range name for which an IP range is allocated. The range name must comply with [`RFC-1035`](https://tools.ietf.org/html/rfc1035) and contain 1-63 characters.
- <var translate="no">AUTHORIZED_NETWORKS:</var> For public IP connections, specify the connections from authorized networks that can connect to your instance.

For the `ipv4Enabled` parameter, set the value to `true`
if you're using a public IP address for your instance or `false` if your instance has a
private IP address.

If you set the `enablePrivatePathForGoogleCloudServices` parameter to `true`,
then you allow other Google Cloud services, such as BigQuery, to access data in
Cloud SQL and make queries against this data over a private IP connection. By setting this parameter to
`false`, other Google Cloud services can't access data in Cloud SQL over a private IP connection.

You can use the `sqlNetworkArchitecture` field to enforce the use of the new network
architecture for the instance upon creation, even if the project isn't fully upgraded.
For more details about the new network architecture and its implications, see
[Upgrade an instance to the new network architecture](https://docs.cloud.google.com/sql/docs/mysql/upgrade-cloud-sql-instance-new-network-architecture.md.txt) and [Allocate an IP address range](https://docs.cloud.google.com/sql/docs/mysql/private-ip.md.txt#allocated-ip).


HTTP method and URL:

```
PATCH https://sqladmin.googleapis.com/v1/projects/PROJECT_ID/instances/INSTANCE_ID
```


Request JSON body:

```
{
  "settings":
  {
    "ipConfiguration": {
      "ipv4Enabled": false,
      "privateNetwork": "projects/PROJECT_ID/global/networks/VPC_NETWORK_NAME",
      "allocatedIpRange": "RANGE_NAME"
      "authorizedNetworks": [AUTHORIZED_NETWORKS],
      
      "enablePrivatePathForGoogleCloudServices": true
      
    }
  },
  "sqlNetworkArchitecture": "NEW_NETWORK_ARCHITECTURE"
}
```

To send your request, expand one of these options:

#### curl (Linux, macOS, or Cloud Shell)

> [!NOTE]
> **Note:** The following command assumes that you have logged in to the `gcloud` CLI with your user account by running [`gcloud init`](https://docs.cloud.google.com/sdk/gcloud/reference/init) or [`gcloud auth login`](https://docs.cloud.google.com/sdk/gcloud/reference/auth/login.md.txt) , or by using [Cloud Shell](https://docs.cloud.google.com/shell/docs.md.txt), which automatically logs you into the `gcloud` CLI . You can check the currently active account by running [`gcloud auth list`](https://docs.cloud.google.com/sdk/gcloud/reference/auth/list.md.txt).


Save the request body in a file named `request.json`,
and execute the following command:

```
curl -X PATCH \
     -H "Authorization: Bearer $(gcloud auth print-access-token)" \
     -H "Content-Type: application/json; charset=utf-8" \
     -d @request.json \
     "https://sqladmin.googleapis.com/v1/projects/PROJECT_ID/instances/INSTANCE_ID"
```

#### PowerShell (Windows)

> [!NOTE]
> **Note:** The following command assumes that you have logged in to the `gcloud` CLI with your user account by running [`gcloud init`](https://docs.cloud.google.com/sdk/gcloud/reference/init) or [`gcloud auth login`](https://docs.cloud.google.com/sdk/gcloud/reference/auth/login.md.txt) . You can check the currently active account by running [`gcloud auth list`](https://docs.cloud.google.com/sdk/gcloud/reference/auth/list.md.txt).


Save the request body in a file named `request.json`,
and execute the following command:

```
$cred = gcloud auth print-access-token
$headers = @{ "Authorization" = "Bearer $cred" }

Invoke-WebRequest `
    -Method PATCH `
    -Headers $headers `
    -ContentType: "application/json; charset=utf-8" `
    -InFile request.json `
    -Uri "https://sqladmin.googleapis.com/v1/projects/PROJECT_ID/instances/INSTANCE_ID" | Select-Object -Expand Content
```

You should receive a JSON response similar to the following:

#### Response

```
{
  "kind": "sql#operation",
  "targetLink": "https://sqladmin.googleapis.com/v1/projects/PROJECT_ID/instances/INSTANCE_ID",
  "status": "PENDING",
  "user": "user@example.com",
  "insertTime": "2020-01-21T22:43:37.981Z",
  "operationType": "UPDATE",
  "name": "OPERATION_ID",
  "targetId": "INSTANCE_ID",
  "selfLink": "https://sqladmin.googleapis.com/v1/projects/PROJECT_ID/operations/OPERATION_ID",
  "targetProject": "PROJECT_ID"
}
```

### REST v1beta4

Create a new instance with a private IP address:


Before using any of the request data,
make the following replacements:

- <var translate="no">PROJECT_ID:</var> The project ID
- <var translate="no">INSTANCE_ID:</var> The instance ID
- <var translate="no">VPC_NETWORK_NAME:</var> Specify the name of the Virtual Private Cloud (VPC) network that you want to use for this instance. Private services access must already be configured for the network.
- <var translate="no">RANGE_NAME:</var> *Optional.* If specified, sets a range name for which an IP range is allocated. The range name must comply with [`RFC-1035`](https://tools.ietf.org/html/rfc1035) and contain 1-63 characters.
- <var translate="no">AUTHORIZED_NETWORKS</var>: For public IP connections, specify the connections from authorized networks that can connect to your instance.

For the `ipv4Enabled` parameter, set the value to `true`
if you're using a public IP address for your instance or `false` if your instance has a
private IP address.

If you set the `enablePrivatePathForGoogleCloudServices` parameter to `true`,
then you allow other Google Cloud services, such as BigQuery, to access data in
Cloud SQL and make queries against this data over a private IP connection. By setting this parameter to
`false`, other Google Cloud services can't access data in Cloud SQL over a private IP connection.

You can use the `sqlNetworkArchitecture` field to enforce the use of the new network
architecture for the instance upon creation, even if the project isn't fully upgraded.
For more details about the new network architecture and its implications, see
[Upgrade an instance to the new network architecture](https://docs.cloud.google.com/sql/docs/mysql/upgrade-cloud-sql-instance-new-network-architecture.md.txt) and [Allocate an IP address range](https://docs.cloud.google.com/sql/docs/mysql/private-ip.md.txt#allocated-ip).


HTTP method and URL:

```
PATCH https://sqladmin.googleapis.com/sql/v1beta4/projects/PROJECT_ID/instances/INSTANCE_ID
```


Request JSON body:

```
{
  "settings":
  {
    "ipConfiguration": {
      "ipv4Enabled": false,
      "privateNetwork": "projects/PROJECT_ID/global/networks/VPC_NETWORK_NAME",
      "allocatedIpRange": "RANGE_NAME"
      "authorizedNetworks": [AUTHORIZED_NETWORKS],
      
      "enablePrivatePathForGoogleCloudServices": true
      
    }
  },
  "sqlNetworkArchitecture": "NEW_NETWORK_ARCHITECTURE"
}
```

To send your request, expand one of these options:

#### curl (Linux, macOS, or Cloud Shell)

> [!NOTE]
> **Note:** The following command assumes that you have logged in to the `gcloud` CLI with your user account by running [`gcloud init`](https://docs.cloud.google.com/sdk/gcloud/reference/init) or [`gcloud auth login`](https://docs.cloud.google.com/sdk/gcloud/reference/auth/login.md.txt) , or by using [Cloud Shell](https://docs.cloud.google.com/shell/docs.md.txt), which automatically logs you into the `gcloud` CLI . You can check the currently active account by running [`gcloud auth list`](https://docs.cloud.google.com/sdk/gcloud/reference/auth/list.md.txt).


Save the request body in a file named `request.json`,
and execute the following command:

```
curl -X PATCH \
     -H "Authorization: Bearer $(gcloud auth print-access-token)" \
     -H "Content-Type: application/json; charset=utf-8" \
     -d @request.json \
     "https://sqladmin.googleapis.com/sql/v1beta4/projects/PROJECT_ID/instances/INSTANCE_ID"
```

#### PowerShell (Windows)

> [!NOTE]
> **Note:** The following command assumes that you have logged in to the `gcloud` CLI with your user account by running [`gcloud init`](https://docs.cloud.google.com/sdk/gcloud/reference/init) or [`gcloud auth login`](https://docs.cloud.google.com/sdk/gcloud/reference/auth/login.md.txt) . You can check the currently active account by running [`gcloud auth list`](https://docs.cloud.google.com/sdk/gcloud/reference/auth/list.md.txt).


Save the request body in a file named `request.json`,
and execute the following command:

```
$cred = gcloud auth print-access-token
$headers = @{ "Authorization" = "Bearer $cred" }

Invoke-WebRequest `
    -Method PATCH `
    -Headers $headers `
    -ContentType: "application/json; charset=utf-8" `
    -InFile request.json `
    -Uri "https://sqladmin.googleapis.com/sql/v1beta4/projects/PROJECT_ID/instances/INSTANCE_ID" | Select-Object -Expand Content
```

You should receive a JSON response similar to the following:

#### Response

```
{
  "kind": "sql#operation",
  "targetLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/PROJECT_ID/instances/INSTANCE_ID",
  "status": "PENDING",
  "user": "user@example.com",
  "insertTime": "2020-01-21T22:43:37.981Z",
  "operationType": "UPDATE",
  "name": "OPERATION_ID",
  "targetId": "INSTANCE_ID",
  "selfLink": "https://sqladmin.googleapis.com/sql/v1beta4/projects/PROJECT_ID/operations/OPERATION_ID",
  "targetProject": "PROJECT_ID"
}
```

### Change the private service access configuration

You can change the allocated address range of a private service connection
without modifying any existing Cloud SQL instances. To change
the private IP address of an existing Cloud SQL instance, follow
[these steps](https://docs.cloud.google.com/sql/docs/mysql/configure-private-services-access.md.txt#change-private-ip).

To change the allocated address range:

### Console

1. In the Google Cloud console, go to the **VPC networks** page.

   [Go to VPC networks](https://console.cloud.google.com/networking/networks)
2. Select the VPC network that you want to use.
3. Select the **Private service connection** tab.
4. Select the **Allocated IP ranges for services** tab.
5. Select the name of the range you want to delete.

   > [!NOTE]
   > **Note:** Before you delete the range, make a note of its name. You need this name later in this procedure.

6. Click **Release**.

7. Click **Allocate IP range**.

8. Create a new range with the same name and new range

   The name matters because the private connection has already been
   established using that address name.

   <br />

> [!NOTE]
> **Note:** After modifying or removing an allocated address range, update VPC peerings. Use the following command, and make sure to use the `--force` argument:

```bash
gcloud services vpc-peerings update \
--network=VPC_NETWORK_NAME \
--ranges=ALLOCATED_RANGES \
--service=servicenetworking.googleapis.com \
--force
```
Cloud SQL does not automatically delete the old subnet with the old IP range. The range is marked as unusable and cannot be used again in the project. This allows existing instances to stay in that subnet. To permanently remove the subnet, all Cloud SQL instances using an address in the range must be deleted. The subnet is deleted four days after the last instance in the subnet is deleted.

### Change the private IP address of an existing Cloud SQL instance

To change the private IP address of an existing Cloud SQL instance, move
the instance from its original network to a temporary VPC
network. Then, [change the private service access
configuration](https://docs.cloud.google.com/sql/docs/mysql/configure-private-services-access#change-psa-config) of the instance's original network and move the
Cloud SQL instance back to its original network.

To move to a different VPC network, follow all but the final step
(moving the instance back) in the following procedure. In this case, the
`TEMPORARY_VPC_NETWORK_NAME`
is the new VPC network. Also,
[delete
the old private connection](https://docs.cloud.google.com/vpc/docs/configure-private-services-access#removing-connection).
It can take a few days for the deleted private connection to disappear from the
Google Cloud console.

If the Cloud SQL instance is hosted in a Shared VPC network,
the `VPC_NETWORK_NAME`
variables used in the following instructions must be the host project's
VPC network names. To specify a network with a Shared VPC
network, use the full URL of the
network---for example, `projects/HOST_PROJECT/global/networks/NETWORK_NAME`.

> [!NOTE]
> **Note:** If the project that's hosting the VPC network operates in dual stack mode, then there are considerations to keep in mind for using this project. For more information, see [Plan to upgrade all Cloud SQL instances in a network project](https://docs.cloud.google.com/sql/docs/mysql/upgrade-cloud-sql-instance-new-network-architecture.md.txt#upgrade-all-instances-in-network-project).

### Console

1. In the Google Cloud console, go to the **VPC networks** page.

   [Go to VPC networks](https://console.cloud.google.com/networking/networks)
2. [Create a temporary VPC network](https://docs.cloud.google.com/vpc/docs/create-modify-vpc-networks.md.txt#creating_networks).
3. [Create an IP allocation in the temporary VPC network](https://docs.cloud.google.com/vpc/docs/configure-private-services-access.md.txt#procedure).
4. [Create a private connection in the temporary VPC network](https://docs.cloud.google.com/vpc/docs/configure-private-services-access.md.txt#creating-connection).
5. Move the Cloud SQL instance to the temporary VPC network.

   ```bash
   gcloud beta sql instances patch INSTANCE_ID \
     --project=PROJECT_ID \
     --network=projects/PROJECT_ID/global/networks/TEMPORARY_VPC_NETWORK_NAME \
     --no-assign-ip
   ```
6. [Change the private service access configuration](https://docs.cloud.google.com/sql/docs/mysql/configure-private-services-access.md.txt#change-psa-config) in
   the original network to add a new allocated range or delete existing ones.

7. Move the Cloud SQL instance back to the original VPC
   network.

   ```bash
   gcloud beta sql instances patch INSTANCE_ID \
     --project=PROJECT_ID \
     --network=projects/PROJECT_ID/global/networks/ORIGINAL_VPC_NETWORK_NAME \
     --no-assign-ip
   ```

## Connect to an instance using its private IP address

You use [private services access](https://docs.cloud.google.com/sql/docs/mysql/configure-private-services-access.md.txt)
to connect to Cloud SQL instances from Compute Engine or Google Kubernetes Engine
instances in the same VPC network (defined here as *internal*
sources) or from outside of that network (an *external* source).

### Connect from an internal source

To connect from a source in the same Google Cloud project as your Cloud SQL
instance, such as the [Cloud SQL Auth Proxy](https://docs.cloud.google.com/sql/docs/mysql/sql-proxy.md.txt) running on a
Compute Engine resource, that resource must be in the same VPC
network where private services access has been established for the
Cloud SQL instance.


To connect from a serverless source, such as [App Engine standard environment](https://docs.cloud.google.com/sql/docs/mysql/connect-app-engine-standard.md.txt#connecting_to),
[Cloud Run](https://docs.cloud.google.com/sql/docs/mysql/connect-run.md.txt#connecting_to),
or [Cloud Run functions](https://docs.cloud.google.com/sql/docs/mysql/connect-functions.md.txt#connecting_to),
your application or function connects directly to your instance through
Serverless VPC Access without the Cloud SQL Auth Proxy.

### Connect from an external source

If an external network (for example, an on-premises network or a VPC
network), is connected to the VPC network to which your
Cloud SQL instance is connected, then you can use [Cloud VPN](https://docs.cloud.google.com/network-connectivity/docs/vpn.md.txt)
or [Cloud Interconnect](https://docs.cloud.google.com/network-connectivity/docs/interconnect.md.txt) to connect
to the instance from a client in the external network.

To permit connections from an external network, do the following:

1. Ensure your VPC network is connected to the external network using a [Cloud VPN tunnel](https://docs.cloud.google.com/network-connectivity/docs/vpn/concepts/overview.md.txt) or a VLAN attachment for [Dedicated Interconnect](https://docs.cloud.google.com/network-connectivity/docs/interconnect/how-to/dedicated/provisioning-overview.md.txt) or [Partner Interconnect](https://docs.cloud.google.com/network-connectivity/docs/interconnect/how-to/partner/provisioning-overview.md.txt).
2. Ensure the Border Gateway Protocol (BGP) sessions on the
   Cloud Routers managing your Cloud VPN tunnels and
   Cloud Interconnect attachments (VLANs) have received specific
   prefixes (destinations) from your on-premises network.

   Default routes (destination 0.0.0.0/0) cannot be imported into the
   Cloud SQL VPC network because that network has its own
   local default route. Local routes for a destination are used even
   though the Cloud SQL peering is configured to import custom routes from
   your VPC network.
3. [Identify the peering connections](https://docs.cloud.google.com/vpc/docs/configure-private-services-access.md.txt#listing-connections) produced by the private services connection. Depending on the service, the private services connection might create one or more of the following peering connections, but not necessarily all of them:
   - `cloudsql-mysql-googleapis-com`
   - `cloudsql-postgres-googleapis-com`
   - `servicenetworking-googleapis-com`
4. [Update **all** of the peering connections](https://docs.cloud.google.com/vpc/docs/using-vpc-peering.md.txt#update-peer-connection) to enable **Export custom
   routes**.
5. [Identify the allocated range](https://docs.cloud.google.com/vpc/docs/configure-private-services-access.md.txt#listing_allocated_ip_address_ranges) used by the private services connection.
6. [Configure Cloud Router custom advertisement mode](https://docs.cloud.google.com/network-connectivity/docs/router/how-to/advertising-custom-ip.md.txt) for the allocated range on the Cloud Routers managing BGP sessions for your Cloud VPN tunnels or Cloud Interconnect attachments (VLANs).

> [!NOTE]
> **Note:** If you're using a [non-RFC 1918 IP address range](https://docs.cloud.google.com/vpc/docs/subnets.md.txt#valid-ranges) for your application, then to allow access from this range, [configure the authorized network](https://docs.cloud.google.com/sql/docs/mysql/authorize-networks.md.txt) for your instance.

### Connect from Cloud Shell

[Cloud Shell](https://docs.cloud.google.com/shell/docs/how-cloud-shell-works.md.txt) uses a Compute Engine
virtual machine that's managed by Google Cloud and is outside of your
VPC network. Therefore, a connectivity path doesn't exist between
Cloud Shell and the private IP address space of your VPC
network.

As a result, Cloud Shell doesn't support connecting to a Cloud SQL
instance that has only a private IP address.

To connect to Cloud SQL instances from an external network using private
IP connectivity, see [Connect to a Cloud SQL instance from outside its VPC](https://docs.cloud.google.com/sql/docs/mysql/connect-to-instance-from-outside-vpc.md.txt).

### Connect from non-RFC 1918 IP addresses

[RFC 1918](https://tools.ietf.org/html/rfc1918) specifies IP
addresses that are assigned to be used internally (that is, within an
organization) and won't route on the Internet. Specifically, these are:

- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16

Connections to a Cloud SQL instance using a private IP address are
automatically authorized for [RFC 1918
address ranges](https://docs.cloud.google.com/vpc/docs/subnets#valid-ranges). This way, all private clients can access the database
without going through the proxy.

> [!NOTE]
> **Note:** You must configure all the non-RFC 1918 IP address ranges as [authorized networks](https://docs.cloud.google.com/sql/docs/mysql/authorize-networks.md.txt) of the Cloud SQL for MySQL instances. Alternatively, you can connect to your instance using the [Cloud SQL Auth Proxy client](https://docs.cloud.google.com/sql/docs/mysql/sql-proxy.md.txt).

To connect from a non-RFC 1918 IP address, you must set
per-instance IP authorization to allow traffic from non-RFC 1918 IP address
ranges.

For example, use a `gcloud` command like the following:

```bash
gcloud sql instances patch INSTANCE_NAME \
--authorized-networks=192.88.99.0/24,11.0.0.0/24
```

> [!NOTE]
> **Note:** This command overwrites all existing authorized networks, so you must include all the authorized networks to use.

Cloud SQL doesn't learn non-RFC 1918 subnet routes from your
VPC network by default. You need to update the network peering to
Cloud SQL to export any non-RFC 1918 routes.

```bash
gcloud compute networks peerings update PEERING_CONNECTION \
--network=VPC_NETWORK_NAME \
--export-subnet-routes-with-public-ip \
--project=PROJECT_ID
```

- Replace the following:
- `PEERING_CONNECTION` is the [name
  of the peering connection](https://docs.cloud.google.com/vpc/docs/configure-private-services-access#listing-connections) produced by the private services connection between your VPC network and the service producer network.
- `VPC_NETWORK_NAME` is the name of your VPC network.
- `PROJECT_ID` is the ID of the project of the VPC network. If you're using Shared VPC, then use the host project ID.

To mitigate IP address exhaustion, you can use
[privately used public IP addresses](https://docs.cloud.google.com/vpc/docs/subnets.md.txt#pupi-addresses).

#### Connect from privately used public IP addresses

If you want to configure your instance in a privately used public IP address range, then enable
`export-subnet-routes-with-public-ip` on the network peering between your network
and the Cloud SQL network.

```bash
gcloud compute networks peerings update PEERING_CONNECTION \
--network=VPC_NETWORK_NAME \
--export-subnet-routes-with-public-ip \
--project=PROJECT_ID
```

- Replace the following:
- `PEERING_CONNECTION` is the name of the peering connection produced by the private services connection between your VPC network and the service producer network. To know the name of the peering connection, go to the [VPC network
  peering](https://console.cloud.google.com/networking/peering/) page.
- `VPC_NETWORK_NAME` is the name of your VPC network.
- `PROJECT_ID` is the ID of the project of the VPC network. If you're using Shared VPC, then use the host project ID.

#### Connect to an instance configured with privately used public IP addresses

If your instance is configured in a privately used public IP address range
and you want to connect to it,
then enable `import-subnet-routes-with-public-ip` on the network peering
between your network and the Cloud SQL network.

```bash
gcloud compute networks peerings update PEERING_CONNECTION \
--network=VPC_NETWORK_NAME \
--import-subnet-routes-with-public-ip \
--project=PROJECT_ID
```

Replace the following:

- `PEERING_CONNECTION` is the name of the peering connection produced by the private services connection between your VPC network and the service producer network. To find the name of the peering connection, go to the [VPC network peering](https://console.cloud.google.com/networking/peering/) page.
- `VPC_NETWORK_NAME` is the name of your VPC network.
- `PROJECT_ID` is the ID of the project of the VPC network. Use the host project ID if you're using Shared VPC.

### Connect by using a write endpoint

In addition to a private IP address, you can use a write endpoint in a SQL
connection string. A write endpoint is a global domain name service (DNS) name
that resolves to the IP address of the current primary instance automatically.
By using a write endpoint, you can avoid having to make application connection
changes when a region failure occurs.

If a replica [failover or switchover](https://docs.cloud.google.com/sql/docs/mysql/replication/cross-region-replicas.md.txt) occurs,
then the write endpoint can help manage private IP addresses of instances.
When this happens, use the write endpoint to connect to the instance that
acts as the primary instance.

> [!NOTE]
> **Note** : A write endpoint is available only for
> Cloud SQL Enterprise Plus edition instances that have private IP addresses and associated networks.
> For more information on creating instances that meet this criteria,
> see [Create instances](https://docs.cloud.google.com/sql/docs/mysql/create-instance.md.txt).

#### How Cloud SQL creates a write endpoint

If you enable the Cloud DNS API for your Google Cloud project, and afterwards, you
[create a primary Cloud SQL Enterprise Plus edition instance](https://docs.cloud.google.com/sql/docs/mysql/create-instance.md.txt),
[promote the replica for the instance](https://docs.cloud.google.com/sql/docs/mysql/replication/manage-replicas.md.txt#promote-replica),
or [upgrade the instance from Cloud SQL Enterprise edition](https://docs.cloud.google.com/sql/docs/mysql/upgrade-cloud-sql-instance-to-enterprise-plus-in-place),
then Cloud SQL generates a write endpoint automatically and assigns it to
the instance.
If the primary instance changes during the switchover or failover processes, then Cloud SQL assigns the write endpoint to the failover replica because this replica is the new primary instance.

For more information, see
[View the write endpoint](https://docs.cloud.google.com/sql/docs/mysql/connect-to-instance-using-write-endpoint.md.txt#view_the_write_endpoint).

#### Assign a write endpoint to an instance

If you don't enable the Cloud DNS API for your Google Cloud project, and then you
create, promote, or upgrade your instance, Cloud SQL doesn't assign the
write endpoint to the instance automatically.

To have Cloud SQL generate a write endpoint and assign it to the
instance, see [Generate the write endpoint](https://docs.cloud.google.com/sql/docs/mysql/connect-to-instance-using-write-endpoint.md.txt).

## Troubleshoot

See [troubleshooting](https://docs.cloud.google.com/sql/docs/mysql/troubleshooting.md.txt#connectivity)
for known connectivity issues, and also [debugging connection issues](https://docs.cloud.google.com/sql/docs/mysql/debugging-connectivity.md.txt) for help with self-diagnostics.