Make a breaking change

Make a breaking change #

A “breaking change” is any change that requires an end user to modify any previously-valid configuration after a provider upgrade. For more information, see Types of breaking changes.

The google and google-beta providers are both considered “stable surfaces” for the purpose of releases, which means that neither provider allows breaking changes except during major releases, which are typically yearly.

Terraform users rely on the stability of Terraform providers (including the Google Cloud provider and other major providers.) Even as part of a major release, breaking changes that are overly broad and/or have little benefit to users can cause deeply negative reactions and significantly delay customers upgrading to the new major version.

Breaking changes may cause significant churn for users by forcing them to update their configurations. It also causes churn in tooling built on top of the providers, such as:

This page covers the general process to make a breaking change. It does not include exact, comprehensive details on how to make every potential breaking change. Breaking changes are complicated; the exact process and implementation may vary drastically depending on the implementation of the impacted resource or field and the change being made.

In minor releases #

If a breaking change fixes a bug that impacts all configurations that include a field or resource, it is generally allowed in a minor release. For example:

  • Removing update support from a field if that field is not actually updatable in the API.
  • Marking a field required if omitting the field always causes an API error.

The following types of changes can be made if the default behavior stays the same and new behavior can be enabled with a flag:

  • Major resource-level or field-level behavioural changes

In the 6.0.0 major release #

The general process for contributing a breaking change to the 6.0.0 major release is:

  1. Make the main branch forwards-compatible with the major release
  2. Add deprecations and warnings to the main branch of magic-modules
  3. Add upgrade guide entries to the FEATURE-BRANCH-major-release-6.0.0 branch of magic-modules
  4. Make the breaking change on FEATURE-BRANCH-major-release-6.0.0

These are covered in more detail in the following sections. The upgrade guide and the actual breaking change will be merged only after both are completed.

Make the main branch forwards-compatible with the major release #

What forwards-compatibility means will vary depending on the breaking change. For example:

  • If a required field is being removed, make the field optional on the main branch.
  • If a field is being renamed, the new field must be added to the main branch

Add deprecations and warnings to the main branch of magic-modules #

Deprecations and warnings must be actionable at the time that they are added to the main branch, and they must be added prior to the 6.0.0 major release. Every deprecation or warning should be surfaced to users of the provider at runtime as well as in documentation.

Field deprecation (due to removal or rename) #

Set deprecation_message on the field. For example:

- name: 'apiFieldName'
  type: String
  description: |
    MULTILINE_FIELD_DESCRIPTION    
  deprecation_message: '`api_field_name` is deprecated and will be removed in a future major release. Use `other_field_name` instead.'

Replace the second sentence with an appropriate short description of the replacement path and/or the reason for deprecation.

The deprecation message will automatically show up in the resource documentation.

  1. Set Deprecated on the field. For example:

    "api_field_name": {
       Type:       schema.String,
       Deprecated: "`api_field_name` is deprecated and will be removed in a future major release. Use `other_field_name` instead.",
       ...
    }
    

    Replace the second sentence with an appropriate short description of the replacement path and/or the reason for deprecation.

  2. Update the documentation for the field to include the deprecation notice. For example:

    * `api_field_name` - (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html), Deprecated) FIELD_DESCRIPTION. `api_field_name` is deprecated and will be removed in a future major release. Use `other_field_name` instead.
    

Resource deprecation (due to removal or rename) #

Set deprecation_message on the resource. For example:

deprecation_message: >-
  `google_RESOURCE_NAME` is deprecated and will be removed in a future major release.
  Use `google_OTHER_RESOURCE_NAME` instead.  

Replace RESOURCE_NAME with the name of the resource (excluding the google_ prefix). Replace the second sentence with an appropriate short description of the replacement path and/or the reason for deprecation.

The deprecation message will automatically show up in the resource documentation.

  1. Set DeprecationMessage on the field. For example:

    return &schema.Resource{
       ...
       DeprecationMessage: "`google_RESOURCE_NAME` is deprecated and will be removed in a future " +
                           "major release. Use `google_OTHER_RESOURCE_NAME` instead.",
       ...
    }
    

    Replace RESOURCE_NAME with the name of the resource (excluding the google_ prefix). Replace the second sentence with an appropriate short description of the replacement path and/or the reason for deprecation.

  2. Add a warning to the resource documentation stating that the resource is deprecated. For example:

    ~> **Warning:** `google_RESOURCE_NAME` is deprecated and will be removed in a future
    major release. Use `google_OTHER_RESOURCE_NAME` instead.
    

Other breaking changes #

Other breaking changes should be called out in the docs for the impacted field or resource. It is also great to log warnings at runtime if possible.

Make the change on FEATURE-BRANCH-major-release-6.0.0 #

When working on your breaking change, make sure that your base branch is FEATURE-BRANCH-major-release-6.0.0. This means that you will follow the standard contribution process with the following changes:

  1. Before you start, check out and sync your local magic-modules and provider repositories with the upstream major release branches.
    cd ~/magic-modules
    git checkout FEATURE-BRANCH-major-release-6.0.0
    git pull --ff-only origin FEATURE-BRANCH-major-release-6.0.0
    cd $GOPATH/src/github.com/hashicorp/terraform-provider-google
    git checkout FEATURE-BRANCH-major-release-6.0.0
    git pull --ff-only origin FEATURE-BRANCH-major-release-6.0.0
    cd $GOPATH/src/github.com/hashicorp/terraform-provider-google-beta
    git checkout FEATURE-BRANCH-major-release-6.0.0
    git pull --ff-only origin FEATURE-BRANCH-major-release-6.0.0
    
  2. Make sure that any deprecation notices and warnings that you added in previous sections are present on the major release branch. Changes to the main branch will be merged into the major release branch every Monday.
  3. Make the breaking change.
  4. Add the upgrade guide entries to version_6_upgrade.html.markdown. Entries should focus on the changes that users need to make when upgrading to 6.0.0, rather than how to write configurations after upgrading. See Terraform provider for Google Cloud 5.0.0 Upgrade Guide and other upgrade guides for examples.
  5. Remove any deprecation notices and warnings (including in documentation) not already removed by the breaking change.
  6. When you create your pull request, change the base branch to FEATURE-BRANCH-major-release-6.0.0
  7. To resolve merge conflicts with git rebase or git merge, use FEATURE-BRANCH-major-release-6.0.0 instead of main.

What’s next? #