Managing Enterprise Storage with Pure Storage Fusion in PowerShell - Building Storage Tiers
In modern IT environments, not all workloads require the same level of storage performance, protection, or cost. Some applications need high performance with aggressive data protection, while others are perfectly fine with lower performance in exchange for cost savings. This tiered approach to storage service delivery is fundamental to efficient infrastructure management.
In my previous post on Fusion, I took an application-centric approach, showing how to deploy SQL Servers using Fusion. Let’s switch gears now and learn how to define a storage service catalog. In this post, I’ll demonstrate how to build a complete storage service catalog using Pure Storage Fusion Presets, offering Bronze, Silver, and Gold tiers with optional replication. We’ll see how to leverage different array types (FlashArray //X and FlashArray //C) to optimize both performance and cost across your fleet.
You can find the source code for this blog post here
Understanding Storage Tiers
Before diving into the implementation, let’s define what each tier represents in our service catalog:
- Bronze: Cost-optimized storage on FlashArray //C arrays with basic snapshot protection
- Silver: Balanced performance on FlashArray //X arrays with enhanced snapshot retention
- Gold: Premium performance with aggressive snapshot and replication policies
Note: The storage tiers here are examples, not best practices. Define your storage tiers to meet your business and technical requirements.
Each tier can be deployed with or without replication, below we’ll define three tiers. Summarized in this chart.
Tier | Array Type | IOPS | Bandwidth | Snapshots | Replication | Use Cases |
---|---|---|---|---|---|---|
Bronze | //C | 10K | 200 MB/s | 6hr/7d | Optional | Dev/Test |
Silver | //X | 50K | 1 GB/s | 2hr/14d | 2 hour RPO | Production |
Gold | //X | 1M | 10 GB/s | 30min/30d | 15 min RPO | Critical |
Setting Up Fleet Connections
First, let’s connect to our primary array and and our secondary array and examine our fleet topology:
# Connect to primary array (FlashArray //X)
$PrimaryArrayName = 'sn1-x90r2-f06-27.puretec.purestorage.com'
$SecondaryArrayName = 'sn1-c60-e12-16.puretec.purestorage.com'
$Credential = Import-CliXml -Path "$HOME\FA_Cred.xml"
$PrimaryArray = Connect-Pfa2Array –EndPoint $PrimaryArrayName -Credential $Credential -IgnoreCertificateError
Now let’s verify our fleet membership and identify available arrays:
# Retrieve all fleet members visible from the primary array
# Excluding FlashBlade (sn1-s200-c09-33) and sn1-c60-e12-16 which is a FlashArray //C to focus on FlashArray //X systems
$PrimaryFleetInfo = Get-Pfa2FleetMember -Array $PrimaryArray -Filter "Member.Name!='sn1-s200-c09-33' and Member.Name!='sn1-c60-e12-16'"
Write-Output "`nFleet Members from Primary Array perspective:"
$PrimaryFleetInfo.Member.Name
Fleet Members from the Primary Array perspective:
sn1-x90r2-f06-27
sn1-x90r2-f06-33
This gives us a view of our FlashArray //X systems that will host our Silver and Gold tier workloads.
Understanding Replication Targets
For workloads requiring replication, we need to configure the secondary array as a replication target. Let’s verify our replication setup. In the code below, we confirm that each of our FlashArray //X’s has an async-replication connection to the FlashArray //C in our lab. This is our snapshot target.
# Get the remote array object needed for configuring replication targets
# Verify if a replication connection already exists between the arrays
# This checks for async-replication type connections specifically
Write-Output "`nChecking for existing replication connections to $($SecondaryArrayName.Split('.')[0])..."
# Retrieve the remote array object needed for configuring replication targets
# CurrentFleetOnly ensures we only get arrays within our managed fleet
$remoteArray = Get-Pfa2RemoteArray -Array $PrimaryArray -CurrentFleetOnly $true -Name $SecondaryArrayName.Split('.')[0]
$remoteArray.Name
Get-Pfa2ArrayConnection -Array $PrimaryArray `
-ContextNames $PrimaryFleetInfo.Member.Name `
-Filter "Remote.Name='$($remoteArray.Name)' and Type='async-replication' and Status='Connected'"
Id : f269a914-00c5-408f-b6ba-a3c4048cdbfd
Name : sn1-c60-e12-16
Context : @{Id='081f096d-1c16-42a6-9855-92678d705a1c'; Name='sn1-x90r2-f06-27'}
Encryption : unencrypted
EncryptionMode :
ManagementAddress : sn1-c60-e12-16.puretec.purestorage.com
Os : Purity//FA
Remote : @{Id='f269a914-00c5-408f-b6ba-a3c4048cdbfd'; Name='sn1-c60-e12-16'; ResourceType='remote-arrays'}
ReplicationAddresses : {10.21.245.107, 10.21.245.193}
ReplicationTransport : ip
Status : connected
Throttle :
Type : async-replication
_Version : 6.8.7
Id : f269a914-00c5-408f-b6ba-a3c4048cdbfd
Name : sn1-c60-e12-16
Context : @{Id='ac5fc11f-8b3b-49a0-8261-43baf50b281b'; Name='sn1-x90r2-f06-33'}
Encryption : unencrypted
EncryptionMode :
ManagementAddress : sn1-c60-e12-16.puretec.purestorage.com
Os : Purity//FA
Remote : @{Id='f269a914-00c5-408f-b6ba-a3c4048cdbfd'; Name='sn1-c60-e12-16'; ResourceType='remote-arrays'}
ReplicationAddresses : {10.21.245.107, 10.21.245.193}
ReplicationTransport : ip
Status : connected
Throttle :
Type : async-replication
_Version : 6.8.7
Due to a current Type mismatch in the PowerShell module, we need to construct the replication targets parameter as a nested list. We will be using this code in the preset creation below. I’ll update this post with the fixed example once the PowerShell module is updated.
# Build the replication targets structure
$ReplicationTargets = [System.Collections.Generic.List[System.Collections.Generic.List[string]]]::new()
$inner = [System.Collections.Generic.List[string]]::new()
$inner.Add("")
$inner.Add($remoteArray.Name)
$inner.Add("remote-arrays")
$ReplicationTargets.Add($inner)
Bronze Tier: Cost-Optimized Storage
The Bronze tier targets FlashArray //C arrays, providing cost-effective capacity with local data protection.
Key aspects of the Bronze tier:
- Storage Class:
flasharray-c
ensures placement on cost-optimized C-series arrays - Performance: Limited to 10,000 IOPS and 200 MB/s bandwidth
- Protection: Snapshots every 6 hours, retained for 7 days
- Use Cases: Development environments, test systems, archival data
Here’s the preset definition:
$BronzePresetNoRepl = @{
Array = $PrimaryArray
ContextNames = 'fsa-lab-fleet1'
Name = "Compute-Bronze-NoRepl"
Description = "Bronze tier compute workload without replication"
WorkloadType = "Custom"
# QoS Configuration - Conservative limits
QosConfigurationsName = @("Bronze-QoS")
QosConfigurationsIopsLimit = @("10000")
QosConfigurationsBandwidthLimit = @((200MB).ToString()) # 200 MB/s
# Placement Configuration - Target C-series arrays for cost optimization
PlacementConfigurationsName = @("Bronze-Placement")
PlacementConfigurationsStorageClassName = @("flasharray-c")
PlacementConfigurationsStorageClassResourceType = @("storage-classes")
PlacementConfigurationsQosConfigurations = @(@("Bronze-QoS"))
# Volume Configuration
VolumeConfigurationsName = @("Bronze-Vol")
VolumeConfigurationsCount = @("1")
VolumeConfigurationsPlacementConfigurations = @(@("Bronze-Placement"))
VolumeConfigurationsProvisionedSize = @(500GB)
# Snapshot Configuration - Basic protection
SnapshotConfigurationsName = @("Bronze-Snapshots")
SnapshotConfigurationsRulesEvery = @(([TimeSpan]::FromHours(6).TotalMilliseconds).ToString())
SnapshotConfigurationsRulesKeepFor = @(([TimeSpan]::FromDays(7).TotalMilliseconds).ToString())
VolumeConfigurationsSnapshotConfigurations = @(@("Bronze-Snapshots"))
# Workload Tags
WorkloadTagsKey = @("tier", "replication", "service-level")
WorkloadTagsValue = @("bronze", "false", "standard")
}
New-Pfa2PresetWorkload @BronzePresetNoRepl
Silver Tier: Balanced Performance
The Silver tier provides enhanced performance on FlashArray //X arrays, suitable for production workloads:
Silver tier characteristics:
- Storage Class:
flasharray-x
for balanced performance - Performance: 50,000 IOPS and 1 GB/s bandwidth
- Protection: 2-hour snapshots and replication with 14-day retention
- RPO: 2-hour recovery point objective
- Use Cases: Production databases, application servers, important file shares
# Silver Tier - With Replication
$SilverPresetWithRepl = @{
Array = $PrimaryArray
ContextNames = 'fsa-lab-fleet1'
Name = "Compute-Silver-WithRepl"
Description = "Silver tier compute workload with bi-hourly replication"
WorkloadType = "Custom"
# QoS Configuration - Balanced performance
QosConfigurationsName = @("Silver-QoS")
QosConfigurationsIopsLimit = @("50000")
QosConfigurationsBandwidthLimit = @((1GB).ToString())
# Placement Configuration - Target X-series for performance
PlacementConfigurationsName = @("Silver-Placement")
PlacementConfigurationsStorageClassName = @("flasharray-x")
PlacementConfigurationsStorageClassResourceType = @("storage-classes")
PlacementConfigurationsQosConfigurations = @(@("Silver-QoS"))
# Volume Configuration
VolumeConfigurationsName = @("Silver-Vol")
VolumeConfigurationsCount = @("1")
VolumeConfigurationsPlacementConfigurations = @(@("Silver-Placement"))
VolumeConfigurationsProvisionedSize = @(1TB)
# Snapshot Configuration
SnapshotConfigurationsName = @("Silver-Snapshots")
SnapshotConfigurationsRulesEvery = @(([TimeSpan]::FromHours(2).TotalMilliseconds).ToString())
SnapshotConfigurationsRulesKeepFor = @(([TimeSpan]::FromDays(14).TotalMilliseconds).ToString())
# Replication Configuration
PeriodicReplicationConfigurationsRemoteTargets = $ReplicationTargets
PeriodicReplicationConfigurationsName = @("Silver-Replication")
PeriodicReplicationConfigurationsRulesEvery = @(([TimeSpan]::FromHours(2).TotalMilliseconds).ToString())
PeriodicReplicationConfigurationsRulesKeepFor = @(([TimeSpan]::FromDays(14).TotalMilliseconds).ToString())
VolumeConfigurationsPeriodicReplicationConfigurations = @(@("Silver-Replication"))
VolumeConfigurationsSnapshotConfigurations = @(@("Silver-Snapshots"))
# Workload Tags
WorkloadTagsKey = @("tier", "replication", "service-level", "rpo")
WorkloadTagsValue = @("silver", "true", "enhanced", "2-hours")
}
New-Pfa2PresetWorkload @SilverPresetWithRepl
Gold Tier: Premium Performance
The Gold tier delivers maximum performance with aggressive data protection:
Gold tier highlights:
- Performance: Near-unlimited (1M IOPS, 10 GB/s)
- Protection: 30-minute snapshots with 30-day retention
- RPO: 15-minute recovery point objective
- Priority: Tagged as critical for operational awareness
- Use Cases: Mission-critical databases, real-time analytics, high-frequency trading systems
# Gold Tier - With Replication
$GoldPresetWithRepl = @{
Array = $PrimaryArray
ContextNames = 'fsa-lab-fleet1'
Name = "Compute-Gold-WithRepl"
Description = "Gold tier compute workload with aggressive replication"
WorkloadType = "Custom"
# QoS Configuration - Maximum performance
QosConfigurationsName = @("Gold-QoS")
QosConfigurationsIopsLimit = @("1000000") # 1M IOPS
QosConfigurationsBandwidthLimit = @((10GB).ToString()) # 10 GB/s
# Placement Configuration
PlacementConfigurationsName = @("Gold-Placement")
PlacementConfigurationsStorageClassName = @("flasharray-x")
PlacementConfigurationsStorageClassResourceType = @("storage-classes")
PlacementConfigurationsQosConfigurations = @(@("Gold-QoS"))
# Volume Configuration
VolumeConfigurationsName = @("Gold-Vol")
VolumeConfigurationsCount = @("1")
VolumeConfigurationsPlacementConfigurations = @(@("Gold-Placement"))
VolumeConfigurationsProvisionedSize = @(2TB)
# Snapshot Configuration
SnapshotConfigurationsName = @("Gold-Snapshots")
SnapshotConfigurationsRulesEvery = @(([TimeSpan]::FromMinutes(30).TotalMilliseconds).ToString())
SnapshotConfigurationsRulesKeepFor = @(([TimeSpan]::FromDays(30).TotalMilliseconds).ToString())
# Replication Configuration
PeriodicReplicationConfigurationsName = @("Gold-Replication")
PeriodicReplicationConfigurationsRulesEvery = @(([TimeSpan]::FromMinutes(15).TotalMilliseconds).ToString())
PeriodicReplicationConfigurationsRulesKeepFor = @(([TimeSpan]::FromDays(30).TotalMilliseconds).ToString())
PeriodicReplicationConfigurationsRemoteTargets = $ReplicationTargets
VolumeConfigurationsPeriodicReplicationConfigurations = @(@("Gold-Replication"))
VolumeConfigurationsSnapshotConfigurations = @(@("Gold-Snapshots"))
# Workload Tags
WorkloadTagsKey = @("tier", "replication", "service-level", "rpo", "priority")
WorkloadTagsValue = @("gold", "true", "premium", "15-minutes", "critical")
}
New-Pfa2PresetWorkload @GoldPresetWithRepl
Verifying Preset Creation
With our presets created, you can use the Get-Pfa2PresetWorkload
cmdlet with a fleet-wide context of -ContextNames "fsa-lab-fleet1"
to get a listing of all of the created presets.
# List all compute tier presets
Write-Output "`nCreated Storage Tier Presets:"
Get-Pfa2PresetWorkload -Array $PrimaryArray -ContextNames "fsa-lab-fleet1" |
Select-Object Name, Description | Format-Table -AutoSize
Name Description
---- -----------
Compute-Gold-WithRepl Gold tier compute workload with aggressive replication
Compute-Silver-WithRepl Silver tier compute workload with bi-hourly replication
Compute-Bronze-NoRepl Bronze tier compute workload without replication
Deploying Workloads from Presets
With our service catalog defined, let’s deploy some workloads. Let’s deploy a Gold tier database workload on our X90 array (because it’s always databases ;):
# Get available fleet members for workload placement, excluding the FlashBlade
$FleetMembers = Get-Pfa2FleetMember -Array $PrimaryArray -Filter "Member.Name!='sn1-s200-c09-33'"
Write-Output "`nCreating Gold tier workload..."
$GoldWorkload = @{
Array = $PrimaryArray
ContextNames = ($FleetMembers.Member.Name | Where-Object { $_ -eq 'sn1-x90r2-f06-33' })
Name = "Database-Prod-01"
PresetNames = @("fsa-lab-fleet1:Compute-Gold-WithRepl")
}
New-Pfa2Workload @GoldWorkload
Creating Gold tier workload...
Id : 10652a0c-796f-4782-9819-08c987520be9
Name : Database-Prod-01
Context : @{Id='ac5fc11f-8b3b-49a0-8261-43baf50b281b'; Name='sn1-x90r2-f06-33'}
Created : 9/4/2025 5:59:13 PM
Destroyed : False
Preset : @{Id='5cc8dc80-4528-43ad-b165-88edf314f4c9'; Name='fsa-lab-fleet1:Compute-Gold-WithRepl'; Revision=1}
Status : ready
StatusDetails : {}
TimeRemaining :
Dynamic Volume Addition
One of the best features of Fusion workloads is the ability to add volumes dynamically while maintaining all preset configurations. This has been a troublesome issue for DBAs and storage administrators, as volumes are often added to a host but not added to a Protection Group, which can leave snapshots of databases at risk, by missing the newly added volume in the Protection Group snapshot. Fusion presets prevent this from happening. First, we find the array our workload is running on using Get-Pfa2Workload
, then we add the new volume with New-Pfa2Volume
. We need to specify the name of the workload with the -WorkloadName
parameter, which is the name of the workload we just deployed, Database-Prod-01
, and also the workload configuration using -WorkloadConfiguration
and a value of Gold-Vol
. This will apply our preset policy to the new volume attached to our workload.
$goldContext = (Get-Pfa2Workload -Array $PrimaryArray -ContextNames $FleetMembers.Member.Name -Name "Database-Prod-01").Context.Name
# Add new volume, notice we don't have to give it a name...all preset configurations will be applied to this volume using the workload configuration.
New-Pfa2Volume -Array $PrimaryArray `
-ContextNames $goldContext `
-Provisioned 100GB `
-WorkloadName "Database-Prod-01" `
-WorkloadConfiguration 'Gold-Vol'
Adding volumes to Gold workload (Database-Prod-01)...
Id : 6436298b-ea11-f6ea-b6d1-d5f88b849209
Name : vg-10652a0c-Gold-QoS-vrbmj/vol-10652a0c-Gold-Vol-0001-fk82f
ConnectionCount :
Created : 9/4/2025 6:00:36 PM
Destroyed : False
HostEncryptionKeyStatus : none
PriorityAdjustment : @{PriorityAdjustmentOperator='+'; PriorityAdjustmentValue=0}
Provisioned : 107374182400
Qos :
Serial : AC5FC11F8B3B49A002879B57
Space :
TimeRemaining :
Context : @{Id='ac5fc11f-8b3b-49a0-8261-43baf50b281b'; Name='sn1-x90r2-f06-33'}
Pod :
Priority : 0
PromotionStatus : promoted
ProtocolEndpoint :
RequestedPromotionState : promoted
Source :
Subtype : regular
VolumeGroup : @{Id='c0174ce6-fccb-c143-f99e-f8835939cffa'; Name='vg-10652a0c-Gold-QoS-vrbmj'}
Workload : @{Id='10652a0c-796f-4782-9819-08c987520be9'; Name='Database-Prod-01'; ResourceType='workloads'; _Configuration='Gold-Vol'}
The new volume automatically inherits:
- QoS settings from the Volume Group
- Snapshot policy from the Protection Group
- Tags and metadata from the workload
Verifying Workload Resources
Let’s examine the volumes that are created as part of our Gold workload deployment, in the output below you’ll see the volume from our initial workload deployment vol-10652a0c-Gold-Vol-0000-lf2sr
and the volume added after the deployment vol-10652a0c-Gold-Vol-0001-fk82f
:
Get-Pfa2Volume -Array $PrimaryArray -ContextNames $goldContext -Filter "workload.name='Database-Prod-01'" | Format-Table -AutoSize
Id Name ConnectionCount Created Destroyed HostEncryptionKeyStatus PriorityAdjustment Provisioned Qos Serial
-- ---- --------------- ------- --------- ----------------------- ------------------ ----------- --- ------
2242c922-ee4f-a6d8-26a6-ec87f833776d vg-10652a0c-Gold-QoS-vrbmj/vol-10652a0c-Gold-Vol-0000-lf2sr 0 9/4/2025 5:59:14 PM False none @{PriorityAdjustmentOperator='+'; PriorityAdjustmentValue=0} 2199023255552 AC5FC11F8B3B49A002879B2E
6436298b-ea11-f6ea-b6d1-d5f88b849209 vg-10652a0c-Gold-QoS-vrbmj/vol-10652a0c-Gold-Vol-0001-fk82f 0 9/4/2025 6:00:36 PM False none @{PriorityAdjustmentOperator='+'; PriorityAdjustmentValue=0} 107374182400 AC5FC11F8B3B49A002879B57
Next, let’s verify that these volumes are correctly configured with snapshot protection by checking their Protection Group membership. Here, you can see the local Protection Group associated with our deployed workload is named pg-10652a0c-Gold-Snapshots-dp9pq
and also the remote Protection Group that our snapshots are being replicated to our FlashArray //C with which is pg-10652a0c-Gold-Replication-kdzrt
$PGNames = Get-Pfa2ProtectionGroup -Array $PrimaryArray -ContextNames $FleetMembers.Member.Name -Filter "workload.name='Database-Prod-01'"
$PGNames | Format-Table -AutoSize
Name Id Context Workload Destroyed EradicationConfig HostCount HostGroupCount
---- -- ------- -------- --------- ----------------- --------- --------------
pg-10652a0c-Gold-Replication-kdzrt 80a5a2a9-d28e-cb5f-9243-b0644020130d @{Id='ac5fc11f-8b3b-49a0-8261-43baf50b281b'; Name='sn1-x90r2-f06-33'} @{Id='10652a0c-796f-4782-9819-08c987520be9'; Name='Database-Prod-01'; ResourceType='workloads'; _Configuration='Gold-Replication'} False @{ManualEradication='enabled'} 0 0
pg-10652a0c-Gold-Snapshots-dp9pq 69872897-c7c7-3666-fad6-cf828e2c7fb4 @{Id='ac5fc11f-8b3b-49a0-8261-43baf50b281b'; Name='sn1-x90r2-f06-33'} @{Id='10652a0c-796f-4782-9819-08c987520be9'; Name='Database-Prod-01'; ResourceType='workloads'; _Configuration='Gold-Snapshots'} False @{ManualEradication='enabled'} 0 0
Using Get-Pfa2ProtectionGroupVolume
, you get a listing of volumes in a Protection Group. Here is the listing of the volumes in our workload’s Protection Group. You can see that the newly added volume named vol-10652a0c-Gold-Vol-0000-lf2sr
is automatically added to the local and remote Protection Groups.
Get-Pfa2ProtectionGroupVolume -Array $PrimaryArray -ContextNames $goldContext -GroupName $PGNames.Name | Format-Table -AutoSize
Context Group Member
------- ----- ------
@{Id='ac5fc11f-8b3b-49a0-8261-43baf50b281b'; Name='sn1-x90r2-f06-33'} @{Id='80a5a2a9-d28e-cb5f-9243-b0644020130d'; Name='pg-10652a0c-Gold-Replication-kdzrt'} @{Id='2242c922-ee4f-a6d8-26a6-ec87f833776d'; Name='vg-10652a0c-Gold-QoS-vrbmj/vol-10652a0c-Gold-Vol-0000-lf2sr'; Destroyed=False}
@{Id='ac5fc11f-8b3b-49a0-8261-43baf50b281b'; Name='sn1-x90r2-f06-33'} @{Id='80a5a2a9-d28e-cb5f-9243-b0644020130d'; Name='pg-10652a0c-Gold-Replication-kdzrt'} @{Id='6436298b-ea11-f6ea-b6d1-d5f88b849209'; Name='vg-10652a0c-Gold-QoS-vrbmj/vol-10652a0c-Gold-Vol-0001-fk82f'; Destroyed=False}
@{Id='ac5fc11f-8b3b-49a0-8261-43baf50b281b'; Name='sn1-x90r2-f06-33'} @{Id='69872897-c7c7-3666-fad6-cf828e2c7fb4'; Name='pg-10652a0c-Gold-Snapshots-dp9pq'} @{Id='2242c922-ee4f-a6d8-26a6-ec87f833776d'; Name='vg-10652a0c-Gold-QoS-vrbmj/vol-10652a0c-Gold-Vol-0000-lf2sr'; Destroyed=False}
@{Id='ac5fc11f-8b3b-49a0-8261-43baf50b281b'; Name='sn1-x90r2-f06-33'} @{Id='69872897-c7c7-3666-fad6-cf828e2c7fb4'; Name='pg-10652a0c-Gold-Snapshots-dp9pq'} @{Id='6436298b-ea11-f6ea-b6d1-d5f88b849209'; Name='vg-10652a0c-Gold-QoS-vrbmj/vol-10652a0c-Gold-Vol-0001-fk82f'; Destroyed=False}
Finally, let’s inspect the Volume Group details to verify our QoS settings are correctly applied we can do this by finding our Volume Group for the workload using Get-Pfa2VolumeGroup
to get the Volume Group and then use Get-Pfa2VolumeGroupVolume
to list the volumes in our Volume Group and in the output below you can see the newly added volumevol-10652a0c-Gold-Vol-0001-fk82f
is automatically added to the Volume Group. Therefore, it will apply our QoS policy.
# The new volume is also added to the Volume Group, which means the QoS policy will apply
$VGNames = Get-Pfa2VolumeGroup -Array $PrimaryArray -ContextNames $goldContext -Filter "workload.name='Database-Prod-01'"
$VGNames
Id : c0174ce6-fccb-c143-f99e-f8835939cffa
Name : vg-10652a0c-Gold-QoS-vrbmj
Context : @{Id='ac5fc11f-8b3b-49a0-8261-43baf50b281b'; Name='sn1-x90r2-f06-33'}
Workload : @{Id='10652a0c-796f-4782-9819-08c987520be9'; Name='Database-Prod-01'; ResourceType='workloads'; _Configuration='Gold-QoS'}
Destroyed : False
Pod :
PriorityAdjustment : @{PriorityAdjustmentOperator='+'; PriorityAdjustmentValue=0}
Qos : @{BandwidthLimit=10737418240; IopsLimit=1000000}
Space : @{DataReduction=1; Snapshots=0; ThinProvisioning=1; TotalPhysical=0; TotalProvisioned=2306397437952; TotalReduction=1; TotalUsed=0; Unique=0; UsedProvisioned=2306397437952; Virtual=0}
TimeRemaining :
VolumeCount : 2
Get-Pfa2VolumeGroupVolume -Array $PrimaryArray -ContextNames $goldContext -GroupName $VGNames.Name | Format-List
Context : @{Id='ac5fc11f-8b3b-49a0-8261-43baf50b281b'; Name='sn1-x90r2-f06-33'}
Group : @{Id='c0174ce6-fccb-c143-f99e-f8835939cffa'; Name='vg-10652a0c-Gold-QoS-vrbmj'}
_Member : @{Id='2242c922-ee4f-a6d8-26a6-ec87f833776d'; Name='vg-10652a0c-Gold-QoS-vrbmj/vol-10652a0c-Gold-Vol-0000-lf2sr'}
Context : @{Id='ac5fc11f-8b3b-49a0-8261-43baf50b281b'; Name='sn1-x90r2-f06-33'}
Group : @{Id='c0174ce6-fccb-c143-f99e-f8835939cffa'; Name='vg-10652a0c-Gold-QoS-vrbmj'}
_Member : @{Id='6436298b-ea11-f6ea-b6d1-d5f88b849209'; Name='vg-10652a0c-Gold-QoS-vrbmj/vol-10652a0c-Gold-Vol-0001-fk82f'}
Fleet-Wide Workload Visibility
One of Fusion’s key benefits is the ability to view and manage resources across your entire fleet. Here’s some code to get a listing of all of the volumes associated with the workloads deployed in this blog post.
Write-Output "`nFleet-wide view of all workload volumes:"
Get-Pfa2Volume -Array $PrimaryArray -ContextNames $FleetMembers.Member.Name -Filter "workload.name='WebApp*' or workload.name='Database-*' or workload.name='Analytics-*'" |
Select-Object Name,
@{N='Array';E={$_.Context.Name}},
@{N='Size(GB)';E={[math]::Round($_.Provisioned/1GB,2)}},
@{N='Workload';E={$_.Workload.Name}},
@{N='VolumeConfig';E={$_.Workload._Configuration}} |
Sort-Object Name |
Format-Table -AutoSize
Fleet-wide view of all workload volumes:
Name Array Size(GB) Workload VolumeConfig
---- ----- -------- -------- ------------
vg-10652a0c-Gold-QoS-vrbmj/vol-10652a0c-Gold-Vol-0000-lf2sr sn1-x90r2-f06-33 2048.000 Database-Prod-01 Gold-Vol
vg-10652a0c-Gold-QoS-vrbmj/vol-10652a0c-Gold-Vol-0001-fk82f sn1-x90r2-f06-33 100.000 Database-Prod-01 Gold-Vol
This unified view enables:
- Capacity planning across arrays
- Performance monitoring by tier
- Compliance verification
- Cost allocation by workload
Best Practices for Service Catalogs
When implementing tiered storage services:
- Start Simple: Begin with basic tiers and add complexity as needed
- Document Clearly: Ensure tier definitions align with business requirements
- Monitor Usage: Track which tiers are most popular to optimize offerings
- Review Regularly: Adjust performance limits and retention policies based on actual usage
- Automate Deployment: Integrate with your service portal or automation platform
Summary
In this post, we’ve built a complete storage service catalog using Pure Storage Fusion Presets, demonstrating:
- How to create tiered storage offerings (Bronze, Silver, Gold)
- Leveraging different array types for cost optimization
- Configuring optional replication for disaster recovery
- Dynamic volume addition to existing workloads
- Fleet-wide resource visibility and management
This approach transforms storage from a technical component into a business service, enabling self-service consumption while maintaining governance and best practices.
Stay tuned as we continue exploring how Pure Storage Fusion enables enterprise storage as a service!