Migrating projects

Stay organized with collections Save and categorize content based on your preferences.

This guide explains how to move a project between organization resources or places within a resource hierarchy.

The project resource is the base-level organizing entity in a Google Cloud organization resource. Projects are created under organization resources, and can be placed under folders or the organization resource itself, forming the resource hierarchy. You may need to migrate projects between organization resources due to acquisitions, regulatory requirements, and separation between business units, among other things.

You can use the Resource Manager API to move projects across organization resources or to another place in the resource hierarchy of its current organization resource. The Resource Manager API also lets you roll back the migration, moving the project back to its original place in the resource hierarchy.

Create a migration plan

The most important thing to consider during a project move is how the migration will impact the services running inside the project. The Resource Manager API treats the project resource and all services running underneath it as a single unit, meaning that no configuration changes will be applied inside the project.

While the migration will not make direct configuration changes to the project, the change in the resource hierarchy is likely to have an impact on the function of the project and its running services. Inherited policies, such as Identity and Access Management or organization policies, will not move with the project during migration, only policies and service accounts that are attached directly to the resource. This may cause unintended behavior after the migration is complete.

Moving your project might also result in organization policy violations, depending on the destination organization resource's organization policies.

Before moving your project, you should consider creating a migration plan to determine the readiness of both your organization and the projects you want to move. In this migration plan, take inventory of each of the services that your project is running, and any other services that may be impacted by the move, or by the resource hierarchy in the destination for your project.

Inventory overview

Use Cloud Asset Inventory to create an overview of resources in use, including Identity and Access Management policies. You can use this overview to help outline your migration plan.

You can also use Cloud Asset Inventory to transfer this data into BigQuery. This will allow you to query the data using SQL, which is easier to read compared to interpreting JSON-formatted data. For information about exporting this data, see Exporting to BigQuery.

Policy verification

When you migrate your project, it will no longer inherit the policies from its current place in the resource hierarchy, and will be subject to the effective policy evaluation at its destination. We recommend making sure that the effective policies at the project's destination match as much as possible the policies that the project had in its source location.

Any policy that is applied directly to the project will still be attached after the migration is complete. Applying policies directly to the project is a good way to verify that the correct policies are applied from the moment the move is complete.

Identity and Access Management policies and organization policies are inherited through the resource hierarchy, and can block a service from functioning if not set properly. Determine the effective policy at the project's destination in your resource hierarchy to ensure the policy aligns with your governance objectives.

Manage encrypted keys

You should verify if your project has a customer-managed encrypted key or other Cloud Key Management Service enabled on it. Cryptographic keys are owned by the project, and a user with owner access to that project will therefore be able to manage and perform cryptographic operations on keys in Cloud KMS in that project.

For more information, see Separation of duties.

Preview features

You can enable preview features on organization, folder, or project resources. If you have enabled an alpha or beta feature on the project to be moved, this feature should continue to function after the migration. If the preview feature is private and not allowlisted for the destination organization resource, you will not be able to make any configuration changes after the move is complete.

Rollback plan

If you discover that something is not working on any of the projects you have migrated, you can move them back to their original location. In order to do that, you need to have the necessary IAM permissions and set the required organization policies so that you can run the project migration in reverse.

For a list of permissions required, see Assign permissions. For the organization policies you need to configure to allow a project migration, see Configure organization policies.

Dedicated import and export folders

Policy inheritance can cause unintended effects when you are migrating a project, both in the source and destination organization resources. You can mitigate this risk by creating specific folders to hold only projects for export and import, and ensuring that the same policies are inherited by the folders in both organization resources. You can also set permissions on these folders that will be inherited to the projects moved within them, helping to accelerate the project migration process.

When planning a migration, consider setting up a dedicated source folder first. To do this, create a folder for each organization resource to which you plan to export projects. Then, set an organization policy on these folders, each with the constraints/resourcemanager.allowedExportDestinations constraint set to the single organization resource to which you want to export projects.

For example, you could set up Export to Marketing Org and Export to Sales Org folders, each with appropriate organization policy constraints set.

Similarly, set up dedicated import folders in the destination organization resource, one for each organization resource from which you want to import projects. To do this, create a folder for each organization resource from which you plan to import projects. Then, set an organization policy on these folders, each with the constraints/resourcemanager.allowedImportSources constraint set to the single organization resource from which you want to import projects.

For example, you could set up Import from Marketing Org and Import from App Development Org folders, each with appropriate organization policy constraints set.

On each of the import and export folders, assign the person who will be moving the projects the roles/resourcemanager.projectMover role. This role will be inherited by any projects that are contained within these folders, giving the user the ability to perform the move operations on any project that is moved into those folders.

After you have completed your project migration, you should remove these dedicated folders.

For information about setting organization policies, see Configure organization policies.

Assign permissions

You need the following permissions to move a project between organization resources.

To gain these permissions, ask your administrator to grant the suggested role at the appropriate level of the resource hierarchy.

Project move permissions

To move a project, you need the following roles on the project, its parent resource, and the destination resource:

  • Project IAM Admin (roles/resourcemanager.projectIamAdmin) on the project that you want to move
  • Project Mover (roles/resourcemanager.projectMover) on the project's parent resource
  • If the destination resource is a folder: Project Mover (roles/resourcemanager.projectMover) on the destination resource
  • If the destination resource is an organization: Project Creator (roles/resourcemanager.projectCreator) on the destination resource

These roles give you the following required permissions:

Required permissions

  • resourcemanager.projects.getIamPolicy on the project you want to move
  • resourcemanager.projects.update on the project you want to move
  • resourcemanager.projects.move on the project's parent resource
  • If the destination resource is a folder: resourcemanager.projects.move on the destination resource
  • If the destination resource is an organization: resourcemanager.projects.create on the destination resource

You can also gain these permissions with a custom role, or other predefined roles.

Organization policy permissions

On the source and destination organization resources, you must have the roles/orgpolicy.policyAdmin role, which grants permission to create and manage organization policies.

Billing account permissions

Cloud Billing accounts can be used across organization resources. Moving a project from one organization resource to another won't impact billing, and charges will continue against the old billing account. However, organization resource moves often also include a requirement to move to a new billing account.

To get the permissions that you need to change the project's billing account, ask your administrator to grant you the following IAM roles:

  • Billing Account User (roles/billing.user) on the destination billing account
  • Project billing manager (roles/billing.projectManager) on the project

For more information about granting roles, see Manage access.

These predefined roles contain the permissions required to change the project's billing account. To see the exact permissions that are required, expand the Required permissions section:

Required permissions

  • billing. resourceAssociations.create on the destination billing account
  • resourcemanager.projects.createBillingAssignment on the project
  • resourcemanager.projects.deleteBillingAssignment on the project

You might also be able to get these permissions with custom roles or other predefined roles.

Configure organization policies

To move a project resource to a new organization resource, you must first apply an organization policy that will define the organization resources to which the project can be moved. You must also set an organization policy in the destination that defines the organization resources from which projects can be imported.

On the parent resource to the project you want to move, set an organization policy that includes the constraints/resourcemanager.allowedExportDestinations constraint. This will define the target destination as a valid location to which you can migrate the project.

On the destination resource, set an organization policy that includes the constraints/resourcemanager.allowedImportSources constraint. This will define the source as a valid location from which you can migrate your project.

For example, say you had a project my-test-project that existed under an organization resource with the ID 12345678901, and you wanted to move it to a new organization resource for your secondary business unit, with the ID 45678901234.

You would set an organization policy on organizations/12345678901with the constraints/resourcemanager.allowedExportDestinations constraint enforced and under:organizations/45678901234 set as an allowed_value.

Then, set an organization policy on organizations/45678901234 with the constraints/resourcemanager.allowedImportSources constraint enforced and under:organizations/12345678901 set as an allowed_value.

Once these organization policies are enforced, you will be able to move my-test-project from organizations/12345678901 to organizations/45678901234, assuming you have the permissions noted in Assign permissions.

Change the billing account for a project

Cloud Billing accounts can be used across organization resources. Moving a project from one organization resource to another won't impact billing, and charges will continue against the old billing account. However, organization resource moves often also include a requirement to move to a new billing account.

To change the billing account, do the following:

  1. Go to the Billing page in the Google Cloud console.
    Go to the Billing page
  2. Click the name of the billing account you want to change.
  3. Under Projects linked to this billing account, find the name of the Project to move and then click the menu button to the right.
  4. Click Change billing, and then select the new billing account.
  5. Click Set account.

Charges already incurred that have not yet been reported in the transaction history will be billed to the former billing account. This can include charges from up to two days prior to when the project was moved.

Move a billing account between organization resources

A billing account can be moved from one organization resource to another, although this isn't often a necessary step. Most existing organization resources will already have a billing account that should be used instead. If you need to migrate an existing billing account:

  1. Get the roles/billing.admin role on the source and destination organization resources.
  2. Go to the Billing page in the Google Cloud console.
    Go to the Billing page
  3. Click on the name of the billing account you want to move.
  4. At the top of the Account Management page, click Change organization.
  5. Select the destination organization resource, and then click Ok.

The billing account is now associated with the specified organization resource.

Perform the migration

If you have the appropriate IAM permissions and the required organization policies are enforced, you can use the Resource Manager API to move a project resource.

gcloud

To migrate a project to another organization resource, run the following command:

gcloud beta projects move PROJECT_ID \
    --organization ORGANIZATION_ID

You can also specify a folder as the target resource, with the following command:

gcloud beta projects move PROJECT_ID \
    --folder FOLDER_ID

Where:

  • PROJECT_ID is the ID or number of the project you wish to migrate.
  • ORGANIZATION_ID is the ID of the organization resource to which you want to move the project. You can only specify one target, either an organization resource or a folder.
  • FOLDER_ID is the ID of the folder to which you want to move the project. You can only specify one target, either a folder or an organization resource.

API

Using the v1 Resource Manager API, you can move a project by setting its parent field to the ID of the destination resource.

To migrate a project:

  • Get the project object using projects.get() method.
  • Set its parent field to the organization resource ID of the organization resource, or the folder ID of the folder to which you are moving it.
  • Update the project object using projects.update() method.

The following code snippet demonstrates the steps above:

    project = crm.projects().get(projectId=flags.projectId).execute()
    project['parent'] = {
        'type': 'organization',
        'id': flags.organizationId
    }

    project = crm.projects().update(
    projectId=flags.projectId, body=project).execute()

Roll back a migration

If you have mistakenly moved a project, you can roll back the operation by performing the move again, with the old source as the new destination, and the old destination as the new source. You must have the necessary IAM permissions and organization policies enforced to allow this as if this were an entirely new migration.

Handling special cases

Migrating projects with no organization resource

You can migrate a project that is not associated with an organization resource into an organization resource. However, you can't change it back to No organization using this process. If you have a project that is associated with your organization resource and you want to revert it to No organization, reach out to your Support representative for assistance.

The process of migrating a project not associated with an organization resource is similar to the process for migrating a project between organization resources, but does not require all of the steps involved in the migration plan. To migrate a project into an organization resource, you should follow these steps:

  1. Verify the impact on this project of the policies it will inherit.

  2. Create a dedicated import folder in the destination organization resource, if desired.

  3. Assign Identity and Access Management permissions for the project and the destination parent as detailed in Assign permissions.

  4. Determine if you need to change the billing account.

Then, you can perform the migration.

Console

To migrate a project into an organization resource:

  1. Open the IAM & admin > Settings page in the Google Cloud console.

    Open the Settings page

  2. Select the Project picker at the top of the page.

  3. From the Organization picker, select No Organization. If you are not associated with any organization resource, the Organization picker will not appear, and you can skip this step.

  4. Select the project you want to migrate.

    Screenshot of project picker

  5. At the top of the page, click Migrate.

  6. On the Organization drop-down list, select the organization resource you want to migrate your project to.

gcloud

To migrate a project into an organization resource, run the following command:

gcloud beta projects move PROJECT_ID \
    --organization ORGANIZATION_ID

Where:

  • PROJECT_ID is the ID of the project you wish to move into the organization resource.
  • ORGANIZATION_ID is the ID of the organization resource to which you wish to move the project.

API

Using the Resource Manager API, you can move a project into the organization resource by setting its parent field to the organization resource ID of the organization resource.

To migrate a project into the organization resource:

  • Get the project object using projects.get() method.
  • Set its parent field to the organization resource ID of the organization resource.
  • Update the project object using projects.update() method.

You can't change the parent field after you set it.

The following code snippet demonstrates the steps above:

    project = crm.projects().get(projectId=flags.projectId).execute()
    project['parent'] = {
        'type': 'organization',
        'id': flags.organizationId
    }

Shared VPC

Shared VPC projects can be migrated following certain conditions. First, a user with the roles/orgpolicy.policyAdmin role in the source organization must set an organization policy containing the constraints/resourcemanager.allowEnabledServicesForExport constraint on the parent of the project to be exported. This constraint should list SHARED_VPC as an allowed_value.

The Shared VPC host project must be migrated first, followed by all of its service projects. We recommend that you match the firewall rules between the organizations at the source and target locations, which should minimize potential issues and avoid any downtime for the projects and network during the migration. We do not offer guarantees about the healthiness of your network if you leave some service projects in the source organization indefinitely while migrating others.

If you move the host project, you can move it back to the source organization, but once you begin moving the service projects, you must move all of them before you can move the host project again.

Custom Identity and Access Management roles

Custom Identity and Access Management roles can be created at the organization level to provide granular control of access to resources, but they are only valid in the organization resource in which they are created. If you try to move a project that contains an IAM policy binding of a user to an organization-level custom IAM role, the move will fail with a failed precondition error, explaining that the role in question does not exist in the destination organization resource.

To list all custom IAM roles at the level of your organization resource, run the following Google Cloud CLI command:

gcloud iam roles list --organization ORGANIZATION_ID

Where the ORGANIZATION_ID is the organization resource ID for which you want to list roles. For information on finding your organization resource ID, see Creating and managing organization resources.

To get information on a custom Identity and Access Management role in your organization resource, run the following Google Cloud CLI command:

gcloud iam roles describe --organization ORGANIZATION_ID \
    ROLE_ID

Where:

  • ORGANIZATION_ID is the organization resource ID of the role's parent organization resource.

  • ROLE_ID is the name of the role you want to describe.

To work around the failed precondition error, you should create equivalent project-level custom roles for each of the organization-level custom roles that the project inherits. Then, remove the IAM role bindings that reference the organization-level custom roles.

Once the project has been migrated, you can update the IAM policies to use the organization-level custom roles in the destination organization resource.

For more information about custom roles, see Creating and managing custom roles.

Bucket Lock

Cloud Storage Bucket Lock allows you to configure a data retention policy on a Cloud Storage bucket that governs how long objects in the bucket must be retained. The bucket lock is protected using a lien to prevent accidentally deleting the project.

The retention policy and lien are kept with the project during a migration, but you should be aware if you are moving a project with a bucket lock enforced, and prevent accidental moves.

VPC Service Controls security perimeters

VPC Service Controls allows users to set up a project-based security perimeter around their Google Cloud services to mitigate data exfiltration risks. You cannot migrate a project that is protected by a VPC Service Controls security perimeter.

To remove a project from a security perimeter, see Managing service perimeters. Projects in VPC Service Controls perimeters may not be blocked from being moved across organization resources for up to a day after a perimeter has been created or updated. It may take several hours for the project to be movable after it has been removed from the service perimeter.

Dedicated Interconnect

We recommend migrating projects with Dedicated Interconnect objects and projects with VLAN attachments to these Dedicated Interconnect objects together. While projects with Dedicated Interconnect objects or VLAN attachments connected to them can be migrated and will function between organization resources, you will not be able to create new VLAN attachments across the organization resource split.

Configuration changes made to a project in one organization resource that has a Dedicated Interconnect object attached or a VLAN attachment to the Dedicated Interconnect object may not propagate to the other, so we recommend not leaving such projects split across organization resources for very long if possible.

Partner Interconnect

There are no special considerations needed when migrating projects with Partner Interconnect.

Cross-project service accounts

If you are moving a project that has a cross-project service account attached to it, that service account will still function in the destination organization resource. That project will continue to work with the attached service account even if there is an organization policy that restricts the domain of that project.

If you are moving a project that owns a cross-project service account attached to another project in the source organization resource, the service account will still function in the destination organization resource. However, you will not be able to use the service account on any resources that have a domain restriction organization policy applied to them that restricts them to the source organization resource's domain.

For example, assume you have project-A, in organizations/12345678901. This project has serviceAccount-1 attached to it, which is set up as a cross-project service account. project-B and project-C, also in organizations/12345678901, use serviceAccount-1 as well.

You have applied an organization policy with the domain restriction constraint to project-C, which only allows it to access the domain of organizations/12345678901.

If you add serviceAccount-1 to the IAM binding for project-C, and then move project-A to organizations/45678901234, the service account will function.

If you move project-A to organizations/45678901234, and then try to add serviceAccount-1 to the IAM binding for project-C, the binding will fail as it violates the domain restriction constraint.

Support cases

If you move a project that has an open support case, you need to reach out to your Google Support contact to let them know the migration has occurred. Any projects that have an open support case with Google will not be able to view those support cases until Google Support updates the case metadata to point to the new organization resource.

If your project is configured to use an Internal OAuth consent screen and you migrate it to another organization resource, only members of the destination organization resource can authorize requests. It may take up to 24 hours for this behavior to take effect. Until then, members of the source organization resource an authorize requests.

The steps below explain how to ensure members of your source organization resource do not lose access during migration. Consider creating new users in your destination organization resource for organization resource members so that you do not need to change the OAuth consent screen configuration.

To avoid loss of access for members of the source organization resource:

  1. Update the OAuth consent screen to be external instead of internal.

  2. Apps that are marked internal and use sensitive data do not need to apply for app verification. If the app uses sensitive data, then when the consent screen is updated to external, the users of the source organization resource will see an unverified app screen before the authorization screen. To avoid this, apply for app verification for the use of sensitive or restricted scopes.

OS Login

If OS Login is enabled in your source project, assign the roles/compute.osLoginExternalUser IAM role to principals that can access the source project, in the destination organization resource to avoid those principals losing access.

Attaching service accounts to resources

For most Google Cloud services, users need the iam.serviceAccounts.actAs permission on a service account to attach that service account to a resource. However, in the past, to ease onboarding certain services allowed users to attach service accounts to resources even if the users didn't have permission to impersonate the service accounts. This is documented here.

If a customer's source organization resource has the legacy behavior (service accounts attachment is possible without the normal role grant) and the destination organization resource does not, grant roles/iam.serviceAccountUser to users that attach these service accounts to resources. For information about impersonating service accounts, see Impersonating service accounts.

To see if your organization resource has the legacy behavior, do the following:

  1. In the Google Cloud console, go to the Organization policies page.

    Go to the Organization policies page

  2. From the project selector at the top of the page, choose the organization resource you want to check for legacy status.

  3. In the filter box at the top of the list of organization policies, enter constraints/appengine.enforceServiceAccountActAsCheck.

  4. If the appengine.enforceServiceAccountActAsCheck organization policy appears in the list, the organization resource has the legacy behavior.

  5. Repeat steps 3 and 4 for each of the following organization policy constraints:

    • appengine.enforceServiceAccountActAsCheck
    • dataflow.enforceComputeDefaultServiceAccountCheck
    • dataproc.enforceComputeDefaultServiceAccountCheck
    • composer.enforceServiceAccountActAsCheck
  6. If any of these organization policy constraints appear, your organization resource uses the legacy behavior.

If the source organization resource has the legacy behavior and the destination does not, grant the roles as mentioned above. If both the source and destination organization resources have the legacy behavior, no action is required, but consider enforcing the policy to prevent unintended impersonation.

Migrating projects with Analytics Hub

If you migrate the project that is using Analytics Hub to a different organization resource, you might encounter some error. To resolve any errors, contact support.