Skip to main content

Azure Storage - Data protection from deletion

Let me start with a story - "In 2015 we were running a 2 weeks performance test on our solution, that was hosted inside Microsoft Azure. After the performance test finished, we have a clean-up of all the resources. The cleaning script was build in such a way as to not delete the logs storage. After a few days, I was notified that we still have consumption on that subscription. I forgot that there are the storages where we have logs, so I purged the subscription. The 2 weeks of performance logs and metrics were lost forever."

Nowadays, we have a lot of mechanisms to avoid such a thing. Let's look at what we could do to not be in the same situations as I was in 2015.

(1) Resource Lock

The first thing that we shall configure is resource lock at Azure Storage level for "Do Not Delete." As long as the resource has this lock, nobody would be able to delete the resource. 

(1.1) RBAC Configuration - restrict lock access

Having the lock configured ensures that you or somebody else cannot remove the storage without removing the lock first. The next step is to ensure that the "Do Not Delete" lock can be modified only by the right people. 

Using RBAC, we have the ability to create roles that have or not have access to Microsoft.Authorization/* or Microsoft.Authorization/locks/* actions. Only users that have these actions assigned can modify a lock. (exception Owner and User Access Administrator). 

(2) Soft Delete

This feature helps us to prevent accidental deletion or even changes on a blob or containers. At the moment when you activate it, the content is only soft deleted. Meaning that in the case you decide that you want to recover the content, you have the ability to do this. 

There is a retention policy that can be configured, depending on your needs. By default, the soft-deleted objects are not visible. If you want to view them, you need to specify in the list option a specific attribute.

(3) Versioning 

Provides us the ability to create multiple versions of the same storage object. Each time when a storage object is modified, a new version of it is created. In the case of deletion, we can restore a previous version of the object. 

When we have the blob versioning active, the deletion operation represents only another version of the blob. The full version tree for the deleted blob is persisted. 

(4) Snapshots

The snapshots provide us the capability to create a 'hard' version of the blob. All the content is copied and can be accessed later on. To access a specific snapshot,, we need to append to the blob name the snapshot's date and time. 

Even if we have snapshots available, we need to be aware that we need to configure them so that others would not be able to remove them.

(5) Change feed

Used for systems where we need to get notified when a blob is modified. The change feed provides a channel for consumers who can be notified when a blob's content is modified. 

Change feed needs to be used carefully because they it can generate a high load on the consumers, and many times, we don't need to be notified of all the changes. 

(6) Point-in-time restore

It gives us the ability to create policies that would protect us from accidental deletion. Once we have the data in a consistent state, we can create a point-in-time restore that can be used later on in time. 

The functionality works in combination with other features that need to be enabled (Soft Delete, Blob versioning, and Change feed). 


Conclusion

If we take the story that I presented initially, I would prefer to have the Resource Lock and a Snapshot created after the performance tests where I finished. These two items would enable me to have the storage configure so that accidental deletion should not happen, and they would not cause data loss. 

Comments

Popular posts from this blog

Windows Docker Containers can make WIN32 API calls, use COM and ASP.NET WebForms

After the last post , I received two interesting questions related to Docker and Windows. People were interested if we do Win32 API calls from a Docker container and if there is support for COM. WIN32 Support To test calls to WIN32 API, let’s try to populate SYSTEM_INFO class. [StructLayout(LayoutKind.Sequential)] public struct SYSTEM_INFO { public uint dwOemId; public uint dwPageSize; public uint lpMinimumApplicationAddress; public uint lpMaximumApplicationAddress; public uint dwActiveProcessorMask; public uint dwNumberOfProcessors; public uint dwProcessorType; public uint dwAllocationGranularity; public uint dwProcessorLevel; public uint dwProcessorRevision; } ... [DllImport("kernel32")] static extern void GetSystemInfo(ref SYSTEM_INFO pSI); ... SYSTEM_INFO pSI = new SYSTEM_INFO(

Azure AD and AWS Cognito side-by-side

In the last few weeks, I was involved in multiple opportunities on Microsoft Azure and Amazon, where we had to analyse AWS Cognito, Azure AD and other solutions that are available on the market. I decided to consolidate in one post all features and differences that I identified for both of them that we should need to take into account. Take into account that Azure AD is an identity and access management services well integrated with Microsoft stack. In comparison, AWS Cognito is just a user sign-up, sign-in and access control and nothing more. The focus is not on the main features, is more on small things that can make a difference when you want to decide where we want to store and manage our users.  This information might be useful in the future when we need to decide where we want to keep and manage our users.  Feature Azure AD (B2C, B2C) AWS Cognito Access token lifetime Default 1h – the value is configurable 1h – cannot be modified

ADO.NET provider with invariant name 'System.Data.SqlClient' could not be loaded

Today blog post will be started with the following error when running DB tests on the CI machine: threw exception: System.InvalidOperationException: The Entity Framework provider type 'System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer' registered in the application config file for the ADO.NET provider with invariant name 'System.Data.SqlClient' could not be loaded. Make sure that the assembly-qualified name is used and that the assembly is available to the running application. See http://go.microsoft.com/fwlink/?LinkId=260882 for more information. at System.Data.Entity.Infrastructure.DependencyResolution.ProviderServicesFactory.GetInstance(String providerTypeName, String providerInvariantName) This error happened only on the Continuous Integration machine. On the devs machines, everything has fine. The classic problem – on my machine it’s working. The CI has the following configuration: TeamCity .NET 4.51 EF 6.0.2 VS2013 It see