Configuring Azure object storage: Terraform, Lifecycle, and RBAC

File storage hits a ceiling as data volumes grow: access slows down, and backups no longer fit into the maintenance window. We configure turnkey Azure object storage — from design and access control to file migration and team handover. Storage costs stop growing, and data access becomes several times faster.

Our competencies:

Frequently Asked Questions

Latest works

  • Development of a web application for FEEDME
    Development of a web application for FEEDME
    1365
  • Development of an online store for the company FURNORO
    Development of an online store for the company FURNORO
    1330
  • B2B Advance company logo design
    B2B Advance company logo design
    776
  • Development of a web application for Enviok
    Development of a web application for Enviok
    1077
  • AIDER company logo development
    AIDER company logo development
    1022
  • CRM development for Chasseurs
    CRM development for Chasseurs
    1113

Azure Blob Storage: where object storage breaks

Object storage seems like the simplest service in the cloud: create a container, grant access, upload files. Problems begin later — when Azure Blob Storage turns into a dumping ground for logs, exports, user attachments, and database dumps.

Data growth happens unnoticed: the container grows, but neither development nor operations has a clear answer to the question “what here is actually needed.”

Data growth hits two places at once. Storage and transaction costs grow, and inventorying the contents turns into hours of manual review.

A separate risk category is public links to files: a container with public read access serves an attachment to anyone who knows the address, and this is usually discovered during a security review, not earlier.

The third typical failure is manual operations instead of configuration. Files are uploaded by scripts without versioning, access is granted through the portal “by eye,” lifecycle rules are not configured, and old versions along with uncommitted uploads are billed for years.

At the same time, there is no way to restore rollback or access audit: no history, no roles, no reproducible scheme.

We break down how this is addressed: configuring file storage as code, lifecycle rules by tags and object age, access through roles and short-lived tokens instead of broad keys.

What managed object storage provides

Managed object storage is not a separate service, but a layer of policies on top of Azure Blob Storage: containers, access, and lifecycle rules are described in code and versioned together with the rest of the infrastructure.

An engineer does not go into the web console to create storage or grant access — a change passes review and reaches the environment the same way as the application.

Data recovery time is reduced from hours to minutes.

Object versioning preserves previous editions of a file, and soft delete leaves a trace even after a delete command: rollback after an export failure or an unsuccessful script is restoring a specific version, not searching for a copy on someone else’s drives and exchanging messages with a contractor.

A separate class of failures goes away with manual file management.

Permissions are granted by roles at the container level, access keys are not spread across configurations and message threads, and policies are not edited by hand — therefore “we deleted the wrong thing” and “a former contractor still has access” stop being recurring stories. Access is checked by role, not by who still has the key.

Storage cost reduction comes not from cutting, but from rules: infrequently accessed data moves to cooler tiers, old versions and uncommitted blocks are cleaned on schedule, and the volume stops growing on its own.

Growth becomes predictable — you can see how much each data stream occupies and what increase a new source adds.

Deployment options and access modes

The choice of scheme is determined by two questions: where requests to the data come from and how strictly traffic needs to be isolated.

The same service can live in a public perimeter, behind a private channel, or in a hybrid scheme — each option has its own constraints, and they show up not at the start, but during scaling or an external audit.

Option When it fits Constraints
Public access by key or signed URL External contractors, one-off exchanges, debugging The key leaks together with the repository or logs; manual rotation; traffic goes over the internet
Restriction by subnets and addresses Your own services in the cloud and access from the office Rules live separately from code; during relocation or address changes, access breaks silently
Private network with a private endpoint Personal data, regulator requirements, internal systems More expensive to maintain: private DNS zone, route coordination, separate path for diagnostics
Multiple storage accounts Different environments, teams, or data classes The number of places where rules and accounts are configured grows; a unified template and shared log are needed
Hybrid scheme: hot data in the cloud, archive on your own infrastructure Requirement to store part of the data locally Two sets of policies and two monitors; without synchronization of tags and retention periods, data sprawls

In practice, the scheme is assembled from several rows of the table: the hot tier in the cloud behind a private network, the archive in a separate account with long retention periods, and access is granted by roles to a specific container, not the entire account.

Such a set is described in code, so the access mode changes by editing the template, not by manual configuration in the console.

Storage implementation stages: from audit to handover

The work proceeds sequentially: each next stage relies on the artifacts of the previous one. This way, migration does not turn into an experiment on the production environment, and access and retention rules are described before the first object appears in Azure Blob Storage.

  1. Data storage audit. Inventory of containers, volumes, read and write profiles, data sources, and their lifecycles. We record what belongs to hot data, what to archival data, and where duplicates or “orphaned” sets currently are.

  2. Storage design. Layout across containers and access tiers: which set goes where, how often it is accessed, what requirements exist for retention and deletion. The design is agreed before writing code.

  3. Infrastructure as code. Terraform modules for the account, containers, network restrictions, and versioning. Any change passes review, and the environment is reproduced from scratch with one command.

  4. Roles and access permissions. Separation at the subscription, resource group, and container level, separate accounts for applications and people, the minimum required set of permissions. We verify that the service does not have excessive access.

  5. Lifecycle policies. Rules for moving objects to cooler tiers, deleting previous versions and uncommitted blocks, and retention periods. The storage estate stops growing uncontrollably, while rollback to a previous state remains possible.

  6. Data migration. First a pilot set: we measure speed, integrity by checksums, and behavior during connection loss. Then the main stream — with the ability to catch up without stopping sources.

  7. Verification and handover. Access and fault-tolerance tests, monitoring and alerting setup, change documentation. We hand over the code, design, and instructions to your team — maintenance stays in-house.

What we hand over after implementation

We hand over not a set of configurations “as they turned out,” but a working system that your engineer can evolve and maintain without us. Below is what physically remains in the repository and in the policies, and what we go through together during acceptance.

  • Data placement design — which containers and accounts are created, where the boundaries of hot and archival tiers are, how resources are laid out across environments.
  • Storage configuration — described declaratively: modules, variables for each environment, isolated state. Deployment from scratch reproduces production without manual edits.
  • Access roles — the list of assignments by container, service accounts for applications, minimally sufficient privileges. Keys are not stored in code or configurations.
  • Lifecycle policies — rules for moving to cooler tiers, versioning, soft delete, and protection against mass deletion. The storage estate stops growing uncontrollably.
  • Backup policy — what is copied, at what frequency, where the copy is stored, who confirms recovery, and by what checks.
  • Storage documentation — resource map, relationship diagram, owners, procedure for adding a new container, and common operations.
  • Monitoring and alerts — a set of signals for availability, authorization failures, and capacity usage, linked to the on-call shift.

During acceptance, we go through the list together with your engineer: deploy storage from scratch, grant and revoke access, restore an object from a copy. Items that are not reproducible remain in progress until resolved.

Case: file storage migration, metrics before and after

The customer worked on a shared network drive: folder permissions were granted manually, and nightly copy jobs could not keep up with data growth.

Rolling back to a previous file version was possible only from a backup and took hours, and some working documents existed in a single copy.

We laid out the disk structure across containers and prefixes in Azure Blob Storage, moved access to container-level roles, and described retention rules declaratively — lifecycle policies now live in the repository and pass review before being applied.

What changed in numbers

Metric Before After
Downtime during cutover hours in a maintenance window 0 — writes were not stopped
Data integrity manual spot checks checksum verification across all objects, no discrepancies
Rollback to previous version hours from backup minutes: versions are stored with the object itself
Access permissions manual per-folder grants container-level role, changes via repository
Volume growth constant, scheduled cleanup lifecycle policies release old versions automatically

The cutover was done without stopping writes: the old disk remained read-accessible until checksum verification confirmed that everything had been migrated.

People continued working in familiar network paths — they were connected to the new storage, so retraining was reduced to one instruction.

In operations, one class of tasks remained instead of three: storage, access, and cleanup rules are described in the repository and reproduced during deployment. Storage costs stopped growing linearly — versions and snapshots are removed by policy, not by someone’s memory.

What to do if file storage is already deployed in Azure

There is no need to stop services for the migration. Both access types are provisioned for the same data, and consumers are migrated one by one: applications working with file paths continue to see them. A compatibility layer sits on top of object storage and provides the familiar reads and writes.

The question is not the migration itself, but which data to leave in file storage and which to move to object storage. The working scheme here is combined, and this is not a temporary stage for one week.

Directories with frequent overwrites, locks, and appends remain on file storage: object storage does not have such operations natively, and the compatibility layer adds latency for small files.

Archives, exports, copies, and media move to object storage — in Azure Blob Storage they are read as whole objects and rarely change, and storage costs stop growing along with volume.

Gradual migration proceeds by consumer, not the entire environment at once. First, copying is enabled, then checksum and size verification — it shows what did not arrive or changed during the process. Then reporting, analytics, and backups move to object storage.

The old environment remains read-open until the last step: rollback is a route change, not restoration from copies. Downtime-free migration relies on dual writes during the transition stage, integrity control, and identical access permissions in both environments.

Common technical doubts before starting

The customer’s engineering team usually asks the same set of questions before starting: will versioning break existing applications, how to restrict network access, and will code need to be rewritten.

In Microsoft Azure, all three topics are addressed by storage settings, not by reworking services — below are short answers for each.

Will enabling versioning break existing writes?

No. Versioning and soft delete are enabled at the container level and do not change the object format — applications write and read the same data.

Only volume grows, so the fate of old versions is immediately described by a lifecycle policy: keep the last few versions and delete the rest by age, so the storage estate does not grow uncontrollably.

Will network access restrictions require application changes?

For services inside a virtual network, the restriction is transparent: access goes through a private endpoint, and the connection string remains the same.

Changes are needed where an application accesses storage by access key or from an external network — such places we move to managed identities and roles, so keys do not sit in configurations.

What happens if lifecycle rules delete something needed?

With soft delete enabled, the object is restored within the specified period. Therefore, we set the retention period for deleted data longer than the interval of checks and backups, and first run new rules in report mode to see what would fall under deletion.

Let's discuss your task and return with an estimate and plan

The first conversation is about gathering inputs, without which the implementation plan will be approximate. We need to understand the volume and profile of data, how it is distributed by access frequency, and who receives access through which channels.

Separately, we clarify requirements for retention periods, deletion protection, and rollback — these determine the structure of containers and policies.

Here is what we cover on the call:

  • data volume and profile: how much is stored now, what growth is expected, what share of objects is read regularly, and what sits as dead weight;
  • access model: who reads and writes, which services access storage, how permissions are separated by roles;
  • storage tiers and lifecycle rules: what moves to the cool and archive tier, what is deleted, and by what attribute;
  • versioning and protection: whether previous object versions are needed, deletion lock, soft delete, and recovery periods;
  • infrastructure as code: where Terraform state is stored, who edits the configuration, and how changes pass review before being applied;
  • network access and identities: public endpoint or private connections, access keys or managed service identities;
  • constraints of your environment: compatibility with existing systems, allowed change windows, and requirements for rollback to the previous configuration.

As the output, you receive an implementation plan: the sequence of stages, configuration composition, acceptance criteria, and a scope estimate with a timeline breakdown. Describe the task in a convenient format — we will return with a plan and a proposed order of work.