Migrate from Discovery Services
Focus
Focus
Prisma AIRS

Migrate from Discovery Services

Table of Contents

Migrate from Discovery Services

Learn about migrating from Discovery Services to a new infrastructure.
Where Can I Use This?What Do I Need?
  • Cloud assets discovery in Strata Cloud Manager
Palo Alto Networks is migrating Discovery services to a new infrastructure. This migration improves reliability and scalability. Depending on your cloud provider, some action may be required to restore full functionality after migration.
Azure Required Actions
  1. Obtain the new perimeter firewall public IPs from your Palo Alto Networks account team or the updated onboarding prerequisites page.
  2. Add the new IPs to your Azure storage account allow list (network rules).
  3. After migration completes, re-enable your Azure cloud account in the SCM portal.
  4. Verify flow log collection resumes.
Cloud IP Tag (CIPT) service continues to function during account disable/re-enable.
If the Azure Account is found in a disabled state, add the new perimeter firewall public IPs to your allow list, then re-enable the account in the portal.
If errors exist, consider re-downloading the TF package. Copy the previously available tfstate file along with the recently downloaded TF file and execute the TF.
If the tfstate file is not available, consider re-downloading the TF package and applying it. Look below for workarounds for any error you may face.
Common Azure Errors and Workarounds
ErrorResource TypeFix
A resource with the ID "..." already existsazuread_service_principalterraform import ... "/servicePrincipals/<objectId>"
RoleDefinitionWithSameNameExists (409)azurerm_role_definitionterraform import ... "<roleDefId>|<scope>"
RoleAssignmentExists (409)azurerm_role_assignmentterraform import 'aws_iam_role.cross_account_assume_role_orch[0]' '<customer_role_name>_orch'
aws_iam_role.cross_account_assume_role_route[0]<customer_role_name>_routeterraform import ... "<fullAssignmentResourceId>"
Azure Troubleshooting Commands
# Step 1: Get the Azure resource identifier az <command to find the ID> # Step 2: Import the resource into TF state terraform import <tf_resource_address> <azure_resource_id> # Step 3: After all imports, apply to push permission changes terraform apply # Lookup each SP's object ID by its app (client) ID az ad sp show --id 70208fa7-2a28-4e98-9f23-b96b95e46a51 --query id -o tsv # ent_app az ad sp show --id ec7c0f5c-b921-4178-a877-cb0e85a38a8c --query id -o tsv # ent_app_orch az ad sp show --id b74e38ad-b5f1-443a-8d72-731df6e1070e --query id -o tsv # ent_app_route az ad sp show --id 40b8763d-7fba-4fdd-b00b-8bc2a02423b7 --query id -o tsv # ent_app_ip_tag # Import — azuread provider v3.x requires the full /servicePrincipals/<objectId> path terraform import azuread_service_principal.ent_app "/servicePrincipals/<ent_app_object_id>" terraform import azuread_service_principal.ent_app_orch "/servicePrincipals/<ent_app_orch_object_id>" terraform import azuread_service_principal.ent_app_route "/servicePrincipals/<ent_app_route_object_id>" terraform import azuread_service_principal.ent_app_ip_tag "/servicePrincipals/<ent_app_ip_tag_object_id>" SUB_ID="<subscription_id>" # Lookup the role definition resource IDs az role definition list --name "panw_airs_discovery" \ --scope "/subscriptions/$SUB_ID" --query "[0].id" -o tsv az role definition list --name "panw_ip_harvesting" \ --scope "/subscriptions/$SUB_ID" --query "[0].id" -o tsv # Import — azurerm format: "<roleDefinitionResourceId>|<scope>" terraform import 'azurerm_role_definition.discovery_role[0]' \ "/subscriptions/$SUB_ID/providers/Microsoft.Authorization/roleDefinitions/<discovery_role_guid>|/subscriptions/$SUB_ID" terraform import 'azurerm_role_definition.ip_tag_role[0]' \ "/subscriptions/$SUB_ID/providers/Microsoft.Authorization/roleDefinitions/<ip_tag_role_guid>|/subscriptions/$SUB_ID" SUB_ID="<subscription_id>" # Lookup each assignment's full resource ID az role assignment list --role "panw_airs_discovery" \ --scope "/subscriptions/$SUB_ID" --query "[0].id" -o tsv az role assignment list --role "panw_ip_harvesting" \ --scope "/subscriptions/$SUB_ID" --query "[0].id" -o tsv # Import using the full ARM resource ID terraform import 'azurerm_role_assignment.role_assign_discovery[0]' \ "/subscriptions/$SUB_ID/providers/Microsoft.Authorization/roleAssignments/<discovery_assignment_guid>" terraform import 'azurerm_role_assignment.role_assign_ip_tag[0]' \ "/subscriptions/$SUB_ID/providers/Microsoft.Authorization/roleAssignments/<ip_tag_assignment_guid>"
AWS Required Actions (Public Clusters Only)
  1. Identify any public EKS or Kubernetes clusters enrolled in container workload discovery.
  2. Add the new perimeter firewall public IPs to the API server endpoint allow list for each public cluster.
  3. Verify container workload discovery resumes in the SCM portal.
AWS accounts are not disabled by this migration. CIPT is not affected.
If the AWS cloud account is found in disabled state, consider enabling the AWS account with one of the following two scenarios:
  1. Previously generated tfstate file is available. Download the latest TF package for the onboarded cloud account. Place the tfstate file along with all the Terraform files that we downloaded. Execute the TF and enable the cloud account.
Every EntityAlreadyExists error block contains two values. Extract them and compose the import command:
│ EntityAlreadyExists: Role with name <A: aws-role-name> already exists. │ with <B: terraform-resource-address>, terraform import '<B>' '<A>'
Run one import per error block, then plan and apply. The table below covers all four roles this TF package can create — only the ones that appear in your errors need to be imported:
Error "with" lineRole CreatedImport Command
aws_iam_role.cross_account_assume_role[0]<customer_role_name>terraform import 'aws_iam_role.cross_account_assume_role[0]' '<customer_role_name>'
aws_iam_role.cross_account_assume_role_ip_tag[0]<customer_role_name>_ip_tagterraform import 'aws_iam_role.cross_account_assume_role_ip_tag[0]' '<customer_role_name>_ip_tag'
aws_iam_role.cross_account_assume_role_orch[0]<customer_role_name>_orchterraform import 'aws_iam_role.cross_account_assume_role_orch[0]' '<customer_role_name>_orch'
aws_iam_role.cross_account_assume_role_route[0]<customer_role_name>_routeterraform import 'aws_iam_role.cross_account_assume_role_route[0]' '<customer_role_name>_route'
Example:
Error 1
│ │ Error: creating IAM Role (jsh-migr-test): operation error IAM: CreateRole, │ https response error StatusCode: 409, │ RequestID: e67cdb68-57b3-4328-8386-ef6f7812141a, │ EntityAlreadyExists: Role with name jsh-migr-test already exists. │ │ with aws_iam_role.cross_account_assume_role[0], │ on iam.tf line 80, in resource "aws_iam_role" "cross_account_assume_role": │ 80: resource "aws_iam_role" "cross_account_assume_role" { │
Fix:
terraform import 'aws_iam_role.cross_account_assume_role[0]' 'jsh-migr-test'
Error 2
│ │ Error: creating IAM Role (jsh-migr-test_ip_tag): operation error IAM: CreateRole, │ https response error StatusCode: 409, │ RequestID: 68e03add-cfd6-466f-abd1-3f1bb79d52f7, │ EntityAlreadyExists: Role with name jsh-migr-test_ip_tag already exists. │ │ with aws_iam_role.cross_account_assume_role_ip_tag[0], │ on iam.tf line 128, in resource "aws_iam_role" "cross_account_assume_role_ip_tag": │ 128: resource "aws_iam_role" "cross_account_assume_role_ip_tag" { │
Fix:
terraform import 'aws_iam_role.cross_account_assume_role_ip_tag[0]' 'jsh-migr-test_ip_tag'
GCP Required Actions
  1. After migration completes, your existing GCP cloud account will be disabled and cannot be re-enabled.
  2. Onboard a new GCP account following the standard GCP onboarding guide.
  3. Configure Cloud IP Tag (CIPT) service on the new GCP account.
  4. Verify CIPT is operating correctly.
  5. Delete the old (disabled) GCP account from the SCM portal.
CIPT on the old account will continue to function until you complete re-onboarding.
Expected Error/Resolution while re-applying the GCP cloud onboarding Terraform
  • Reapply/edit disabled account after onboarding (GCP)
  • You may encounter errors while trying to reapply terraform for the onboarded accounts, if .tfstate file is not provided; both should be imported using:
Error: Error creating Topic: googleapi: Error 409: Resource already exists in the project (resource=panw-discovery-<tsg_id>-asset-feed) Error: Custom project role projects/<project>/roles/panw_discovery_<tsgId> already exists and must be imported
Both need to be imported using:
  • terraform import 'google_project_iam_custom_role.iam_role_cloudasset-assets_list[0]' projects/<project>/roles/panw_discovery_<tsgId>
  • terraform import google_pubsub_topic.asset_feed_pub_sub_topic projects/<project>/topics/panw-discovery-<tsgId>-asset-feed
General loud IP Tag (CIPT) Updates
When migrating from the legacy SCM environment to the MSF consider the following:
  • Azure: CIPT continues to function even when the Azure account is disabled post-migration. After adding the new perimeter firewall IPs and re-enabling the account, CIPT resumes automatically. The CIPT enable-account call is ignored if CIPT is already active.
  • AWS: No impact. CIPT continues to function normally post-migration.
  • GCP: CIPT continues to function on the old (disabled) GCP account post-migration. To operate CIPT on the new MSF infrastructure, you must onboard a new GCP account, configure CIPT on it, and then delete the old account.

Delicensing Blackout

Delicensing is unavailable during the migration maintenance window. If you need to delicense a product or remove a tenant, complete that action before the maintenance window begins. Contact support if you have time-sensitive delicensing requirements.