:_mod-docs-content-type: PROCEDURE
[id="cco-ccoctl-upgrading_{context}"]
= Updating cloud provider resources with the Cloud Credential Operator utility

[role="_abstract"]
Update the cloud provider resources for your {product-title} cluster by using the CCO utility (`ccoctl`). The process for upgrading these resources is similar to creating the resources during installation.

[NOTE]
====
On AWS clusters, some `ccoctl` commands make AWS API calls to create or modify AWS resources. You can use the `--dry-run` flag to avoid making API calls. Using this flag creates JSON files on the local file system instead. You can review and modify the JSON files and then apply them with the AWS CLI tool using the `--cli-input-json` parameters.
====

.Prerequisites

* You have extracted the `CredentialsRequest` custom resources (CRs) from the {product-title} release image and ensured that a namespace that matches the text in the `spec.secretRef.namespace` field exists in the cluster.

* You have extracted and configured the `ccoctl` binary from the release image.

.Procedure

. Create the output directory if it does not already exist by running the following command:
+
[source,terminal]
----
$ mkdir -p <path_to_ccoctl_output_dir>
----

. Extract the bound service account signing key from the cluster and save it to the output directory by running the following command:
+
[source,terminal]
----
$ oc get secret bound-service-account-signing-key \
  -n openshift-kube-apiserver \
  -ojsonpath='{ .data.service-account\.pub }' | base64 \
  -d > <path_to_ccoctl_output_dir>/serviceaccount-signer.public
----

. Use the `ccoctl` tool to process all `CredentialsRequest` objects by running the command for your cloud provider. The following commands process `CredentialsRequest` objects:
+
.Amazon Web Services (AWS)
[source,terminal]
----
$ ccoctl aws create-all \
  --name=<name> \
  --region=<aws_region> \
  --credentials-requests-dir=<path_to_credentials_requests_directory> \
  --output-dir=<path_to_ccoctl_output_dir> \
  --public-key-file= \
  <path_to_ccoctl_output_dir>/serviceaccount-signer.public \
  --create-private-s3-bucket \
  --permissions-boundary-arn=<policy_arn>
----
+
where:
+
--
`<name>`:: Specifies the name used to tag any cloud resources that are created for tracking.
`<aws_region>`:: Specifies the AWS region in which cloud resources will be created.
`<path_to_credentials_requests_directory>`:: Specifies the directory containing the files for the component `CredentialsRequest` objects.
`<path_to_ccoctl_output_dir>`:: Specifies the path to the output directory. For `--public-key-file`, this directory contains the `serviceaccount-signer.public` file that you extracted from the cluster.
`<policy_arn>`:: Optional: Specifies the Amazon Resource Name (ARN) of the {aws-short} IAM policy to use as the permissions boundary for the IAM roles created by the `ccoctl` utility.
--
+
[NOTE]
====
By default, the `ccoctl` utility stores the OpenID Connect (OIDC) configuration files in a public S3 bucket and uses the S3 URL as the public OIDC endpoint. To store the OIDC configuration in a private S3 bucket that is accessed by the IAM identity provider through a public CloudFront distribution URL instead, use the `--create-private-s3-bucket` parameter. This is an optional parameter.
====
+
[NOTE]
====
To create the AWS resources individually, use the "Creating AWS resources individually" procedure in the "Installing a cluster on AWS with customizations" content. This option might be useful if you need to review the JSON files that the `ccoctl` tool creates before modifying AWS resources, or if the process the `ccoctl` tool uses to create AWS resources automatically does not meet the requirements of your organization.
====
+
.{gcp-first}
[source,terminal]
----
$ ccoctl gcp create-all \
  --name=<name> \
  --region=<gcp_region> \
  --project=<gcp_project_id> \
  --credentials-requests-dir=<path_to_credentials_requests_directory> \
  --output-dir=<path_to_ccoctl_output_dir> \
  --public-key-file=<path_to_ccoctl_output_dir>/serviceaccount-signer.public \
  --key-storage-method=<key_storage_method>
----
+
where:
+
--
`<name>`:: Specifies the user-defined name for all created {gcp-short} resources used for tracking.
`<gcp_region>`:: Specifies the {gcp-short} region in which cloud resources will be created.
`<gcp_project_id>`:: Specifies the {gcp-short} project ID in which cloud resources will be created.
`<path_to_credentials_requests_directory>`:: Specifies the directory containing the files of `CredentialsRequest` manifests to create {gcp-short} service accounts.
`<path_to_ccoctl_output_dir>`:: Specifies the path to the output directory. For `--public-key-file`, this directory contains the `serviceaccount-signer.public` file that you extracted from the cluster.
`<key_storage_method>`:: Optional: Specifies the method for storing OIDC JWK files. Accepted values are `public-bucket` and `pool-jwk-file`. The default value `public-bucket` creates a public GCS bucket to host the OIDC configuration and JWK files. The `pool-jwk-file` value attaches the JWK directly to the workload identity pool provider without creating a public bucket.
--
+
[NOTE]
====
If your cluster was previously configured with the `public-bucket` method and you switch to `pool-jwk-file`, the existing GCS bucket is no longer used. You can delete the old `<name>-oidc` bucket from your {gcp-short} project to avoid retaining an unnecessary public resource.
====
+
.{ibm-cloud-title}
[source,terminal]
----
$ ccoctl ibmcloud create-service-id \
  --credentials-requests-dir=<path_to_credential_requests_directory> \
  --name=<cluster_name> \
  --output-dir=<installation_directory> \
  --resource-group-name=<resource_group_name>
----
+
where:
+
--
`<path_to_credential_requests_directory>`:: Specifies the directory containing the files for the component `CredentialsRequest` objects.
`<cluster_name>`:: Specifies the name of the {product-title} cluster.
`<installation_directory>`:: Optional: Specifies the directory in which you want the `ccoctl` utility to create objects. By default, the utility creates objects in the directory in which the commands are run.
`<resource_group_name>`:: Optional: Specifies the name of the resource group used for scoping the access policies.
--
+
.{azure-first}
[source,terminal]
----
$ ccoctl azure create-managed-identities \
  --name <azure_infra_name> \
  --output-dir=<path_to_ccoctl_output_dir> \
  --region <azure_region> \
  --subscription-id <azure_subscription_id> \
  --credentials-requests-dir <path_to_directory_for_credentials_requests> \
  --issuer-url "${OIDC_ISSUER_URL}" \
  --dnszone-resource-group-name <azure_dns_zone_resourcegroup_name> \
  --installation-resource-group-name "${AZURE_INSTALL_RG}" \
  --preserve-existing-roles
----
+
where:
+
--
`<azure_infra_name>`:: Specifies the value of the `name` parameter used to create an Azure resource group.
To use an existing Azure resource group instead of creating a new one, specify the `--oidc-resource-group-name` argument with the existing group name as its value.
`<path_to_ccoctl_output_dir>`:: Specifies the path to the output directory.
`<azure_region>`:: Specifies the region of the existing cluster.
`<azure_subscription_id>`:: Specifies the subscription ID of the existing cluster.
`<path_to_directory_for_credentials_requests>`:: Specifies the directory containing the files for the component `CredentialsRequest` objects.
`"${OIDC_ISSUER_URL}"`:: Specifies the OIDC issuer URL from the existing cluster.
You can obtain this value by running the following command:
+
[source,terminal]
----
$ oc get authentication cluster \
  -o jsonpath \
  --template='{ .spec.serviceAccountIssuer }'
----
`<azure_dns_zone_resourcegroup_name>`:: Specifies the name of the resource group that contains the DNS zone.
`"${AZURE_INSTALL_RG}"`:: Specifies the {azure-short} resource group name.
You can obtain this value by running the following command:
+
[source,terminal]
----
$ oc get infrastructure cluster \
  -o jsonpath \
  --template '{ .status.platformStatus.azure.resourceGroupName }'
----

[NOTE]
====
Specifying the flag `ccoctl.azure.create-managed-identities.preserve-existing-roles` ensures that any custom role assignments you define on managed identities are not removed during {product-title} updates. This flag is optional.
====
--
+
.Nutanix
[source,terminal]
----
$ ccoctl nutanix create-shared-secrets \
  --credentials-requests-dir=<path_to_credentials_requests_directory> \
  --output-dir=<ccoctl_output_dir> \
  --credentials-source-filepath=<path_to_credentials_file>
----
+
where:
+
--
`<path_to_credentials_requests_directory>`:: Specifies the path to the directory that contains the files for the component `CredentialsRequests` objects.
`<ccoctl_output_dir>`:: Optional: Specifies the directory in which you want the `ccoctl` utility to create objects. By default, the utility creates objects in the directory in which the commands are run.
`<path_to_credentials_file>`:: Optional: Specifies the directory that contains the credentials data YAML file. By default, `ccoctl` expects this file to be in `<home_directory>/.nutanix/credentials`.
--
+
For each `CredentialsRequest` object, `ccoctl` creates the required provider resources and a permissions policy as defined in each `CredentialsRequest` object from the {product-title} release image.

. Apply the secrets to your cluster by running the following command:
+
[source,terminal]
----
$ ls <path_to_ccoctl_output_dir>/manifests/*-credentials.yaml | xargs -I{} oc apply -f {}
----

.Verification

You can verify that the required provider resources and permissions policies are created by querying the cloud provider. For more information, refer to your cloud provider documentation on listing roles or service accounts.

.Next steps

* Update the `upgradeable-to` annotation to indicate that the cluster is ready to upgrade.
