Repository: kubernetes-sigs/cluster-api-provider-azure
Pull request #1516 (2021-07-12 22:39:37)

have consistent validation/defaulting for machine and machinetemplate
 <!-- If this is your first PR, welcome! Please make sure you read the [contributing guidelines](../CONTRIBUTING.md). -->

 <!-- Please label this pull request according to what type of issue you are addressing (see ../CONTRIBUTING.md) -->
**What type of PR is this?**
/kind other
<!--
Add one of the following kinds:
/kind feature
/kind bug
/kind api-change
/kind cleanup
/kind deprecation
/kind design
/kind documentation
/kind failing-test
/kind flake
/kind other
-->

**What this PR does / why we need it**:
Make the validation and defaulting of `AzureMachine` and `AzureMachineTemplate` consistent with each other. This is to make sure that the controller does not end up in a continuous reconcile loop.

Ref: https://github.com/kubernetes-sigs/cluster-api-provider-azure/pull/1501#issuecomment-878388206


**TODOs**:
<!-- Put an "X" character inside the brackets of each completed task. Some may be optional depending on the PR. -->

- [x] squashed commits
- [x] includes documentation
- [x] adds unit tests

**Release note**:
<!--  Write your release note:
1. Enter your extended release note in the below block. If the PR requires additional action from users switching to the new release, include the string "action required".
2. If no release note is required, just write "NONE".
-->
```release-note
Consistent validation for AzureMachineTemplate and AzureMachine
```


k8s-ci-robot: @ykakarap: The label(s) `kind/other` cannot be applied, because the repository doesn't have them.

<details>

In response to [this](https://github.com/kubernetes-sigs/cluster-api-provider-azure/pull/1516):

> 
>
> 
>**What type of PR is this?**
>/kind other
>
>
>**What this PR does / why we need it**:
>Make the validation and defaulting of `AzureMachine` and `AzureMachineTemplate` consistent with each other. This is to make sure that the controller does not end up in a continuous reconcile loop.
>
>Ref: https://github.com/kubernetes-sigs/cluster-api-provider-azure/pull/1501#issuecomment-878388206
>
>
>**TODOs**:
>
>
>- [x] squashed commits
>- [x] includes documentation
>- [x] adds unit tests
>
>**Release note**:
>
>```release-note
>NONE
>```
>


Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository.
</details>
k8s-ci-robot: [APPROVALNOTIFIER] This PR is **NOT APPROVED**

This pull-request has been approved by:
To complete the [pull request process](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process), please assign **devigned** after the PR has been reviewed.
You can assign the PR to them by writing `/assign @devigned` in a comment when ready.

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=kubernetes-sigs%2Fcluster-api-provider-azure).

<details open>
Needs approval from an approver in each of these files:

- **[OWNERS](https://github.com/kubernetes-sigs/cluster-api-provider-azure/blob/master/OWNERS)**

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":["devigned"]} -->
k8s-ci-robot: @ykakarap: The following test **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-cluster-api-provider-azure-verify | 43b869a966215d4f7c2a6e6809533dc59c08f0ba | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_cluster-api-provider-azure/1516/pull-cluster-api-provider-azure-verify/1414716106274246656) | `/test pull-cluster-api-provider-azure-verify`

[Full PR test history](https://prow.k8s.io/pr-history?org=kubernetes-sigs&repo=cluster-api-provider-azure&pr=1516). [Your PR dashboard](https://prow.k8s.io/pr?query=is%3Apr%20state%3Aopen%20author%3Aykakarap). Please help us cut down on flakes by [linking to](https://git.k8s.io/community/contributors/devel/sig-testing/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/kubernetes-sigs/cluster-api-provider-azure/issues?q=is:issue+is:open) when you hit one in your PR.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
k8s-ci-robot: @ykakarap: The following tests **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-cluster-api-provider-azure-verify | 43b869a966215d4f7c2a6e6809533dc59c08f0ba | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_cluster-api-provider-azure/1516/pull-cluster-api-provider-azure-verify/1414716106274246656) | `/test pull-cluster-api-provider-azure-verify`
pull-cluster-api-provider-azure-apidiff | 43b869a966215d4f7c2a6e6809533dc59c08f0ba | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_cluster-api-provider-azure/1516/pull-cluster-api-provider-azure-apidiff/1414716106307801088) | `/test pull-cluster-api-provider-azure-apidiff`

[Full PR test history](https://prow.k8s.io/pr-history?org=kubernetes-sigs&repo=cluster-api-provider-azure&pr=1516). [Your PR dashboard](https://prow.k8s.io/pr?query=is%3Apr%20state%3Aopen%20author%3Aykakarap). Please help us cut down on flakes by [linking to](https://git.k8s.io/community/contributors/devel/sig-testing/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/kubernetes-sigs/cluster-api-provider-azure/issues?q=is:issue+is:open) when you hit one in your PR.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
k8s-ci-robot: @ykakarap: The following tests **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-cluster-api-provider-azure-verify | 43b869a966215d4f7c2a6e6809533dc59c08f0ba | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_cluster-api-provider-azure/1516/pull-cluster-api-provider-azure-verify/1414716106274246656) | `/test pull-cluster-api-provider-azure-verify`
pull-cluster-api-provider-azure-apidiff | 1526ca8823a8657fe00a8eb07f6e7f2bef9490b6 | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_cluster-api-provider-azure/1516/pull-cluster-api-provider-azure-apidiff/1414716736560697344) | `/test pull-cluster-api-provider-azure-apidiff`

[Full PR test history](https://prow.k8s.io/pr-history?org=kubernetes-sigs&repo=cluster-api-provider-azure&pr=1516). [Your PR dashboard](https://prow.k8s.io/pr?query=is%3Apr%20state%3Aopen%20author%3Aykakarap). Please help us cut down on flakes by [linking to](https://git.k8s.io/community/contributors/devel/sig-testing/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/kubernetes-sigs/cluster-api-provider-azure/issues?q=is:issue+is:open) when you hit one in your PR.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
k8s-ci-robot: @ykakarap: The following tests **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-cluster-api-provider-azure-apidiff | 1526ca8823a8657fe00a8eb07f6e7f2bef9490b6 | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_cluster-api-provider-azure/1516/pull-cluster-api-provider-azure-apidiff/1414716736560697344) | `/test pull-cluster-api-provider-azure-apidiff`
pull-cluster-api-provider-azure-verify | 1526ca8823a8657fe00a8eb07f6e7f2bef9490b6 | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_cluster-api-provider-azure/1516/pull-cluster-api-provider-azure-verify/1414716736522948608) | `/test pull-cluster-api-provider-azure-verify`

[Full PR test history](https://prow.k8s.io/pr-history?org=kubernetes-sigs&repo=cluster-api-provider-azure&pr=1516). [Your PR dashboard](https://prow.k8s.io/pr?query=is%3Apr%20state%3Aopen%20author%3Aykakarap). Please help us cut down on flakes by [linking to](https://git.k8s.io/community/contributors/devel/sig-testing/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/kubernetes-sigs/cluster-api-provider-azure/issues?q=is:issue+is:open) when you hit one in your PR.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
k8s-ci-robot: @ykakarap: The following tests **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-cluster-api-provider-azure-apidiff | 1526ca8823a8657fe00a8eb07f6e7f2bef9490b6 | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_cluster-api-provider-azure/1516/pull-cluster-api-provider-azure-apidiff/1414716736560697344) | `/test pull-cluster-api-provider-azure-apidiff`
pull-cluster-api-provider-azure-verify | 1526ca8823a8657fe00a8eb07f6e7f2bef9490b6 | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_cluster-api-provider-azure/1516/pull-cluster-api-provider-azure-verify/1414716736522948608) | `/test pull-cluster-api-provider-azure-verify`
pull-cluster-api-provider-azure-test | 1526ca8823a8657fe00a8eb07f6e7f2bef9490b6 | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_cluster-api-provider-azure/1516/pull-cluster-api-provider-azure-test/1414716736388730880) | `/test pull-cluster-api-provider-azure-test`

[Full PR test history](https://prow.k8s.io/pr-history?org=kubernetes-sigs&repo=cluster-api-provider-azure&pr=1516). [Your PR dashboard](https://prow.k8s.io/pr?query=is%3Apr%20state%3Aopen%20author%3Aykakarap). Please help us cut down on flakes by [linking to](https://git.k8s.io/community/contributors/devel/sig-testing/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/kubernetes-sigs/cluster-api-provider-azure/issues?q=is:issue+is:open) when you hit one in your PR.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
k8s-ci-robot: @ykakarap: The following tests **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-cluster-api-provider-azure-verify | 1526ca8823a8657fe00a8eb07f6e7f2bef9490b6 | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_cluster-api-provider-azure/1516/pull-cluster-api-provider-azure-verify/1414716736522948608) | `/test pull-cluster-api-provider-azure-verify`
pull-cluster-api-provider-azure-test | 1526ca8823a8657fe00a8eb07f6e7f2bef9490b6 | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_cluster-api-provider-azure/1516/pull-cluster-api-provider-azure-test/1414716736388730880) | `/test pull-cluster-api-provider-azure-test`
pull-cluster-api-provider-azure-apidiff | 3b332948b0b3779d4292f9d46a6eacef414a6f09 | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_cluster-api-provider-azure/1516/pull-cluster-api-provider-azure-apidiff/1414721779628249088) | `/test pull-cluster-api-provider-azure-apidiff`

[Full PR test history](https://prow.k8s.io/pr-history?org=kubernetes-sigs&repo=cluster-api-provider-azure&pr=1516). [Your PR dashboard](https://prow.k8s.io/pr?query=is%3Apr%20state%3Aopen%20author%3Aykakarap). Please help us cut down on flakes by [linking to](https://git.k8s.io/community/contributors/devel/sig-testing/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/kubernetes-sigs/cluster-api-provider-azure/issues?q=is:issue+is:open) when you hit one in your PR.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
k8s-ci-robot: @ykakarap: The following tests **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-cluster-api-provider-azure-apidiff | 3b332948b0b3779d4292f9d46a6eacef414a6f09 | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_cluster-api-provider-azure/1516/pull-cluster-api-provider-azure-apidiff/1414721779628249088) | `/test pull-cluster-api-provider-azure-apidiff`
pull-cluster-api-provider-azure-test | 3b332948b0b3779d4292f9d46a6eacef414a6f09 | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_cluster-api-provider-azure/1516/pull-cluster-api-provider-azure-test/1414721779447894016) | `/test pull-cluster-api-provider-azure-test`

[Full PR test history](https://prow.k8s.io/pr-history?org=kubernetes-sigs&repo=cluster-api-provider-azure&pr=1516). [Your PR dashboard](https://prow.k8s.io/pr?query=is%3Apr%20state%3Aopen%20author%3Aykakarap). Please help us cut down on flakes by [linking to](https://git.k8s.io/community/contributors/devel/sig-testing/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/kubernetes-sigs/cluster-api-provider-azure/issues?q=is:issue+is:open) when you hit one in your PR.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
k8s-ci-robot: @ykakarap: The following tests **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-cluster-api-provider-azure-test | 3b332948b0b3779d4292f9d46a6eacef414a6f09 | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_cluster-api-provider-azure/1516/pull-cluster-api-provider-azure-test/1414721779447894016) | `/test pull-cluster-api-provider-azure-test`
pull-cluster-api-provider-azure-apidiff | 04d77fab1503024a3138a3a48b128540f11e5f8e | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_cluster-api-provider-azure/1516/pull-cluster-api-provider-azure-apidiff/1414729956717498368) | `/test pull-cluster-api-provider-azure-apidiff`

[Full PR test history](https://prow.k8s.io/pr-history?org=kubernetes-sigs&repo=cluster-api-provider-azure&pr=1516). [Your PR dashboard](https://prow.k8s.io/pr?query=is%3Apr%20state%3Aopen%20author%3Aykakarap). Please help us cut down on flakes by [linking to](https://git.k8s.io/community/contributors/devel/sig-testing/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/kubernetes-sigs/cluster-api-provider-azure/issues?q=is:issue+is:open) when you hit one in your PR.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
k8s-ci-robot: @ykakarap: The following tests **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-cluster-api-provider-azure-apidiff | 04d77fab1503024a3138a3a48b128540f11e5f8e | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_cluster-api-provider-azure/1516/pull-cluster-api-provider-azure-apidiff/1414729956717498368) | `/test pull-cluster-api-provider-azure-apidiff`
pull-cluster-api-provider-azure-e2e-windows | 04d77fab1503024a3138a3a48b128540f11e5f8e | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_cluster-api-provider-azure/1516/pull-cluster-api-provider-azure-e2e-windows/1414729956629417984) | `/test pull-cluster-api-provider-azure-e2e-windows`

[Full PR test history](https://prow.k8s.io/pr-history?org=kubernetes-sigs&repo=cluster-api-provider-azure&pr=1516). [Your PR dashboard](https://prow.k8s.io/pr?query=is%3Apr%20state%3Aopen%20author%3Aykakarap). Please help us cut down on flakes by [linking to](https://git.k8s.io/community/contributors/devel/sig-testing/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/kubernetes-sigs/cluster-api-provider-azure/issues?q=is:issue+is:open) when you hit one in your PR.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
k8s-ci-robot: @ykakarap: The following tests **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-cluster-api-provider-azure-apidiff | 04d77fab1503024a3138a3a48b128540f11e5f8e | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_cluster-api-provider-azure/1516/pull-cluster-api-provider-azure-apidiff/1414729956717498368) | `/test pull-cluster-api-provider-azure-apidiff`
pull-cluster-api-provider-azure-e2e-windows | 04d77fab1503024a3138a3a48b128540f11e5f8e | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_cluster-api-provider-azure/1516/pull-cluster-api-provider-azure-e2e-windows/1414729956629417984) | `/test pull-cluster-api-provider-azure-e2e-windows`
pull-cluster-api-provider-azure-e2e | 04d77fab1503024a3138a3a48b128540f11e5f8e | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_cluster-api-provider-azure/1516/pull-cluster-api-provider-azure-e2e/1414729960806944768) | `/test pull-cluster-api-provider-azure-e2e`

[Full PR test history](https://prow.k8s.io/pr-history?org=kubernetes-sigs&repo=cluster-api-provider-azure&pr=1516). [Your PR dashboard](https://prow.k8s.io/pr?query=is%3Apr%20state%3Aopen%20author%3Aykakarap). Please help us cut down on flakes by [linking to](https://git.k8s.io/community/contributors/devel/sig-testing/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/kubernetes-sigs/cluster-api-provider-azure/issues?q=is:issue+is:open) when you hit one in your PR.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
shysank: /test pull-cluster-api-provider-azure-e2e
/test pull-cluster-api-provider-azure-e2e-windows

k8s-ci-robot: @ykakarap: The following tests **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-cluster-api-provider-azure-apidiff | 04d77fab1503024a3138a3a48b128540f11e5f8e | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_cluster-api-provider-azure/1516/pull-cluster-api-provider-azure-apidiff/1414729956717498368) | `/test pull-cluster-api-provider-azure-apidiff`
pull-cluster-api-provider-azure-e2e | 04d77fab1503024a3138a3a48b128540f11e5f8e | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_cluster-api-provider-azure/1516/pull-cluster-api-provider-azure-e2e/1414729960806944768) | `/test pull-cluster-api-provider-azure-e2e`
pull-cluster-api-provider-azure-e2e-windows | 04d77fab1503024a3138a3a48b128540f11e5f8e | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_cluster-api-provider-azure/1516/pull-cluster-api-provider-azure-e2e-windows/1415010006037696512) | `/test pull-cluster-api-provider-azure-e2e-windows`

[Full PR test history](https://prow.k8s.io/pr-history?org=kubernetes-sigs&repo=cluster-api-provider-azure&pr=1516). [Your PR dashboard](https://prow.k8s.io/pr?query=is%3Apr%20state%3Aopen%20author%3Aykakarap). Please help us cut down on flakes by [linking to](https://git.k8s.io/community/contributors/devel/sig-testing/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/kubernetes-sigs/cluster-api-provider-azure/issues?q=is:issue+is:open) when you hit one in your PR.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
k8s-ci-robot: @ykakarap: The following tests **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-cluster-api-provider-azure-apidiff | 04d77fab1503024a3138a3a48b128540f11e5f8e | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_cluster-api-provider-azure/1516/pull-cluster-api-provider-azure-apidiff/1414729956717498368) | `/test pull-cluster-api-provider-azure-apidiff`
pull-cluster-api-provider-azure-e2e-windows | 04d77fab1503024a3138a3a48b128540f11e5f8e | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_cluster-api-provider-azure/1516/pull-cluster-api-provider-azure-e2e-windows/1415010006037696512) | `/test pull-cluster-api-provider-azure-e2e-windows`
pull-cluster-api-provider-azure-e2e | 04d77fab1503024a3138a3a48b128540f11e5f8e | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_cluster-api-provider-azure/1516/pull-cluster-api-provider-azure-e2e/1415010005999947776) | `/test pull-cluster-api-provider-azure-e2e`

[Full PR test history](https://prow.k8s.io/pr-history?org=kubernetes-sigs&repo=cluster-api-provider-azure&pr=1516). [Your PR dashboard](https://prow.k8s.io/pr?query=is%3Apr%20state%3Aopen%20author%3Aykakarap). Please help us cut down on flakes by [linking to](https://git.k8s.io/community/contributors/devel/sig-testing/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/kubernetes-sigs/cluster-api-provider-azure/issues?q=is:issue+is:open) when you hit one in your PR.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
shysank: Looks like it's failing in one of the webhooks
```
E0713 18:16:07.570772       1 controller.go:302] controller-runtime/manager/controller/azurecluster "msg"="Reconciler error" "error"="AzureClusterIdentity.infrastructure.cluster.x-k8s.io \"cluster-identity\" not found" "name"="capz-e2e-g4bxk2" "namespace"="capz-e2e-g4bxk2" "reconciler group"="infrastructure.cluster.x-k8s.io" "reconciler kind"="AzureCluster" 
I0713 18:16:07.573298       1 http.go:98] controller-runtime/webhook/webhooks "msg"="received request" "webhook"="/validate-infrastructure-cluster-x-k8s-io-v1alpha4-azuremachinetemplate" "UID"="a8f65c88-48d1-4ca0-824b-48a5293c18e0" "kind"={"group":"infrastructure.cluster.x-k8s.io","version":"v1alpha4","kind":"AzureMachineTemplate"} "resource"={"group":"infrastructure.cluster.x-k8s.io","version":"v1alpha4","resource":"azuremachinetemplates"}
I0713 18:16:07.573576       1 deleg.go:130] azurecluster-resource "msg"="validate update"  "name"="capz-e2e-g4bxk2-md-0"
I0713 18:16:07.574695       1 http.go:138] controller-runtime/webhook/webhooks "msg"="wrote response" "code"=422 "reason"="Invalid" "webhook"="/validate-infrastructure-cluster-x-k8s-io-v1alpha4-azuremachinetemplate" "UID"="a8f65c88-48d1-4ca0-824b-48a5293c18e0" "allowed"=false
I0713 18:16:07.587646       1 http.go:98] controller-runtime/webhook/webhooks "msg"="received request" "webhook"="/mutate-infrastructure-cluster-x-k8s-io-v1alpha4-azuremachinetemplate" "UID"="8dd8f960-25e3-4a2d-a445-1de0002c88c9" "kind"={"group":"infrastructure.cluster.x-k8s.io","version":"v1alpha4","kind":"AzureMachineTemplate"} "resource"={"group":"infrastructure.cluster.x-k8s.io","version":"v1alpha4","resource":"azuremachinetemplates"}
I0713 18:16:07.588468       1 deleg.go:130] azuremachinetemplate-resource "msg"="default"  "name"="capz-e2e-g4bxk2-md-0"
I0713 18:16:07.590008       1 http.go:138] controller-runtime/webhook/webhooks "msg"="wrote response" "code"=200 "reason"="" "webhook"="/mutate-infrastructure-cluster-x-k8s-io-v1alpha4-azuremachinetemplate" "UID"="8dd8f960-25e3-4a2d-a445-1de0002c88c9" "allowed"=true
I0713 18:16:07.594402       1 http.go:98] controller-runtime/webhook/webhooks "msg"="received request" "webhook"="/validate-infrastructure-cluster-x-k8s-io-v1alpha4-azuremachinetemplate" "UID"="4bc26884-c38b-43c6-82cb-a4034983e41d" "kind"={"group":"infrastructure.cluster.x-k8s.io","version":"v1alpha4","kind":"AzureMachineTemplate"} "resource"={"group":"infrastructure.cluster.x-k8s.io","version":"v1alpha4","resource":"azuremachinetemplates"}
I0713 18:16:07.594794       1 deleg.go:130] azurecluster-resource "msg"="validate update"  "name"="capz-e2e-g4bxk2-md-0"
I0713 18:16:07.595569       1 http.go:138] controller-runtime/webhook/webhooks "msg"="wrote response" "code"=422 "reason"="Invalid" "webhook"="/validate-infrastructure-cluster-x-k8s-io-v1alpha4-azuremachinetemplate" "UID"="4bc26884-c38b-43c6-82cb-a4034983e41d" "allowed"=false
I0713 18:16:07.644296       1 http.go:98] controller-runtime/webhook/webhooks "msg"="received request" "webhook"="/mutate-infrastructure-cluster-x-k8s-io-v1alpha4-azuremachinetemplate" "UID"="bfac3b58-994f-40ce-8774-24cee162e575" "kind"={"group":"infrastructure.cluster.x-k8s.io","version":"v1alpha4","kind":"AzureMachineTemplate"} "resource"={"group":"infrastructure.cluster.x-k8s.io","version":"v1alpha4","resource":"azuremachinetemplates"}
I0713 18:16:07.644604       1 deleg.go:130] azuremachinetemplate-resource "msg"="default"  "name"="capz-e2e-g4bxk2-md-0"
I0713 18:16:07.645338       1 http.go:138] controller-runtime/webhook/webhooks "msg"="wrote response" "code"=200 "reason"="" "webhook"="/mutate-infrastructure-cluster-x-k8s-io-v1alpha4-azuremachinetemplate" "UID"="bfac3b58-994f-40ce-8774-24cee162e575" "allowed"=true
I0713 18:16:07.653880       1 http.go:98] controller-runtime/webhook/webhooks "msg"="received request" "webhook"="/validate-infrastructure-cluster-x-k8s-io-v1alpha4-azuremachinetemplate" "UID"="b6aebbc7-ea1b-44e9-956b-2568bc0507c3" "kind"={"group":"infrastructure.cluster.x-k8s.io","version":"v1alpha4","kind":"AzureMachineTemplate"} "resource"={"group":"infrastructure.cluster.x-k8s.io","version":"v1alpha4","resource":"azuremachinetemplates"}
I0713 18:16:07.654427       1 deleg.go:130] azurecluster-resource "msg"="validate update"  "name"="capz-e2e-g4bxk2-md-0"
I0713 18:16:07.655474       1 http.go:138] controller-runtime/webhook/webhooks "msg"="wrote response" "code"=422 "reason"="Invalid" "webhook"="/validate-infrastructure-cluster-x-k8s-io-v1alpha4-azuremachinetemplate" "UID"="b6aebbc7-ea1b-44e9-956b-2568bc0507c3" "allowed"=false
I0713 18:16:07.669878       1 http.go:98] controller-runtime/webhook/webhooks "msg"="received request" "webhook"="/mutate-infrastructure-cluster-x-k8s-io-v1alpha4-azuremachinetemplate" "UID"="ea2238e6-8b5c-45d7-8824-9d53c5796fed" "kind"={"group":"infrastructure.cluster.x-k8s.io","version":"v1alpha4","kind":"AzureMachineTemplate"} "resource"={"group":"infrastructure.cluster.x-k8s.io","version":"v1alpha4","resource":"azuremachinetemplates"}
I0713 18:16:07.670291       1 deleg.go:130] azuremachinetemplate-resource "msg"="default"  "name"="capz-e2e-g4bxk2-md-0"
I0713 18:16:07.670933       1 http.go:138] controller-runtime/webhook/webhooks "msg"="wrote response" "code"=200 "reason"="" "webhook"="/mutate-infrastructure-cluster-x-k8s-io-v1alpha4-azuremachinetemplate" "UID"="ea2238e6-8b5c-45d7-8824-9d53c5796fed" "allowed"=true
```
ykakarap: Yes. The newly added defaulting and validation logic looks like are causing the problem. I am still debugging the problem. Will post more updates here once I have more information. 
ykakarap: Ref for more details: https://kubernetes.slack.com/archives/C8TSNPY4T/p1626192816217300?thread_ts=1626139569.203800&cid=C8TSNPY4T
k8s-ci-robot: @ykakarap: The following tests **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
pull-cluster-api-provider-azure-e2e-windows | 04d77fab1503024a3138a3a48b128540f11e5f8e | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_cluster-api-provider-azure/1516/pull-cluster-api-provider-azure-e2e-windows/1415010006037696512) | `/test pull-cluster-api-provider-azure-e2e-windows`
pull-cluster-api-provider-azure-e2e | 04d77fab1503024a3138a3a48b128540f11e5f8e | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_cluster-api-provider-azure/1516/pull-cluster-api-provider-azure-e2e/1415010005999947776) | `/test pull-cluster-api-provider-azure-e2e`
pull-cluster-api-provider-azure-apidiff | 813f9f196cd542a2a13a24e5362d25a5d66739b2 | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_cluster-api-provider-azure/1516/pull-cluster-api-provider-azure-apidiff/1415056568533127168) | `/test pull-cluster-api-provider-azure-apidiff`

[Full PR test history](https://prow.k8s.io/pr-history?org=kubernetes-sigs&repo=cluster-api-provider-azure&pr=1516). [Your PR dashboard](https://prow.k8s.io/pr?query=is%3Apr%20state%3Aopen%20author%3Aykakarap). Please help us cut down on flakes by [linking to](https://git.k8s.io/community/contributors/devel/sig-testing/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/kubernetes-sigs/cluster-api-provider-azure/issues?q=is:issue+is:open) when you hit one in your PR.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
ykakarap: @shysank @CecileRobertMichon This PR is now ready for review.
ykakarap: /assign @CecileRobertMichon 
/assign @shysank 

Patch:
diff --git a/api/v1alpha4/azuremachine_default.go b/api/v1alpha4/azuremachine_default.go
index f5bdffcfe..bb3743df9 100644
--- a/api/v1alpha4/azuremachine_default.go
+++ b/api/v1alpha4/azuremachine_default.go
@@ -19,6 +19,7 @@ package v1alpha4
 import (
 	"encoding/base64"
 
+	"github.com/go-logr/logr"
 	"golang.org/x/crypto/ssh"
 	"k8s.io/apimachinery/pkg/util/uuid"
 
@@ -26,60 +27,70 @@ import (
 )
 
 // SetDefaultSSHPublicKey sets the default SSHPublicKey for an AzureMachine.
-func (m *AzureMachine) SetDefaultSSHPublicKey() error {
-	sshKeyData := m.Spec.SSHPublicKey
+func (s *AzureMachineSpec) SetDefaultSSHPublicKey() error {
+	sshKeyData := s.SSHPublicKey
 	if sshKeyData == "" {
 		_, publicRsaKey, err := utilSSH.GenerateSSHKey()
 		if err != nil {
 			return err
 		}
 
-		m.Spec.SSHPublicKey = base64.StdEncoding.EncodeToString(ssh.MarshalAuthorizedKey(publicRsaKey))
+		s.SSHPublicKey = base64.StdEncoding.EncodeToString(ssh.MarshalAuthorizedKey(publicRsaKey))
 	}
 
 	return nil
 }
 
 // SetDefaultCachingType sets the default cache type for an AzureMachine.
-func (m *AzureMachine) SetDefaultCachingType() error {
-	if m.Spec.OSDisk.CachingType == "" {
-		m.Spec.OSDisk.CachingType = "None"
+func (s *AzureMachineSpec) SetDefaultCachingType() {
+	if s.OSDisk.CachingType == "" {
+		s.OSDisk.CachingType = "None"
 	}
-	return nil
 }
 
 // SetDataDisksDefaults sets the data disk defaults for an AzureMachine.
-func (m *AzureMachine) SetDataDisksDefaults() {
+func (s *AzureMachineSpec) SetDataDisksDefaults() {
 	set := make(map[int32]struct{})
 	// populate all the existing values in the set
-	for _, disk := range m.Spec.DataDisks {
+	for _, disk := range s.DataDisks {
 		if disk.Lun != nil {
 			set[*disk.Lun] = struct{}{}
 		}
 	}
 	// Look for unique values for unassigned LUNs
-	for i, disk := range m.Spec.DataDisks {
+	for i, disk := range s.DataDisks {
 		if disk.Lun == nil {
-			for l := range m.Spec.DataDisks {
+			for l := range s.DataDisks {
 				lun := int32(l)
 				if _, ok := set[lun]; !ok {
-					m.Spec.DataDisks[i].Lun = &lun
+					s.DataDisks[i].Lun = &lun
 					set[lun] = struct{}{}
 					break
 				}
 			}
 		}
 		if disk.CachingType == "" {
-			m.Spec.DataDisks[i].CachingType = "ReadWrite"
+			s.DataDisks[i].CachingType = "ReadWrite"
 		}
 	}
 }
 
 // SetIdentityDefaults sets the defaults for VM Identity.
-func (m *AzureMachine) SetIdentityDefaults() {
-	if m.Spec.Identity == VMIdentitySystemAssigned {
-		if m.Spec.RoleAssignmentName == "" {
-			m.Spec.RoleAssignmentName = string(uuid.NewUUID())
+func (s *AzureMachineSpec) SetIdentityDefaults() {
+	if s.Identity == VMIdentitySystemAssigned {
+		if s.RoleAssignmentName == "" {
+			s.RoleAssignmentName = string(uuid.NewUUID())
 		}
 	}
 }
+
+// SetDefaults sets to the defaults for the AzureMachineSpec.
+func (s *AzureMachineSpec) SetDefaults(log logr.Logger) {
+	err := s.SetDefaultSSHPublicKey()
+	if err != nil {
+		log.Error(err, "SetDefaultSshPublicKey failed")
+	}
+	s.SetDefaultCachingType()
+	s.SetDataDisksDefaults()
+	s.SetIdentityDefaults()
+}
diff --git a/api/v1alpha4/azuremachine_validation.go b/api/v1alpha4/azuremachine_validation.go
index ed7e31d34..c996a369e 100644
--- a/api/v1alpha4/azuremachine_validation.go
+++ b/api/v1alpha4/azuremachine_validation.go
@@ -27,6 +27,37 @@ import (
 	"k8s.io/apimachinery/pkg/util/validation/field"
 )
 
+// ValidateAzureMachineSpec check for validation errors of azuremachine.spec.
+func ValidateAzureMachineSpec(spec AzureMachineSpec) field.ErrorList {
+	var allErrs field.ErrorList
+
+	if errs := ValidateImage(spec.Image, field.NewPath("image")); len(errs) > 0 {
+		allErrs = append(allErrs, errs...)
+	}
+
+	if errs := ValidateOSDisk(spec.OSDisk, field.NewPath("osDisk")); len(errs) > 0 {
+		allErrs = append(allErrs, errs...)
+	}
+
+	if errs := ValidateSSHKey(spec.SSHPublicKey, field.NewPath("sshPublicKey")); len(errs) > 0 {
+		allErrs = append(allErrs, errs...)
+	}
+
+	if errs := ValidateSystemAssignedIdentity(spec.Identity, "", spec.RoleAssignmentName, field.NewPath("roleAssignmentName")); len(errs) > 0 {
+		allErrs = append(allErrs, errs...)
+	}
+
+	if errs := ValidateUserAssignedIdentity(spec.Identity, spec.UserAssignedIdentities, field.NewPath("userAssignedIdentities")); len(errs) > 0 {
+		allErrs = append(allErrs, errs...)
+	}
+
+	if errs := ValidateDataDisks(spec.DataDisks, field.NewPath("dataDisks")); len(errs) > 0 {
+		allErrs = append(allErrs, errs...)
+	}
+
+	return allErrs
+}
+
 // ValidateSSHKey validates an SSHKey.
 func ValidateSSHKey(sshKey string, fldPath *field.Path) field.ErrorList {
 	allErrs := field.ErrorList{}
diff --git a/api/v1alpha4/azuremachine_webhook.go b/api/v1alpha4/azuremachine_webhook.go
index 5e7258fcc..473db4204 100644
--- a/api/v1alpha4/azuremachine_webhook.go
+++ b/api/v1alpha4/azuremachine_webhook.go
@@ -45,36 +45,12 @@ var _ webhook.Validator = &AzureMachine{}
 // ValidateCreate implements webhook.Validator so a webhook will be registered for the type.
 func (m *AzureMachine) ValidateCreate() error {
 	machinelog.Info("validate create", "name", m.Name)
-	var allErrs field.ErrorList
-
-	if errs := ValidateImage(m.Spec.Image, field.NewPath("image")); len(errs) > 0 {
-		allErrs = append(allErrs, errs...)
-	}
-
-	if errs := ValidateOSDisk(m.Spec.OSDisk, field.NewPath("osDisk")); len(errs) > 0 {
-		allErrs = append(allErrs, errs...)
-	}
-
-	if errs := ValidateSSHKey(m.Spec.SSHPublicKey, field.NewPath("sshPublicKey")); len(errs) > 0 {
-		allErrs = append(allErrs, errs...)
-	}
-
-	if errs := ValidateSystemAssignedIdentity(m.Spec.Identity, "", m.Spec.RoleAssignmentName, field.NewPath("roleAssignmentName")); len(errs) > 0 {
-		allErrs = append(allErrs, errs...)
-	}
-
-	if errs := ValidateUserAssignedIdentity(m.Spec.Identity, m.Spec.UserAssignedIdentities, field.NewPath("userAssignedIdentities")); len(errs) > 0 {
-		allErrs = append(allErrs, errs...)
-	}
 
-	if errs := ValidateDataDisks(m.Spec.DataDisks, field.NewPath("dataDisks")); len(errs) > 0 {
-		allErrs = append(allErrs, errs...)
+	if allErrs := ValidateAzureMachineSpec(m.Spec); len(allErrs) > 0 {
+		return apierrors.NewInvalid(GroupVersion.WithKind("AzureMachine").GroupKind(), m.Name, allErrs)
 	}
 
-	if len(allErrs) == 0 {
-		return nil
-	}
-	return apierrors.NewInvalid(GroupVersion.WithKind("AzureMachine").GroupKind(), m.Name, allErrs)
+	return nil
 }
 
 // ValidateUpdate implements webhook.Validator so a webhook will be registered for the type.
@@ -183,18 +159,5 @@ func (m *AzureMachine) ValidateDelete() error {
 // Default implements webhookutil.defaulter so a webhook will be registered for the type.
 func (m *AzureMachine) Default() {
 	machinelog.Info("default", "name", m.Name)
-
-	err := m.SetDefaultSSHPublicKey()
-	if err != nil {
-		machinelog.Error(err, "SetDefaultSshPublicKey failed")
-	}
-
-	err = m.SetDefaultCachingType()
-	if err != nil {
-		machinelog.Error(err, "SetDefaultCachingType failed")
-	}
-
-	m.SetDataDisksDefaults()
-
-	m.SetIdentityDefaults()
+	m.Spec.SetDefaults(machinelog)
 }
diff --git a/api/v1alpha4/azuremachinetemplate_webhook.go b/api/v1alpha4/azuremachinetemplate_webhook.go
index 1bbf295d2..708b5f504 100644
--- a/api/v1alpha4/azuremachinetemplate_webhook.go
+++ b/api/v1alpha4/azuremachinetemplate_webhook.go
@@ -31,7 +31,7 @@ import (
 const AzureMachineTemplateImmutableMsg = "AzureMachineTemplate spec.template.spec field is immutable. Please create new resource instead. ref doc: https://cluster-api.sigs.k8s.io/tasks/change-machine-template.html"
 
 // log is for logging in this package.
-var _ = logf.Log.WithName("azuremachinetemplate-resource")
+var machinetemplatelog = logf.Log.WithName("azuremachinetemplate-resource")
 
 // SetupWebhookWithManager sets up and registers the webhook with the manager.
 func (r *AzureMachineTemplate) SetupWebhookWithManager(mgr ctrl.Manager) error {
@@ -40,18 +40,26 @@ func (r *AzureMachineTemplate) SetupWebhookWithManager(mgr ctrl.Manager) error {
 		Complete()
 }
 
-// +kubebuilder:webhook:verbs=update,path=/validate-infrastructure-cluster-x-k8s-io-v1alpha4-azuremachinetemplate,mutating=false,failurePolicy=fail,matchPolicy=Equivalent,groups=infrastructure.cluster.x-k8s.io,resources=azuremachinetemplates,versions=v1alpha4,name=validation.azuremachinetemplate.infrastructure.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1beta1
+// +kubebuilder:webhook:verbs=create;update,path=/mutate-infrastructure-cluster-x-k8s-io-v1alpha4-azuremachinetemplate,mutating=true,failurePolicy=fail,matchPolicy=Equivalent,groups=infrastructure.cluster.x-k8s.io,resources=azuremachinetemplates,versions=v1alpha4,name=default.azuremachinetemplate.infrastructure.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1beta1
+// +kubebuilder:webhook:verbs=create;update,path=/validate-infrastructure-cluster-x-k8s-io-v1alpha4-azuremachinetemplate,mutating=false,failurePolicy=fail,matchPolicy=Equivalent,groups=infrastructure.cluster.x-k8s.io,resources=azuremachinetemplates,versions=v1alpha4,name=validation.azuremachinetemplate.infrastructure.cluster.x-k8s.io,sideEffects=None,admissionReviewVersions=v1beta1
 
+var _ webhook.Defaulter = &AzureMachineTemplate{}
 var _ webhook.Validator = &AzureMachineTemplate{}
 
 // ValidateCreate implements webhook.Validator so a webhook will be registered for the type.
 func (r *AzureMachineTemplate) ValidateCreate() error {
+	machinetemplatelog.Info("validate create", "name", r.Name)
+	spec := r.Spec.Template.Spec
+
+	if allErrs := ValidateAzureMachineSpec(spec); len(allErrs) > 0 {
+		return apierrors.NewInvalid(GroupVersion.WithKind("AzureMachineTemplate").GroupKind(), r.Name, allErrs)
+	}
 	return nil
 }
 
 // ValidateUpdate implements webhook.Validator so a webhook will be registered for the type.
 func (r *AzureMachineTemplate) ValidateUpdate(oldRaw runtime.Object) error {
-	clusterlog.Info("validate update", "name", r.Name)
+	machinetemplatelog.Info("validate update", "name", r.Name)
 	var allErrs field.ErrorList
 	old := oldRaw.(*AzureMachineTemplate)
 
@@ -71,3 +79,9 @@ func (r *AzureMachineTemplate) ValidateUpdate(oldRaw runtime.Object) error {
 func (r *AzureMachineTemplate) ValidateDelete() error {
 	return nil
 }
+
+// Default implements webhookutil.defaulter so a webhook will be registered for the type.
+func (r *AzureMachineTemplate) Default() {
+	machinetemplatelog.Info("default", "name", r.Name)
+	r.Spec.Template.Spec.SetDefaults(machinetemplatelog)
+}
diff --git a/config/webhook/manifests.yaml b/config/webhook/manifests.yaml
index 836c7070b..bb9ef40b7 100644
--- a/config/webhook/manifests.yaml
+++ b/config/webhook/manifests.yaml
@@ -48,6 +48,27 @@ webhooks:
     resources:
     - azuremachines
   sideEffects: None
+- admissionReviewVersions:
+  - v1beta1
+  clientConfig:
+    service:
+      name: webhook-service
+      namespace: system
+      path: /mutate-infrastructure-cluster-x-k8s-io-v1alpha4-azuremachinetemplate
+  failurePolicy: Fail
+  matchPolicy: Equivalent
+  name: default.azuremachinetemplate.infrastructure.cluster.x-k8s.io
+  rules:
+  - apiGroups:
+    - infrastructure.cluster.x-k8s.io
+    apiVersions:
+    - v1alpha4
+    operations:
+    - CREATE
+    - UPDATE
+    resources:
+    - azuremachinetemplates
+  sideEffects: None
 - admissionReviewVersions:
   - v1beta1
   clientConfig:
@@ -154,6 +175,7 @@ webhooks:
     apiVersions:
     - v1alpha4
     operations:
+    - CREATE
     - UPDATE
     resources:
     - azuremachinetemplates


Test patch:
diff --git a/api/v1alpha4/azuremachine_default_test.go b/api/v1alpha4/azuremachine_default_test.go
index dab074c0f..fd3a56f2f 100644
--- a/api/v1alpha4/azuremachine_default_test.go
+++ b/api/v1alpha4/azuremachine_default_test.go
@@ -27,7 +27,7 @@ import (
 	. "github.com/onsi/gomega"
 )
 
-func TestAzureMachine_SetDefaultSSHPublicKey(t *testing.T) {
+func TestAzureMachineSpec_SetDefaultSSHPublicKey(t *testing.T) {
 	g := NewWithT(t)
 
 	type test struct {
@@ -38,16 +38,16 @@ func TestAzureMachine_SetDefaultSSHPublicKey(t *testing.T) {
 	publicKeyExistTest := test{machine: createMachineWithSSHPublicKey(t, existingPublicKey)}
 	publicKeyNotExistTest := test{machine: createMachineWithSSHPublicKey(t, "")}
 
-	err := publicKeyExistTest.machine.SetDefaultSSHPublicKey()
+	err := publicKeyExistTest.machine.Spec.SetDefaultSSHPublicKey()
 	g.Expect(err).To(BeNil())
 	g.Expect(publicKeyExistTest.machine.Spec.SSHPublicKey).To(Equal(existingPublicKey))
 
-	err = publicKeyNotExistTest.machine.SetDefaultSSHPublicKey()
+	err = publicKeyNotExistTest.machine.Spec.SetDefaultSSHPublicKey()
 	g.Expect(err).To(BeNil())
 	g.Expect(publicKeyNotExistTest.machine.Spec.SSHPublicKey).To(Not(BeEmpty()))
 }
 
-func TestAzureMachine_SetIdentityDefaults(t *testing.T) {
+func TestAzureMachineSpec_SetIdentityDefaults(t *testing.T) {
 	g := NewWithT(t)
 
 	type test struct {
@@ -67,19 +67,19 @@ func TestAzureMachine_SetIdentityDefaults(t *testing.T) {
 		Identity: VMIdentityUserAssigned,
 	}}}
 
-	roleAssignmentExistTest.machine.SetIdentityDefaults()
+	roleAssignmentExistTest.machine.Spec.SetIdentityDefaults()
 	g.Expect(roleAssignmentExistTest.machine.Spec.RoleAssignmentName).To(Equal(existingRoleAssignmentName))
 
-	roleAssignmentEmptyTest.machine.SetIdentityDefaults()
+	roleAssignmentEmptyTest.machine.Spec.SetIdentityDefaults()
 	g.Expect(roleAssignmentEmptyTest.machine.Spec.RoleAssignmentName).To(Not(BeEmpty()))
 	_, err := uuid.Parse(roleAssignmentEmptyTest.machine.Spec.RoleAssignmentName)
 	g.Expect(err).To(Not(HaveOccurred()))
 
-	notSystemAssignedTest.machine.SetIdentityDefaults()
+	notSystemAssignedTest.machine.Spec.SetIdentityDefaults()
 	g.Expect(notSystemAssignedTest.machine.Spec.RoleAssignmentName).To(BeEmpty())
 }
 
-func TestAzureMachine_SetDataDisksDefaults(t *testing.T) {
+func TestAzureMachineSpec_SetDataDisksDefaults(t *testing.T) {
 	cases := []struct {
 		name   string
 		disks  []DataDisk
@@ -240,7 +240,7 @@ func TestAzureMachine_SetDataDisksDefaults(t *testing.T) {
 			t.Parallel()
 			machine := hardcodedAzureMachineWithSSHKey(generateSSHPublicKey(true))
 			machine.Spec.DataDisks = tc.disks
-			machine.SetDataDisksDefaults()
+			machine.Spec.SetDataDisksDefaults()
 			if !reflect.DeepEqual(machine.Spec.DataDisks, tc.output) {
 				expected, _ := json.MarshalIndent(tc.output, "", "\t")
 				actual, _ := json.MarshalIndent(machine.Spec.DataDisks, "", "\t")
diff --git a/api/v1alpha4/azuremachinetemplate_webhook_test.go b/api/v1alpha4/azuremachinetemplate_webhook_test.go
index 153d87b81..9279cc1a6 100644
--- a/api/v1alpha4/azuremachinetemplate_webhook_test.go
+++ b/api/v1alpha4/azuremachinetemplate_webhook_test.go
@@ -19,11 +19,125 @@ package v1alpha4
 import (
 	"testing"
 
+	"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2020-06-30/compute"
 	"github.com/Azure/go-autorest/autorest/to"
 	. "github.com/onsi/gomega"
 	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
+func TestAzureMachineTemplate_ValidateCreate(t *testing.T) {
+	g := NewWithT(t)
+
+	tests := []struct {
+		name            string
+		machineTemplate *AzureMachineTemplate
+		wantErr         bool
+	}{
+		{
+			name: "azuremachinetemplate with marketplane image - full",
+			machineTemplate: createAzureMachineTemplateFromMachine(
+				createMachineWithtMarketPlaceImage(t, "PUB1234", "OFFER1234", "SKU1234", "1.0.0"),
+			),
+			wantErr: false,
+		},
+		{
+			name: "azuremachinetemplate with marketplace image - missing publisher",
+			machineTemplate: createAzureMachineTemplateFromMachine(
+				createMachineWithtMarketPlaceImage(t, "", "OFFER1234", "SKU1234", "1.0.0"),
+			),
+			wantErr: true,
+		},
+		{
+			name: "azuremachinetemplate with shared gallery image - full",
+			machineTemplate: createAzureMachineTemplateFromMachine(
+				createMachineWithSharedImage(t, "SUB123", "RG123", "NAME123", "GALLERY1", "1.0.0"),
+			),
+			wantErr: false,
+		},
+		{
+			name: "azuremachinetemplate with marketplace image - missing subscription",
+			machineTemplate: createAzureMachineTemplateFromMachine(
+				createMachineWithSharedImage(t, "", "RG123", "NAME123", "GALLERY1", "1.0.0"),
+			),
+			wantErr: true,
+		},
+		{
+			name: "azuremachinetemplate with image by - with id",
+			machineTemplate: createAzureMachineTemplateFromMachine(
+				createMachineWithImageByID(t, "ID123"),
+			),
+			wantErr: false,
+		},
+		{
+			name: "azuremachinetemplate with image by - without id",
+			machineTemplate: createAzureMachineTemplateFromMachine(
+				createMachineWithImageByID(t, ""),
+			),
+			wantErr: true,
+		},
+		{
+			name: "azuremachinetemplate with valid SSHPublicKey",
+			machineTemplate: createAzureMachineTemplateFromMachine(
+				createMachineWithSSHPublicKey(t, validSSHPublicKey),
+			),
+			wantErr: false,
+		},
+		{
+			name: "azuremachinetemplate without SSHPublicKey",
+			machineTemplate: createAzureMachineTemplateFromMachine(
+				createMachineWithSSHPublicKey(t, ""),
+			),
+			wantErr: true,
+		},
+		{
+			name: "azuremachinetemplate with invalid SSHPublicKey",
+			machineTemplate: createAzureMachineTemplateFromMachine(
+				createMachineWithSSHPublicKey(t, "invalid ssh key"),
+			),
+			wantErr: true,
+		},
+		{
+			name: "azuremachinetemplate with list of user-assigned identities",
+			machineTemplate: createAzureMachineTemplateFromMachine(
+				createMachineWithUserAssignedIdentities(t, []UserAssignedIdentity{{ProviderID: "azure:///123"}, {ProviderID: "azure:///456"}}),
+			),
+			wantErr: false,
+		},
+		{
+			name: "azuremachinetemplate with empty list of user-assigned identities",
+			machineTemplate: createAzureMachineTemplateFromMachine(
+				createMachineWithUserAssignedIdentities(t, []UserAssignedIdentity{}),
+			),
+			wantErr: true,
+		},
+		{
+			name: "azuremachinetemplate with valid osDisk cache type",
+			machineTemplate: createAzureMachineTemplateFromMachine(
+				createMachineWithOsDiskCacheType(t, string(compute.PossibleCachingTypesValues()[1])),
+			),
+			wantErr: false,
+		},
+		{
+			name: "azuremachinetemplate with invalid osDisk cache type",
+			machineTemplate: createAzureMachineTemplateFromMachine(
+				createMachineWithOsDiskCacheType(t, "invalid_cache_type"),
+			),
+			wantErr: true,
+		},
+	}
+
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			err := test.machineTemplate.ValidateCreate()
+			if test.wantErr {
+				g.Expect(err).To(HaveOccurred())
+			} else {
+				g.Expect(err).NotTo(HaveOccurred())
+			}
+		})
+	}
+}
+
 func TestAzureMachineTemplate_ValidateUpdate(t *testing.T) {
 	g := NewWithT(t)
 	failureDomain := "domaintest"
@@ -126,3 +240,13 @@ func TestAzureMachineTemplate_ValidateUpdate(t *testing.T) {
 		})
 	}
 }
+
+func createAzureMachineTemplateFromMachine(machine *AzureMachine) *AzureMachineTemplate {
+	return &AzureMachineTemplate{
+		Spec: AzureMachineTemplateSpec{
+			Template: AzureMachineTemplateResource{
+				Spec: machine.Spec,
+			},
+		},
+	}
+}
diff --git a/templates/test/ci/cluster-template-prow-ci-version.yaml b/templates/test/ci/cluster-template-prow-ci-version.yaml
index c8ddb58f1..9556c2351 100644
--- a/templates/test/ci/cluster-template-prow-ci-version.yaml
+++ b/templates/test/ci/cluster-template-prow-ci-version.yaml
@@ -133,9 +133,9 @@ spec:
               DEBIAN_FRONTEND=noninteractive apt-get install -y $$CI_PACKAGE=$$PACKAGE_VERSION
             done
           else
-            CI_URL="gs://k8s-release-dev/ci-periodic/$$CI_VERSION/bin/linux/amd64"
+            CI_URL="gs://kubernetes-release-dev/ci-periodic/$$CI_VERSION/bin/linux/amd64"
             if ! $${GSUTIL} ls "$${CI_URL}" > /dev/null; then
-              CI_URL="gs://k8s-release-dev/ci/$$CI_VERSION/bin/linux/amd64"
+              CI_URL="gs://kubernetes-release-dev/ci/$$CI_VERSION/bin/linux/amd64"
             fi
             for CI_PACKAGE in "$${PACKAGES_TO_TEST[@]}"; do
               echo "* downloading binary: $$CI_URL/$$CI_PACKAGE"
@@ -150,7 +150,7 @@ spec:
             $${GSUTIL} cp "$$CI_URL/$$CI_CONTAINER.$$CONTAINER_EXT" "$$CI_DIR/$$CI_CONTAINER.$$CONTAINER_EXT"
             $${SUDO} ctr -n k8s.io images import "$$CI_DIR/$$CI_CONTAINER.$$CONTAINER_EXT" || echo "* ignoring expected 'ctr images import' result"
             $${SUDO} ctr -n k8s.io images tag k8s.gcr.io/$$CI_CONTAINER-amd64:"$${CI_VERSION//+/_}" k8s.gcr.io/$$CI_CONTAINER:"$${CI_VERSION//+/_}"
-            $${SUDO} ctr -n k8s.io images tag k8s.gcr.io/$$CI_CONTAINER-amd64:"$${CI_VERSION//+/_}" gcr.io/k8s-staging-ci-images/$$CI_CONTAINER:"$${CI_VERSION//+/_}"
+            $${SUDO} ctr -n k8s.io images tag k8s.gcr.io/$$CI_CONTAINER-amd64:"$${CI_VERSION//+/_}" gcr.io/kubernetes-ci-images/$$CI_CONTAINER:"$${CI_VERSION//+/_}"
           done
         fi
         echo "* checking binary versions"
@@ -321,9 +321,9 @@ spec:
                 DEBIAN_FRONTEND=noninteractive apt-get install -y $$CI_PACKAGE=$$PACKAGE_VERSION
               done
             else
-              CI_URL="gs://k8s-release-dev/ci-periodic/$$CI_VERSION/bin/linux/amd64"
+              CI_URL="gs://kubernetes-release-dev/ci-periodic/$$CI_VERSION/bin/linux/amd64"
               if ! $${GSUTIL} ls "$${CI_URL}" > /dev/null; then
-                CI_URL="gs://k8s-release-dev/ci/$$CI_VERSION/bin/linux/amd64"
+                CI_URL="gs://kubernetes-release-dev/ci/$$CI_VERSION/bin/linux/amd64"
               fi
               for CI_PACKAGE in "$${PACKAGES_TO_TEST[@]}"; do
                 echo "* downloading binary: $$CI_URL/$$CI_PACKAGE"
@@ -338,7 +338,7 @@ spec:
               $${GSUTIL} cp "$$CI_URL/$$CI_CONTAINER.$$CONTAINER_EXT" "$$CI_DIR/$$CI_CONTAINER.$$CONTAINER_EXT"
               $${SUDO} ctr -n k8s.io images import "$$CI_DIR/$$CI_CONTAINER.$$CONTAINER_EXT" || echo "* ignoring expected 'ctr images import' result"
               $${SUDO} ctr -n k8s.io images tag k8s.gcr.io/$$CI_CONTAINER-amd64:"$${CI_VERSION//+/_}" k8s.gcr.io/$$CI_CONTAINER:"$${CI_VERSION//+/_}"
-              $${SUDO} ctr -n k8s.io images tag k8s.gcr.io/$$CI_CONTAINER-amd64:"$${CI_VERSION//+/_}" gcr.io/k8s-staging-ci-images/$$CI_CONTAINER:"$${CI_VERSION//+/_}"
+              $${SUDO} ctr -n k8s.io images tag k8s.gcr.io/$$CI_CONTAINER-amd64:"$${CI_VERSION//+/_}" gcr.io/kubernetes-ci-images/$$CI_CONTAINER:"$${CI_VERSION//+/_}"
             done
           fi
           echo "* checking binary versions"
diff --git a/templates/test/ci/cluster-template-prow-machine-pool-ci-version.yaml b/templates/test/ci/cluster-template-prow-machine-pool-ci-version.yaml
index a5d60bbb1..9e2ed080d 100644
--- a/templates/test/ci/cluster-template-prow-machine-pool-ci-version.yaml
+++ b/templates/test/ci/cluster-template-prow-machine-pool-ci-version.yaml
@@ -137,9 +137,9 @@ spec:
               DEBIAN_FRONTEND=noninteractive apt-get install -y $$CI_PACKAGE=$$PACKAGE_VERSION
             done
           else
-            CI_URL="gs://k8s-release-dev/ci-periodic/$$CI_VERSION/bin/linux/amd64"
+            CI_URL="gs://kubernetes-release-dev/ci-periodic/$$CI_VERSION/bin/linux/amd64"
             if ! $${GSUTIL} ls "$${CI_URL}" > /dev/null; then
-              CI_URL="gs://k8s-release-dev/ci/$$CI_VERSION/bin/linux/amd64"
+              CI_URL="gs://kubernetes-release-dev/ci/$$CI_VERSION/bin/linux/amd64"
             fi
             for CI_PACKAGE in "$${PACKAGES_TO_TEST[@]}"; do
               echo "* downloading binary: $$CI_URL/$$CI_PACKAGE"
@@ -154,7 +154,7 @@ spec:
             $${GSUTIL} cp "$$CI_URL/$$CI_CONTAINER.$$CONTAINER_EXT" "$$CI_DIR/$$CI_CONTAINER.$$CONTAINER_EXT"
             $${SUDO} ctr -n k8s.io images import "$$CI_DIR/$$CI_CONTAINER.$$CONTAINER_EXT" || echo "* ignoring expected 'ctr images import' result"
             $${SUDO} ctr -n k8s.io images tag k8s.gcr.io/$$CI_CONTAINER-amd64:"$${CI_VERSION//+/_}" k8s.gcr.io/$$CI_CONTAINER:"$${CI_VERSION//+/_}"
-            $${SUDO} ctr -n k8s.io images tag k8s.gcr.io/$$CI_CONTAINER-amd64:"$${CI_VERSION//+/_}" gcr.io/k8s-staging-ci-images/$$CI_CONTAINER:"$${CI_VERSION//+/_}"
+            $${SUDO} ctr -n k8s.io images tag k8s.gcr.io/$$CI_CONTAINER-amd64:"$${CI_VERSION//+/_}" gcr.io/kubernetes-ci-images/$$CI_CONTAINER:"$${CI_VERSION//+/_}"
           done
         fi
         echo "* checking binary versions"
@@ -327,9 +327,9 @@ spec:
             DEBIAN_FRONTEND=noninteractive apt-get install -y $$CI_PACKAGE=$$PACKAGE_VERSION
           done
         else
-          CI_URL="gs://k8s-release-dev/ci-periodic/$$CI_VERSION/bin/linux/amd64"
+          CI_URL="gs://kubernetes-release-dev/ci-periodic/$$CI_VERSION/bin/linux/amd64"
           if ! $${GSUTIL} ls "$${CI_URL}" > /dev/null; then
-            CI_URL="gs://k8s-release-dev/ci/$$CI_VERSION/bin/linux/amd64"
+            CI_URL="gs://kubernetes-release-dev/ci/$$CI_VERSION/bin/linux/amd64"
           fi
           for CI_PACKAGE in "$${PACKAGES_TO_TEST[@]}"; do
             echo "* downloading binary: $$CI_URL/$$CI_PACKAGE"
@@ -344,7 +344,7 @@ spec:
           $${GSUTIL} cp "$$CI_URL/$$CI_CONTAINER.$$CONTAINER_EXT" "$$CI_DIR/$$CI_CONTAINER.$$CONTAINER_EXT"
           $${SUDO} ctr -n k8s.io images import "$$CI_DIR/$$CI_CONTAINER.$$CONTAINER_EXT" || echo "* ignoring expected 'ctr images import' result"
           $${SUDO} ctr -n k8s.io images tag k8s.gcr.io/$$CI_CONTAINER-amd64:"$${CI_VERSION//+/_}" k8s.gcr.io/$$CI_CONTAINER:"$${CI_VERSION//+/_}"
-          $${SUDO} ctr -n k8s.io images tag k8s.gcr.io/$$CI_CONTAINER-amd64:"$${CI_VERSION//+/_}" gcr.io/k8s-staging-ci-images/$$CI_CONTAINER:"$${CI_VERSION//+/_}"
+          $${SUDO} ctr -n k8s.io images tag k8s.gcr.io/$$CI_CONTAINER-amd64:"$${CI_VERSION//+/_}" gcr.io/kubernetes-ci-images/$$CI_CONTAINER:"$${CI_VERSION//+/_}"
         done
       fi
       echo "* checking binary versions"
diff --git a/templates/test/ci/patches/control-plane-ci-version.yaml b/templates/test/ci/patches/control-plane-ci-version.yaml
index 10840e071..3d1aca090 100644
--- a/templates/test/ci/patches/control-plane-ci-version.yaml
+++ b/templates/test/ci/patches/control-plane-ci-version.yaml
@@ -58,9 +58,9 @@ spec:
               DEBIAN_FRONTEND=noninteractive apt-get install -y $$CI_PACKAGE=$$PACKAGE_VERSION
             done
           else
-            CI_URL="gs://k8s-release-dev/ci-periodic/$$CI_VERSION/bin/linux/amd64"
+            CI_URL="gs://kubernetes-release-dev/ci-periodic/$$CI_VERSION/bin/linux/amd64"
             if ! $${GSUTIL} ls "$${CI_URL}" > /dev/null; then
-              CI_URL="gs://k8s-release-dev/ci/$$CI_VERSION/bin/linux/amd64"
+              CI_URL="gs://kubernetes-release-dev/ci/$$CI_VERSION/bin/linux/amd64"
             fi
             for CI_PACKAGE in "$${PACKAGES_TO_TEST[@]}"; do
               echo "* downloading binary: $$CI_URL/$$CI_PACKAGE"
@@ -75,7 +75,7 @@ spec:
             $${GSUTIL} cp "$$CI_URL/$$CI_CONTAINER.$$CONTAINER_EXT" "$$CI_DIR/$$CI_CONTAINER.$$CONTAINER_EXT"
             $${SUDO} ctr -n k8s.io images import "$$CI_DIR/$$CI_CONTAINER.$$CONTAINER_EXT" || echo "* ignoring expected 'ctr images import' result"
             $${SUDO} ctr -n k8s.io images tag k8s.gcr.io/$$CI_CONTAINER-amd64:"$${CI_VERSION//+/_}" k8s.gcr.io/$$CI_CONTAINER:"$${CI_VERSION//+/_}"
-            $${SUDO} ctr -n k8s.io images tag k8s.gcr.io/$$CI_CONTAINER-amd64:"$${CI_VERSION//+/_}" gcr.io/k8s-staging-ci-images/$$CI_CONTAINER:"$${CI_VERSION//+/_}"
+            $${SUDO} ctr -n k8s.io images tag k8s.gcr.io/$$CI_CONTAINER-amd64:"$${CI_VERSION//+/_}" gcr.io/kubernetes-ci-images/$$CI_CONTAINER:"$${CI_VERSION//+/_}"
           done
         fi
         echo "* checking binary versions"
diff --git a/templates/test/ci/prow-ci-version/patches/machine-deployment-ci-version.yaml b/templates/test/ci/prow-ci-version/patches/machine-deployment-ci-version.yaml
index 52ad190d7..3207df33c 100644
--- a/templates/test/ci/prow-ci-version/patches/machine-deployment-ci-version.yaml
+++ b/templates/test/ci/prow-ci-version/patches/machine-deployment-ci-version.yaml
@@ -56,9 +56,9 @@ spec:
                   DEBIAN_FRONTEND=noninteractive apt-get install -y $$CI_PACKAGE=$$PACKAGE_VERSION
                 done
               else
-                CI_URL="gs://k8s-release-dev/ci-periodic/$$CI_VERSION/bin/linux/amd64"
+                CI_URL="gs://kubernetes-release-dev/ci-periodic/$$CI_VERSION/bin/linux/amd64"
                 if ! $${GSUTIL} ls "$${CI_URL}" > /dev/null; then
-                  CI_URL="gs://k8s-release-dev/ci/$$CI_VERSION/bin/linux/amd64"
+                  CI_URL="gs://kubernetes-release-dev/ci/$$CI_VERSION/bin/linux/amd64"
                 fi
                 for CI_PACKAGE in "$${PACKAGES_TO_TEST[@]}"; do
                   echo "* downloading binary: $$CI_URL/$$CI_PACKAGE"
@@ -73,7 +73,7 @@ spec:
                 $${GSUTIL} cp "$$CI_URL/$$CI_CONTAINER.$$CONTAINER_EXT" "$$CI_DIR/$$CI_CONTAINER.$$CONTAINER_EXT"
                 $${SUDO} ctr -n k8s.io images import "$$CI_DIR/$$CI_CONTAINER.$$CONTAINER_EXT" || echo "* ignoring expected 'ctr images import' result"
                 $${SUDO} ctr -n k8s.io images tag k8s.gcr.io/$$CI_CONTAINER-amd64:"$${CI_VERSION//+/_}" k8s.gcr.io/$$CI_CONTAINER:"$${CI_VERSION//+/_}"
-                $${SUDO} ctr -n k8s.io images tag k8s.gcr.io/$$CI_CONTAINER-amd64:"$${CI_VERSION//+/_}" gcr.io/k8s-staging-ci-images/$$CI_CONTAINER:"$${CI_VERSION//+/_}"
+                $${SUDO} ctr -n k8s.io images tag k8s.gcr.io/$$CI_CONTAINER-amd64:"$${CI_VERSION//+/_}" gcr.io/kubernetes-ci-images/$$CI_CONTAINER:"$${CI_VERSION//+/_}"
               done
             fi
             echo "* checking binary versions"
diff --git a/templates/test/ci/prow-machine-pool-ci-version/patches/machine-pool-ci-version.yaml b/templates/test/ci/prow-machine-pool-ci-version/patches/machine-pool-ci-version.yaml
index 98f788230..59c92460b 100644
--- a/templates/test/ci/prow-machine-pool-ci-version/patches/machine-pool-ci-version.yaml
+++ b/templates/test/ci/prow-machine-pool-ci-version/patches/machine-pool-ci-version.yaml
@@ -54,9 +54,9 @@ spec:
               DEBIAN_FRONTEND=noninteractive apt-get install -y $$CI_PACKAGE=$$PACKAGE_VERSION
             done
           else
-            CI_URL="gs://k8s-release-dev/ci-periodic/$$CI_VERSION/bin/linux/amd64"
+            CI_URL="gs://kubernetes-release-dev/ci-periodic/$$CI_VERSION/bin/linux/amd64"
             if ! $${GSUTIL} ls "$${CI_URL}" > /dev/null; then
-              CI_URL="gs://k8s-release-dev/ci/$$CI_VERSION/bin/linux/amd64"
+              CI_URL="gs://kubernetes-release-dev/ci/$$CI_VERSION/bin/linux/amd64"
             fi
             for CI_PACKAGE in "$${PACKAGES_TO_TEST[@]}"; do
               echo "* downloading binary: $$CI_URL/$$CI_PACKAGE"
@@ -71,7 +71,7 @@ spec:
             $${GSUTIL} cp "$$CI_URL/$$CI_CONTAINER.$$CONTAINER_EXT" "$$CI_DIR/$$CI_CONTAINER.$$CONTAINER_EXT"
             $${SUDO} ctr -n k8s.io images import "$$CI_DIR/$$CI_CONTAINER.$$CONTAINER_EXT" || echo "* ignoring expected 'ctr images import' result"
             $${SUDO} ctr -n k8s.io images tag k8s.gcr.io/$$CI_CONTAINER-amd64:"$${CI_VERSION//+/_}" k8s.gcr.io/$$CI_CONTAINER:"$${CI_VERSION//+/_}"
-            $${SUDO} ctr -n k8s.io images tag k8s.gcr.io/$$CI_CONTAINER-amd64:"$${CI_VERSION//+/_}" gcr.io/k8s-staging-ci-images/$$CI_CONTAINER:"$${CI_VERSION//+/_}"
+            $${SUDO} ctr -n k8s.io images tag k8s.gcr.io/$$CI_CONTAINER-amd64:"$${CI_VERSION//+/_}" gcr.io/kubernetes-ci-images/$$CI_CONTAINER:"$${CI_VERSION//+/_}"
           done
         fi
         echo "* checking binary versions"