Cloud Tech by Victor

Search

30 results for “bicep

Search results

Blog

Build a Secure Azure Environment in Minutes with Bicep: VMs, Networking, Private Endpoints & Blob Replication

A hands-on Infrastructure-as-Code lab deploying a production-ready Azure environment from a single Bicep template.

Blog

Deploying a Scalable Azure Environment with Bicep: VMs, NSGs, Subnets & Load Balancer (Step-by-Step Lab)

A hands-on IaC walkthrough using VS Code and Bicep to build a secure, highly available Azure environment.

Blog

Automating Azure Infrastructure with Bicep: A Hands-On IaC Lab Using VS Code

Deploying VNets, VMs, IAM, Policies, Monitoring, and Governance using Infrastructure as Code.

DevOps

Terraform vs Bicep

How Terraform and Bicep differ in state management, cloud scope, and tooling, and which one fits your Azure infrastructure-as-code workflow.

Azure Fundamentals

What is Azure Resource Manager (ARM) and why does every Azure operation go through it?

ARM is the deployment and management layer that every Azure operation, whether from the Portal, CLI, PowerShell, or an ARM/Bicep template, ultimately goes through. It provides a consistent API surface, handles authentication and authorization checks against Azure RBAC, and is what enables declarative deployment (submit a template describing desired resources, ARM figures out what to create/update). Because every path converges on ARM, access control and activity logging are consistent regardless of which tool was used to make a change.

Container Image Scanning

Why does a smaller, minimal base image reduce security risk beyond just producing a smaller download?

Every package present in a base image is a package that can have a known vulnerability, and a full general-purpose distribution image bundles far more OS packages, libraries, and tools than most applications actually need at runtime. A minimal image (Alpine, a distroless image, or a multi-stage build's final stage) simply has fewer things in it that could ever show up in a vulnerability scan, which is a structural reduction in attack surface, not a mitigation that has to be maintained the way a scanner's exception list does.

Azure Active Directory (Entra ID)

What is a managed identity, and what problem does it solve compared to a service principal with a client secret?

A managed identity is an Entra ID identity automatically managed by Azure for a resource (a VM, an App Service, a Function), with credentials that Azure handles entirely, no client secret is ever stored, retrieved, or rotated by the application. A traditional service principal with a client secret requires that secret to be stored somewhere (a config file, a key vault) and rotated manually or via automation, which is itself a credential-management burden and a leak risk. Managed identities remove that burden for the common case of "this Azure resource needs to authenticate to another Azure service," which is why they're preferred whenever the workload runs on Azure compute.

Database Locking & Deadlocks

Two transactions each update two of the same two accounts, but in opposite order, and deadlock. What's the actual fix, not just for this pair of transactions, but for the application generally?

The deadlock happens because Transaction 1 locks account A then waits for account B, while Transaction 2 locks account B then waits for account A, a circular wait. The general fix isn't retry logic alone, retries only paper over deadlocks that keep recurring, it's acquiring locks on multiple objects in the same, consistent order everywhere in the application (for example, always locking accounts in ascending id order), which makes the circular-wait pattern structurally impossible rather than merely less frequent. Retry logic is still worth having as a safety net, but consistent lock ordering is what actually eliminates this class of deadlock.

Linux Process Management & systemd

What is the practical difference between ps -ef and ps aux, and why do they show different columns for the same processes?

`-ef` is UNIX-style syntax and `aux` is BSD-style syntax for the same underlying command, and they weren't designed as one consistent interface; mixing them can even be ambiguous depending on other options used. The manual is explicit that BSD-style options change the default output to include process state (STAT) and full command arguments (COMMAND) instead of just the executable name, and BSD-style selection also defaults to showing every process the invoking user owns across all terminals, while UNIX-style selection defaults to processes on the current terminal only. Neither is "more correct," they're two different historical option conventions layered onto the same command, which is why picking one and being consistent about it matters more than which one.

Python Syntax Fundamentals

Why does Python use indentation instead of braces to define code blocks, and what problem does this create?

Python uses indentation as syntax specifically to force a consistent visual structure, code that looks nested is nested, with no possibility of a brace mismatch making the visual and actual structure disagree, a real class of bugs in brace-delimited languages. The trade-off is that whitespace becomes semantically meaningful: mixing tabs and spaces, or an accidentally misaligned line, is a syntax error (or worse, silently changes which block a line belongs to) rather than a cosmetic issue. Python 3 disallows mixing tabs and spaces in the same file specifically to prevent the silent version of this problem.

Web Performance & Core Web Vitals

A page has a fast average LCP but users still frequently report the page feeling slow. What could the percentile-based measurement reveal that an average wouldn't?

If a substantial slice of real page loads, say the slowest 25%, badly miss the 2.5 second LCP threshold (a slow connection, a busy device, a cold cache), the average can still look fine because it's dominated by the faster majority, while a real, sizable group of users are having a genuinely bad experience the average is actively hiding. Checking the 75th-percentile value directly (rather than the mean) surfaces that gap: if the 75th percentile is well above 2.5 seconds even though the average looks fine, that's a concrete signal that meaningful numbers of real users are missing the threshold, not a false alarm.

Linux Logging & Monitoring with journald

What does journalctl -u myservice actually show you, beyond just log lines the service itself printed?

`-u`/`--unit=` expands into a filter that captures more than the service's own stdout/stderr, it includes messages logged about the unit by systemd itself (start, stop, failure notifications) and associated coredump information if the process crashed, correlated by the unit's identity rather than by manually grepping a shared log file for its name. This is more reliable than text-searching a combined log, since it's scoped by the actual unit metadata the journal records, not by whatever string happens to appear in a log line.

Message Queues & Event-Driven Architecture

What is a visibility timeout, and what problem does it solve that simply having multiple consumers poll a queue would create?

When a consumer receives a message, the queue doesn't delete it immediately, it starts a visibility timeout during which that message is hidden from other consumers, so a second consumer polling the same queue won't also pick up and process the same message concurrently. The consumer is expected to finish processing and explicitly delete the message before the timeout expires; if it does, the message never reappears. Without this mechanism, multiple consumers competing for messages would routinely double-process the same one, exactly the race condition visibility timeouts exist to prevent.

Service Mesh Basics

What does a service mesh add on top of what Kubernetes Services already provide?

A Kubernetes Service provides basic load-balanced routing to a set of Pods by label selector, that's it. A service mesh intercepts every request in and out of a Pod (via a sidecar proxy) to add a uniform layer of capabilities across all services without changing application code: mutual TLS encryption between services, fine-grained traffic control (canary percentages, retries, timeouts, circuit breaking), and rich per-request observability (latency, error rate, and request volume between every pair of services). Services give you connectivity; a mesh gives you control and visibility over that connectivity.

Big O Notation

What is the difference between time complexity and space complexity?

Time complexity describes how the number of operations grows with input size; space complexity describes how additional memory usage grows with input size. An algorithm can trade one for the other, memoization in dynamic programming typically turns exponential time into polynomial time by spending O(n) or more extra space to cache results.

Browser Rendering Pipeline

What are the five stages of the browser rendering pipeline, and which ones does a change to a property like width actually have to go through?

The pipeline runs JavaScript, Style calculation, Layout, Paint, and Composite, in that order. Changing a property that affects geometry, `width`, `height`, `position`, forces the browser through every stage: layout has to be recalculated (since the element's size or position changed), then paint (since pixels changed), then composite. That full path is why layout-affecting properties are the most expensive to animate, every frame re-runs the whole pipeline, not just a cheap final step.

CI/CD Pipelines

What is the difference between continuous integration, continuous delivery, and continuous deployment?

Continuous integration means every code change is automatically built and tested against the main branch frequently; the goal is catching integration problems within minutes, not weeks. Continuous delivery extends that so every change that passes CI is automatically packaged into a release-ready artifact, though a human still decides when to actually deploy it. Continuous deployment goes one step further and removes that human gate, every change that passes all automated checks is deployed to production automatically. The three form a spectrum of increasing automation, and most teams stop at continuous delivery rather than full continuous deployment for anything customer-facing.

Database Connection Pooling

What is the practical difference between session pooling and transaction pooling, and why does transaction pooling scale better?

Session pooling assigns one server connection to a client for their entire session, released back to the pool only when the client disconnects, which supports every PostgreSQL feature but means a mostly-idle client still occupies a real server connection the whole time it's connected. Transaction pooling instead assigns a server connection only for the duration of a single transaction, returning it to the pool the moment the transaction ends, so many more clients can share a small, fixed pool of real connections, since a client that isn't actively mid-transaction isn't holding one at all. This is why transaction pooling is the standard choice for applications with many short-lived connections (like a web app's connection-per-request pattern) against a database with a hard connection limit.

Database Transactions & Isolation Levels

A transaction under Repeatable Read isolation fails with "could not serialize access due to concurrent update." What actually happened, and what is the application expected to do?

Repeatable Read uses snapshot isolation, the transaction sees a consistent snapshot from its own start, but if it then tries to update a row that another, concurrently-committed transaction already modified, PostgreSQL detects the conflict and aborts the transaction with a serialization failure rather than silently applying an update based on stale data. This is not an application bug, it is Repeatable Read (and Serializable) working as designed, both isolation levels explicitly require the application to catch this specific error and retry the transaction from the beginning, trading the guarantee of not overwriting concurrent changes for the operational cost of occasional automatic retries.

Docker Fundamentals

Why is publishing a port with `-p 8080:80` different from the container just "having" port 80?

A container's ports exist only on its own private network namespace by default; nothing on the host or outside can reach them until Docker explicitly forwards a host port to it. `-p 8080:80` tells Docker's network layer to forward the host's port 8080 to port 80 inside the container's namespace, host port first, container port second. Leaving a port `EXPOSE`d in a Dockerfile only records metadata/documentation, it has no effect on connectivity at all: another container on the same Docker network can already reach any port the first container is listening on, EXPOSE or not. Publishing to the host is the one thing that always requires an explicit `-p`.

Hash Tables & the Hash/Equality Contract

Why does Python's documentation say a class defining mutable objects with a custom __eq__ should not implement __hash__ at all?

If an object's hash is derived from fields that can change after the object is already stored as a dict key, mutating it changes its hash value, but the object stays in whatever bucket it was originally placed in based on the old hash, so a subsequent lookup computes the new hash, looks in the new (wrong) bucket, and fails to find an object that is, in fact, still in the dictionary. Making a mutable object unhashable by default (which not defining `__hash__` effectively signals) prevents this specific class of bug entirely, at the cost of not being able to use that object as a dict key or set member at all, a deliberate, documented trade-off favoring correctness over convenience.

Idempotency in Distributed Systems

A client sends a payment request, the network times out before a response arrives, and the client retries with the same idempotency key. What actually happens on the server?

If the original request already completed (successfully or even with an error like a 500) before the retry arrives, the server returns the exact same result it returned (or would have returned) the first time, the same status code and response body, without re-executing the underlying operation, so the customer isn't charged twice just because the client never saw the first response. This is the entire point of an idempotency key: it lets a client safely retry an operation whose actual outcome it's genuinely uncertain about (did the first request even reach the server? did it complete before the timeout?) without that retry risking a duplicate side effect.

Kubernetes Security

What is the difference between the Baseline and Restricted Pod Security Standards levels, and why are they cumulative?

Baseline blocks the most well-known container privilege-escalation paths, privileged containers, host namespaces, hostPath volumes, dangerous Linux capabilities, while still allowing a fairly permissive pod spec otherwise. Restricted inherits every Baseline rule and adds real hardening on top: it requires running as non-root, forbids privilege escalation outright, requires a restricted seccomp profile, and requires dropping all Linux capabilities except NET_BIND_SERVICE. A read-only root filesystem is not part of either standard, it's a separate hardening measure some organizations layer on as their own policy, on top of, not as part of, Restricted. They're cumulative by design, Restricted is Baseline plus more, so a workload that passes Restricted automatically satisfies Baseline too, and a cluster can apply different levels per namespace based on how much a given workload can be trusted.

Linux Filesystem Hierarchy & Permissions

A process creates a file requesting mode 0666, but the file ends up with permissions 0644. What decided that, and would the outcome change if the parent directory had a default ACL?

The process's umask is what changed the requested mode: umask 022 turns off the write bit for group and others from any requested mode, so 0666 (rw-rw-rw-) becomes 0666 & ~022 = 0644 (rw-r--r--). The umask is applied by the kernel at file/directory creation time, not by the application deciding to be conservative. If the parent directory has a default ACL set, that changes the outcome: default ACL inheritance takes precedence over the umask entirely, so the new file's permissions would instead be derived from the ACL, not from applying umask to the requested mode.

LLM Evaluation & Reducing Hallucinations

Why is an evaluation suite necessary before shipping a prompt change, instead of just testing it manually on a few examples?

A prompt change can improve one success dimension while quietly breaking another, better accuracy but worse consistency, or improved tone at the cost of latency, and manually eyeballing a handful of examples won't reliably catch a regression on a dimension you weren't specifically looking at. An evaluation suite tests against a defined, ideally large set of cases, including deliberately hard edge cases like sarcasm or mixed sentiment, and scores every dimension that actually matters, which turns "it feels better" into a measurable, defensible, trackable claim, and catches regressions before they reach production rather than after.

PostgreSQL Fundamentals

Why does wrapping several statements in `BEGIN`/`COMMIT` matter, even for a multi-step operation that's logically one action?

Without an explicit transaction, PostgreSQL commits each statement independently the moment it succeeds; if a multi-step operation (debit one account, credit another) fails halfway through, the database is left in an inconsistent, partially-applied state with no way to undo the completed step. Wrapping the statements in `BEGIN`/`COMMIT` groups them so they can be committed or rolled back together, but that alone isn't automatic protection against every failure mode: PostgreSQL only aborts a transaction on its own when a statement raises an actual SQL error, an `UPDATE` that runs successfully but matches zero rows (a mistyped account id, for instance) is not an error at all, and would otherwise be committed as if the transfer had actually happened. Making the transaction genuinely safe means checking that each `UPDATE` affected exactly the one row expected and issuing an explicit `ROLLBACK` if either check fails, only issuing `COMMIT` once both checks pass.

Python Async Programming

Why does calling a blocking function inside an async function defeat the purpose of using asyncio?

A blocking call (synchronous file I/O, a synchronous HTTP request, `time.sleep`) occupies the single thread the event loop runs on, and unlike `await`, it does not yield control back, the entire event loop is frozen for the duration of that blocking call, so every other coroutine that could otherwise be making progress is stalled too. This is why async code requires async-compatible libraries throughout the I/O path; a single accidental blocking call anywhere in a hot path can silently serialize what was supposed to be concurrent work, and the bug often doesn't show up until real concurrent load exposes it.

Python Virtual Environments & Packaging

Why does installing packages globally (outside a virtual environment) cause problems across multiple projects?

A global Python installation has exactly one set of installed package versions shared by everything that uses it. Two projects needing different, incompatible versions of the same package (one needs `requests==2.28`, another needs `requests==2.31` for a bug fix it depends on) cannot both be satisfied globally, installing one breaks the other. A virtual environment gives each project its own isolated package set, so version requirements never conflict across projects, and a project's dependencies are fully reproducible independent of whatever else happens to be installed globally.

Recursion & the Call Stack

Python's own documentation warns that raising the recursion limit "should be done with care, because a too-high limit can lead to a crash." Why doesn't raising the limit simply allow deeper, safe recursion?

The recursion limit is a proxy for the real constraint, actual available C stack space, which is platform-dependent and finite regardless of what the configured limit says. Setting the limit higher than the platform's actual available stack can support doesn't create more stack space, it just removes the early warning that would have raised a clean `RecursionError`, so recursion can now run deep enough to exhaust the real stack and crash the process with a low-level segmentation fault instead, a worse failure mode than the exception the limit was preventing in the first place.

Testing Python with pytest

What is a pytest fixture, and what problem does it solve compared to manual setup/teardown?

A fixture is a function decorated with `@pytest.fixture` that provides a reusable piece of test setup (a database connection, a temp directory, a configured client) which pytest automatically injects into any test function that declares it as a parameter. It solves the same problem as `unittest`'s `setUp`/`tearDown` methods, but as small, composable, independently reusable functions rather than one monolithic method per test class, a test can request exactly the fixtures it needs, and fixtures can depend on other fixtures, building up complex setup from simple, testable pieces.

Search results for “bicep” | Cloud Tech by Victor