Introduction
An Azure Site-to-Site VPN can sometimes present a particularly frustrating problem:
Azure reports the VPN tunnel as Connected, but applications can no longer communicate with systems on the remote network.
Administrators may find that manually resetting the IPsec connection temporarily restores connectivity, only for the problem to return later.
Because the Azure portal continues to show the connection as Connected, it is easy to assume the VPN Gateway itself is healthy and start investigating firewalls, servers, applications or routing elsewhere.
However, a VPN being connected only confirms that an IKE/IPsec relationship exists between the VPN peers. It does not necessarily prove that every required application flow is successfully passing through the negotiated IPsec Security Association.
In a recent troubleshooting exercise, we encountered exactly this scenario.
The Azure Site-to-Site VPN remained connected, but users experienced intermittent connectivity. Resetting the IPsec connection temporarily restored service.
Rather than immediately changing VPN parameters or repeatedly resetting the tunnel, we used:
Azure VPN Gateway VPN Troubleshoot
Azure Storage for diagnostic output
VPN connection status diagnostics
Azure VPN Gateway resource logs
KQL queries
Azure PowerShell
IPsec/IKE policy verification
Traffic selector analysis
The investigation revealed an important clue:
A large number of Azure-to-on-premises packets were being dropped because of a traffic selector mismatch.
This article walks through the investigation method and explains how to troubleshoot this type of issue safely.
The Problem
The environment consisted of:
Azure Virtual Network
|
|
Azure VPN Gateway
|
| IKEv2 / IPsec
|
Internet
|
|
On-Premises VPN Device
|
|
On-Premises NetworkUsers reported intermittent loss of connectivity between Azure workloads and resources hosted on-premises.
The symptoms were:
Site-to-Site VPN showed Connected
Application connections stopped working intermittently
Azure resources could no longer reliably communicate with the remote network
Resetting the Azure VPN/IPsec connection restored communication
The issue returned later
There was no obvious indication that the Azure gateway itself was unavailable
This is an important distinction.
The problem was not simply:
VPN tunnel = DownInstead, it was closer to:
IKE/IPsec tunnel = Established
but
Application traffic = Not successfully traversing the tunnelWhy "Connected" Does Not Always Mean "Healthy"
Site-to-Site VPN connectivity has several layers.
A simplified view is:
Application
↓
IP routing
↓
Traffic selector / encryption domain
↓
IPsec Child SA / Phase 2
↓
IKE SA / Phase 1
↓
Internet connectivityIt is therefore possible for:
IKE = Established
VPN = Connectedwhile:
Required application traffic = DroppedFor example, if the active Phase 2 Security Association only covers:
Azure subnet A
↕
On-premises subnet Abut an application generates:
Azure subnet B
→
On-premises subnet Athat packet may not match the negotiated traffic selector.
The result can be a VPN connection that appears operational while production traffic fails.
Step 1 – Do Not Immediately Reset the VPN
When users report an outage, one of the most valuable things an administrator can do is preserve the failure state.
Resetting the connection immediately may restore service, but it also destroys useful diagnostic evidence.
A reset can cause:
Existing IKE SA removed
↓
Existing IPsec Child SA removed
↓
New IKE negotiation
↓
New Phase 2 negotiation
↓
New traffic selectors installedIf the issue relates to:
traffic selector negotiation
Phase 2 rekey
stale Security Associations
PFS negotiation
DPD
on-premises VPN behaviour
the reset may temporarily hide the underlying problem.
Therefore, where operationally possible:
Record the exact time of the outage.
Confirm the Azure VPN connection state.
Run VPN troubleshooting.
Capture diagnostic logs.
Record on-premises VPN state.
Only then reset the connection if required.
Step 2 – Run Azure VPN Gateway "VPN Troubleshoot"
Azure Network Watcher provides a VPN troubleshooting capability that can collect diagnostic information for VPN Gateway connections.
In the Azure portal, navigate to the relevant VPN troubleshooting functionality and select the affected connection.
Configure a Storage Account so that Azure can save the troubleshooting output.
A typical workflow is:
Azure Network Watcher
↓
VPN Troubleshoot
↓
Select VPN Gateway
↓
Select affected VPN connection
↓
Select/create Storage Account
↓
Start troubleshootingThe generated results can help show whether the VPN is connected and provide statistics associated with the tunnel.
In our investigation, we saved the generated connection status information to Azure Blob Storage for further analysis.
This is useful because it gives you a snapshot of the tunnel condition without immediately changing the VPN configuration.
Step 3 – Examine the Generated Connection Status
The generated VPN troubleshooting output contained statistics similar to:
Connectivity State : Connected
Remote Tunnel Endpoint : <remote-public-ip>
Ingress Bytes : <value>
Egress Bytes : <value>
Ingress Packets : <value>
Egress Packets : <value>
Ingress Traffic Selector Mismatch Drops : 0
Egress Traffic Selector Mismatch Drops : <high value>
Connected Since : <timestamp>
Throttle : FalseThe most important line was:
Egress Packets Dropped due to Traffic Selector MismatchA significant proportion of outbound packets had been dropped for this reason.
That changed the direction of the investigation.
Instead of treating this primarily as a VPN Gateway availability issue, the focus moved toward:
Azure address spaces
↓
On-premises address spaces
↓
Negotiated IPsec traffic selectors
↓
Phase 2 / Child SAWhat Is a Traffic Selector?
A traffic selector determines which traffic is allowed to use an IPsec Security Association.
For example:
Azure network
10.x.x.x/16
↕
On-premises network
172.x.x.x/24An IPsec Security Association may be negotiated to protect traffic between those networks.
In vendor terminology, traffic selectors may also be called:
Proxy IDs
Encryption domains
Crypto ACLs
Local/remote networks
Phase 2 selectors
Quick Mode selectors
Child SA selectors
The exact terminology depends on the VPN appliance.
Microsoft documents TunnelDiagnosticLog, IKEDiagnosticLog, GatewayDiagnosticLog and RouteDiagnosticLog as key VPN Gateway diagnostic categories. TunnelDiagnosticLog records tunnel state changes, while IKEDiagnosticLog provides IKE control-plane events useful for deeper IPsec troubleshooting.
Route-Based vs Policy-Based VPNs
Before changing Azure traffic selector settings, determine how the on-premises VPN is configured.
A modern route-based VPN typically uses:
Tunnel interface / VTI
+
Routingrather than tightly defining every subnet combination using crypto ACLs.
Azure connections commonly use:
UsePolicyBasedTrafficSelectors = Falsefor route-based deployments.
A policy-based VPN may instead explicitly define:
Local encryption domain
↕
Remote encryption domainFor example:
Azure:
10.x.x.0/24
On-premises:
172.x.x.0/24Do not simply enable policy-based traffic selectors because you see selector mismatch drops. First determine what the remote VPN device actually expects.
Step 4 – Inspect the Azure VPN Connection Configuration
Use Azure PowerShell:
$conn = Get-AzVirtualNetworkGatewayConnection `
-ResourceGroupName "<RESOURCE-GROUP>" `
-Name "<VPN-CONNECTION>"
$conn | Format-List *Review:
ConnectionType
ConnectionProtocol
ConnectionStatus
EnableBgp
UsePolicyBasedTrafficSelectors
DpdTimeoutSeconds
IpsecPolicies
TrafficSelectorPoliciesA typical route-based configuration might look conceptually like:
ConnectionType : IPsec
ConnectionProtocol : IKEv2
ConnectionStatus : Connected
EnableBgp : False
UsePolicyBasedTrafficSelectors : False
TrafficSelectorPolicies : {}At this stage, do not change anything.
First document the existing configuration.
Step 5 – Examine the IPsec/IKE Policy
Run:
$conn.IpsecPolicies | Format-List *Review:
SALifeTimeSeconds
SADataSizeKilobytes
IpsecEncryption
IpsecIntegrity
IkeEncryption
IkeIntegrity
DhGroup
PfsGroupFor example:
IKE Phase 1
----------------
Encryption AES256
Integrity SHA256
DH Group Group 14
IPsec Phase 2
----------------
Encryption AES256
Integrity SHA256
PFS ECP group
SA lifetime configured valueAzure supports custom IPsec/IKE connection policies that allow administrators to explicitly define encryption, integrity, DH, PFS and SA parameters.
The corresponding on-premises VPN should be checked for compatibility.
Particular attention should be given to:
IKE encryption
IKE integrity
DH group
IPsec encryption
IPsec integrity
PFS groupA mismatch in these settings can cause Phase 1 or Phase 2 negotiation/rekey issues.
Step 6 – Identify the Azure VNet Address Space
Run:
$vnet = Get-AzVirtualNetwork `
-ResourceGroupName "<RESOURCE-GROUP>" `
-Name "<VNET-NAME>"
$vnet.AddressSpace.AddressPrefixesThen list the subnets:
$vnet.Subnets |
Select-Object Name, AddressPrefix, AddressPrefixes |
Format-Table -AutoSizeYou may see something conceptually like:
VNet
10.x.x.0/22
Subnets
------------------------------------------------
GatewaySubnet 10.x.x.x/26
AzureFirewallSubnet 10.x.x.x/26
DirectoryServicesSubnet 10.x.x.x/26
AzureBastionSubnet 10.x.x.x/26
ApplicationSubnet 10.x.x.x/28Do not assume that the subnet containing the application is automatically the selector negotiated by the VPN.
The complete network configuration matters.
Step 7 – Identify the On-Premises Network Azure Knows About
Retrieve the Local Network Gateway:
$lng = Get-AzLocalNetworkGateway `
-ResourceGroupName "<RESOURCE-GROUP>" `
-Name "<LOCAL-NETWORK-GATEWAY>"
$lng.LocalNetworkAddressSpace.AddressPrefixesFor example:
172.x.x.x/27Azure uses the Local Network Gateway configuration to represent networks reachable behind the remote VPN device.
You can now compare:
Azure address space
↕
Local Network Gateway address spaceagainst the actual Phase 2 selectors configured on the on-premises device.
Step 8 – Check the On-Premises Phase 2 / Child SA
This step is critical.
From the on-premises firewall/VPN appliance, retrieve the active IPsec Phase 2 or Child SA.
Depending on vendor, look for fields such as:
Local selector
Remote selector
Local proxy ID
Remote proxy ID
Encryption domain
Crypto ACL
Child SA
Quick Mode SAThe firewall might show:
Local selector:
172.x.x.x/27
Remote selector:
10.x.x.x/22Compare these values against Azure.
A mismatch could look like:
Azure expects:
10.x.x.x/22
↕
172.x.x.x/27
Remote firewall negotiates:
10.x.y.x/28
↕
172.x.x.x/27Traffic originating outside the narrower selector may not match the active Child SA.
Step 9 – Check Whether Azure Firewall Is in the Path
Many Azure environments use a topology such as:
Application subnet
↓
User Defined Route
↓
Azure Firewall
↓
VPN Gateway
↓
On-premises networkIf Azure Firewall is involved, determine the actual source and destination IP addresses being sent toward the remote network.
Example KQL:
AZFWNetworkRule
| where TimeGenerated > ago(24h)
| where ipv4_is_in_range(DestinationIp, "<ON-PREMISES-CIDR>")
| project
TimeGenerated,
SourceIp,
DestinationIp,
DestinationPort,
Protocol,
Action
| order by TimeGenerated descYou are looking for:
Source IP
Destination IP
Destination Port
Protocol
Firewall ActionThis identifies the actual flow that must match the IPsec selector.
For example:
Application IP
↓
Remote database IP
↓
TCP 1433or:
Application IP
↓
Remote web service
↓
TCP 443Step 10 – Enable Azure VPN Gateway Diagnostic Logs
VPN troubleshooting should not stop with the generated connection status file.
Enable VPN Gateway diagnostic logging and send the logs to Log Analytics.
Important log categories include:
TunnelDiagnosticLog
IKEDiagnosticLog
GatewayDiagnosticLog
RouteDiagnosticLogMicrosoft documents these categories as covering tunnel state changes, IKE control messages, gateway configuration/maintenance events and route/BGP activity.
KQL – Find Tunnel Disconnects
AzureDiagnostics
| where TimeGenerated > ago(7d)
| where Category == "TunnelDiagnosticLog"
| where OperationName in (
"TunnelConnected",
"TunnelDisconnected"
)
| project
TimeGenerated,
OperationName,
remoteIP_s,
instance_s,
Message
| order by TimeGenerated ascThis helps answer:
Did the tunnel genuinely disconnect?
When did it disconnect?
Which gateway instance generated the event?
Did it reconnect immediately?
Did the gateway instance change?
KQL – Search IKE/IPsec Errors
AzureDiagnostics
| where TimeGenerated > ago(7d)
| where Category == "IKEDiagnosticLog"
| extend msg = tolower(Message)
| where
msg contains "error"
or msg contains "fail"
or msg contains "timeout"
or msg contains "dpd"
or msg contains "rekey"
or msg contains "delete"
or msg contains "selector"
or msg contains "proposal"
or msg contains "child"
or msg contains "pfs"
| project
TimeGenerated,
OperationName,
Message
| order by TimeGenerated descThis is useful for finding evidence of:
DPD failures
IKE failures
Child SA deletion
Phase 2 rekey
Traffic selector negotiation
Proposal mismatch
PFS mismatch
Peer timeoutKQL – Search Specifically for Traffic Selector Problems
AzureDiagnostics
| where TimeGenerated > ago(7d)
| where Category == "IKEDiagnosticLog"
| extend msg = tolower(Message)
| where
msg contains "traffic selector"
or msg contains "selector"
or msg contains "ts_unacceptable"
or msg contains "policy match"
or msg contains "no policy"
| project
TimeGenerated,
OperationName,
Message
| order by TimeGenerated descA selector-related error around the same time as the application outage is a strong indicator that the IPsec encryption domains need to be reviewed.
KQL – Build a Complete Incident Timeline
One of the most useful troubleshooting queries is:
AzureDiagnostics
| where TimeGenerated > ago(24h)
| where Category in (
"TunnelDiagnosticLog",
"IKEDiagnosticLog",
"GatewayDiagnosticLog",
"RouteDiagnosticLog"
)
| project
TimeGenerated,
Category,
OperationName,
remoteIP_s,
instance_s,
Message
| order by TimeGenerated ascWhen an outage occurs, narrow the time range:
AzureDiagnostics
| where TimeGenerated between (
datetime(<INCIDENT-START>) ..
datetime(<INCIDENT-END>)
)
| where Category in (
"TunnelDiagnosticLog",
"IKEDiagnosticLog",
"GatewayDiagnosticLog",
"RouteDiagnosticLog"
)
| project
TimeGenerated,
Category,
OperationName,
remoteIP_s,
instance_s,
Message
| order by TimeGenerated ascThis allows you to reconstruct the sequence:
Application failure
↓
IKE event
↓
Child SA event
↓
Selector negotiation
↓
Tunnel state change
↓
ReconnectStep 11 – Look for Rekey Patterns
An intermittent problem that repeatedly disappears after a VPN reset should always raise the question:
Does the failure occur during IPsec rekey?
An IPsec tunnel does not use a single Security Association forever.
Phase 2 Security Associations expire and are renegotiated.
A possible failure sequence is:
VPN working normally
↓
Phase 2 SA approaches expiration
↓
Rekey begins
↓
Peer proposes different/narrower selectors
↓
New Child SA established
↓
Tunnel still reports Connected
↓
Some application traffic no longer matches
↓
Traffic droppedThen:
Administrator resets VPN
↓
Fresh IKE/Phase 2 negotiation
↓
Traffic works againThis does not prove that rekey is the problem, but the timing should be investigated.
Compare the outage times against the configured IPsec SA lifetime.
Step 12 – Verify PFS Carefully
When a custom IPsec policy is configured, do not overlook Perfect Forward Secrecy.
For example, Azure may be configured for:
PFS = ECP groupwhile the remote firewall has:
PFS = disabledor:
PFS = different DH groupThe exact representation varies by vendor.
One device may show:
ECP256while another displays:
Group 19Always consult the VPN vendor's mapping.
A Phase 2 configuration mismatch can result in rekey failures or Child SA negotiation problems even when Phase 1 is healthy.
Step 13 – Validate Routing Separately
Traffic selector troubleshooting should not replace normal route validation.
If BGP is not enabled, Azure typically learns the on-premises ranges through the Local Network Gateway configuration.
For a VM network interface, check effective routes:
Get-AzEffectiveRouteTable `
-NetworkInterfaceName "<NIC-NAME>" `
-ResourceGroupName "<RESOURCE-GROUP>"Confirm that the remote prefix points toward the expected next hop.
Possible paths include:
VirtualNetworkGatewayor:
VirtualApplianceif traffic is intentionally routed through Azure Firewall or another NVA first.
Step 14 – Validate the Problem with Controlled Traffic
If the VPN diagnostic counters show traffic selector mismatch drops, perform a controlled test.
Record the current counter.
Then initiate connectivity from a known Azure source to a known on-premises destination.
For example:
Test-NetConnection <REMOTE-IP> -Port 443or:
Test-NetConnection <REMOTE-DATABASE-IP> -Port 1433Use the real application port whenever possible.
Then rerun the VPN troubleshooting status.
If:
Traffic selector mismatch dropsincrease immediately after the test, that is strong evidence that the tested source/destination pair does not match the negotiated IPsec selector.
What Not to Do
1. Do Not Keep Resetting the VPN Without Collecting Evidence
A reset may fix the symptom while removing evidence of the failure state.
Use reset as a recovery action, not as your troubleshooting strategy.
2. Do Not Assume "Connected" Means Application Connectivity Is Healthy
Always differentiate:
Control planefrom:
Data planeThe IKE tunnel may exist while application packets are being dropped.
3. Do Not Immediately Enable Policy-Based Traffic Selectors
Seeing a traffic selector mismatch does not automatically mean:
UsePolicyBasedTrafficSelectors = Trueis the solution.
First determine whether the remote device is:
route-based/VTI
policy-based
using proxy IDs
using multiple Child SAs
using specific encryption domains
Changing Azure selector behaviour without understanding the on-premises configuration can make the tunnel worse.
4. Do Not Change Multiple IPsec Parameters at Once
Avoid simultaneously changing:
IKE encryption
IPsec encryption
DH group
PFS
SA lifetime
DPD
Traffic selectorsIf you change everything at once and the problem disappears, you won't know which setting caused it.
Change one logical component at a time.
5. Do Not Assume SA Lifetimes Must Be Numerically Identical
IPsec SA lifetime behaviour deserves investigation, particularly when problems occur during rekey, but administrators should avoid changing values simply because they differ between vendors.
Focus first on:
IKE compatibility
IPsec compatibility
DH/PFS compatibility
Traffic selectors
Rekey behaviour6. Do Not Ignore the On-Premises VPN Logs
Azure represents only one half of the VPN.
You should correlate:
Azure IKE logs
+
Azure tunnel logs
+
On-premises IKE/IPsec logs
+
Application timestampsThe remote VPN appliance can often show exactly what selector it proposed and why a Child SA was removed or renegotiated.
Recommended Troubleshooting Workflow
A reliable workflow is:
1. User reports connectivity problem
↓
2. Record exact time
↓
3. Confirm Azure VPN tunnel state
↓
4. Do NOT immediately reset
↓
5. Run Azure VPN Troubleshoot
↓
6. Save diagnostic output to Blob Storage
↓
7. Examine connection status counters
↓
8. Look for traffic selector drops
↓
9. Capture Azure VPN diagnostic logs
↓
10. Capture on-prem VPN Child SA
↓
11. Compare Azure/on-prem selectors
↓
12. Compare Phase 1 / Phase 2 policy
↓
13. Validate routing
↓
14. Generate controlled traffic
↓
15. Confirm counters/log behaviour
↓
16. Correct the identified mismatch
↓
17. Monitor before closing incidentThis is far more effective than repeatedly resetting the VPN.
Example Root-Cause Scenario
Consider this example.
Azure contains:
VNet:
10.20.0.0/16
Application subnet:
10.20.10.0/24The on-premises network is:
172.16.20.0/24Azure believes the remote network is:
172.16.20.0/24But the on-premises firewall negotiates:
10.20.10.0/28
↕
172.16.20.0/24An application using:
10.20.10.25is outside:
10.20.10.0/28so traffic does not match the negotiated selector.
Azure may still report:
VPN Connection = Connectedwhile the application flow fails.
The correct solution is not necessarily to reset the VPN.
The correct solution is to understand why the encryption domains differ and align them with the intended network design.
Remediation Options
The correct remediation depends on the design.
Option 1 – Correct the On-Premises Route-Based VPN
If both sides are intended to use route-based VPNs, ensure the on-premises device is configured accordingly and supports the required Azure and on-premises routes.
This is often the preferred modern architecture.
Option 2 – Correct the Encryption Domain / Proxy IDs
If explicit selectors are required, ensure the correct Azure and on-premises ranges are represented.
For example:
Azure workload network
↕
On-premises application networkAvoid unnecessarily broad ranges simply to make the problem disappear.
The selectors should represent the intended security architecture.
Option 3 – Configure Azure Policy-Based Traffic Selectors When Required
Certain on-premises VPN appliances require explicit policy-based selector behaviour.
Azure can support policy-based traffic selectors in appropriate configurations.
However, implement this only after confirming the remote VPN requirement and testing all required subnet combinations.
Option 4 – Correct the Custom IPsec Policy
If the issue is caused by Phase 2 negotiation, align:
Encryption
Integrity
DH group
PFS groupwith the supported configuration on both peers.
Microsoft provides configuration options for custom IPsec/IKE policies on Site-to-Site VPN connections.
Option 5 – Investigate Rekey Behaviour
If application failures correlate with Security Association renewal:
compare Azure and remote VPN logs
identify the peer initiating rekey
inspect proposed selectors
inspect PFS negotiation
inspect Child SA deletion
inspect duplicate/stale SAs
verify vendor firmware and known VPN issues
Do not simply reduce SA lifetime as a first response.
Monitoring After Remediation
After making the correction, monitor:
Tunnel disconnect events
Traffic selector mismatch drops
IKE negotiation failures
Child SA events
Application connectivity
Firewall flowsA useful KQL query is:
AzureDiagnostics
| where TimeGenerated > ago(24h)
| where Category in (
"TunnelDiagnosticLog",
"IKEDiagnosticLog",
"GatewayDiagnosticLog"
)
| where
OperationName contains "Disconnect"
or Message contains "fail"
or Message contains "error"
or Message contains "selector"
or Message contains "rekey"
| project
TimeGenerated,
Category,
OperationName,
remoteIP_s,
instance_s,
Message
| order by TimeGenerated ascAlso rerun Azure VPN Troubleshoot after remediation and verify that:
Egress Packets Dropped due to Traffic Selector Mismatchis no longer continuously increasing during valid production traffic.
Key Lessons
The most important lesson is:
A connected VPN tunnel does not prove that the data plane is healthy.
When an Azure Site-to-Site VPN periodically stops passing traffic, particularly when resetting the connection temporarily fixes it, investigate beyond the portal's Connected/Disconnected indicator.
Check:
VPN troubleshooting counters
Traffic selector mismatch
IKE logs
Tunnel logs
Phase 2 Child SAs
PFS
Encryption domains
Azure address spaces
Local Network Gateway prefixes
On-premises proxy IDs
Routing
Firewall flow logs
Rekey timingMost importantly, preserve the failed state long enough to collect evidence.
A manual reset may restore service, but understanding why the reset restores service is what ultimately leads to a permanent fix.
Conclusion
Intermittent Azure Site-to-Site VPN problems can be challenging because the VPN control plane and data plane can behave differently.
In the scenario discussed here, Azure continued to report the VPN connection as connected. However, the VPN troubleshooting output saved to Azure Blob Storage revealed a much more useful clue: packets were being dropped because they did not match the active traffic selector.
That evidence changed the investigation from:
"Why does the Azure VPN Gateway keep disconnecting?"to:
"Why does production traffic no longer match the negotiated IPsec Security Association?"That is a much more precise troubleshooting question.
By combining Azure VPN Troubleshoot, connection-status output, PowerShell, Log Analytics, KQL, IPsec/IKE policy analysis and the on-premises Child SA configuration, administrators can distinguish gateway availability problems from routing, selector and Phase 2 negotiation issues—and fix the actual root cause instead of repeatedly resetting the tunnel.
Need Help Troubleshooting Azure Connectivity?
Onsys Technologies provides Azure infrastructure, networking, database and managed IT services for organisations running business-critical workloads across cloud and on-premises environments.
Our team can assist with:
Azure VPN Gateway troubleshooting
Site-to-Site VPN architecture
ExpressRoute troubleshooting
Azure Firewall
Hybrid network connectivity
Azure routing and UDR analysis
IPsec/IKE troubleshooting
Network performance diagnostics
Azure monitoring and alerting
Cloud infrastructure health checks
If your Azure VPN shows Connected but your applications are still experiencing intermittent connectivity, a systematic analysis of both the control plane and data plane can often identify the underlying issue without relying on repeated tunnel resets.
Onsys Technologies – Azure, Database and Cloud Infrastructure Specialists

