Search
30 results for “terraform”
Search results
Terraform Basics
How Terraform's declarative state model, providers, and plan/apply workflow let infrastructure be versioned and reviewed like code, and the state pitfalls that trip up most teams.
Terraform Azure Tutorial: How to Create Resource Groups, VNets, Subnets, NSGs, and VMs Step‑by‑Step IaC
Terraform on Azure: Building a Real-World Infrastructure from Scratch.
Terraform vs Ansible
Terraform provisions infrastructure and Ansible configures it. How the two tools differ in model, state, and strengths, and how they pair.
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.
Why does GitOps improve auditability compared to engineers running kubectl or terraform apply directly?
Every change to cluster state has to go through a Git commit, which means it inherits Git's existing history, authorship, and (if branch protection is configured) pull-request review, automatically. Direct `kubectl apply` access leaves no equivalent trail: two changes with the same effect are indistinguishable, there's no required review step, and reconstructing "who changed what and why" after an incident means digging through cluster event logs instead of reading a linear, reviewed commit history.
At what point in the Terraform workflow are Sentinel (or similar policy-as-code) checks evaluated, and why does that timing matter?
Policy checks evaluate against the plan, the output of `terraform plan`, before `terraform apply` actually provisions anything, which means a policy violation blocks the run from proceeding to apply at all. Evaluating against the plan rather than the already-applied state is what makes this a preventive control instead of a detective one; the non-compliant resource is stopped before it exists, not flagged for cleanup afterward once it's already live and potentially already been exploited or has already incurred cost.
Why is scanning IaC source (Terraform files) not sufficient on its own, without also checking the plan?
Static scanning of Terraform source can catch some misconfigurations (a hardcoded insecure default) but can't see values that only exist after variables, data sources, and module composition are actually resolved, an insecure setting could depend on a variable supplied at runtime that static source scanning alone can't evaluate. The plan is the fully resolved, concrete set of resources Terraform is actually about to create or change, which is why policy-as-code tools evaluate the plan, not just the source, as the authoritative point to check against before anything is provisioned.
What is Terraform state and why is it required?
State is a JSON file (by default `terraform.tfstate`) that maps every resource block in your configuration to the real-world object Terraform created for it (an AWS instance ID, a DNS record, etc.). Terraform is declarative, your config describes the desired end state, not the steps to get there, so on every run it needs state to compute a diff between what exists now and what the config says should exist. Without state, Terraform would have no way to know whether a resource already exists, needs updating, or was deleted outside of Terraform.
Why is storing Terraform state locally a problem for a team, and what is the standard fix?
Local state is a single file on one person's machine, a second engineer running `terraform apply` has no idea what the first one already created, so both can independently "discover" no matching state and try to recreate resources, or worse, apply conflicting changes concurrently with no locking. The standard fix is a remote backend (S3+DynamoDB, Terraform Cloud, GCS, Azure Blob) that stores state centrally and supports locking, so only one apply can run at a time and everyone reads the same source of truth.
What is the difference between terraform plan and terraform apply, and why does that separation matter?
`plan` computes and displays the diff between current state and desired config without changing anything; it is a dry run. `apply` executes that diff against real infrastructure. Separating them means a human (or a CI approval gate) can review exactly what will be created, changed, or destroyed before anything actually happens, which is the core safety mechanism that makes infrastructure-as-code safer than manually clicking through a cloud console, nothing changes without a reviewed, explicit plan.
Building a Production-Ready AKS GitOps Platform with Terraform and ArgoCD
The DevOps Project That Finally Made Kubernetes, GitOps, and Terraform Click
How to Build a Production-Ready Auto-Scaling Azure Web App with Modular Terraform (VMSS, Load Balancer & NAT Gateway)
From Basic Terraform to Production IaC: Building an Auto-Scaling Azure Web App with Modular Terraform.
Infrastructure as Code Security
How policy-as-code catches a non-compliant infrastructure change at the plan stage, before anything is provisioned, and why that timing is what makes it a real control rather than a post-incident audit trail.
What problem does policy-as-code solve that a manual infrastructure change review does not?
A manual review depends on a human noticing a specific misconfiguration, an open security group, an unencrypted storage bucket, in a plan diff that may span hundreds of resources, and that scrutiny has to be repeated consistently by every reviewer on every change. Policy-as-code encodes the same rule once as executable logic and runs it automatically against every plan, so an overly permissive security group is caught the same way on the hundredth change as the first, without depending on which reviewer happened to be paying attention that day.
In a systemd unit, what is the practical difference between Type=simple and Type=forking, and why does that distinction matter for dependency ordering?
With Type=simple, systemd considers the unit started the moment the main process is forked off, it does not wait for the application to finish its own initialization, so anything depending on that unit might start before the service is actually ready to handle requests. Type=forking expects the traditional daemon pattern, the initial process forks and exits once it judges its own startup complete, so systemd marks the unit started as soon as that original process exits successfully, while the actual daemon keeps running as a separate, now-orphaned process. That only tracks the daemonization handoff, not genuine application readiness, a process can exit believing setup is done while it is still finishing initialization in the background, so Type=forking is a better signal than Type=simple but still not a readiness guarantee. Type=notify is the one that actually is readiness-safe: the service explicitly calls sd_notify to tell systemd exactly when it's ready, rather than systemd inferring readiness from process exit behavior at all.
What does it mean for a sorting algorithm to be "stable," and why does that matter for sorting by multiple keys in separate passes?
A stable sort guarantees that when two elements compare as equal under the current sort key, their original relative order is preserved rather than left unspecified. This matters directly for multi-key sorting done as a series of single-key sorts: sort by a secondary key first, then stably sort by the primary key, and elements sharing the same primary key retain their secondary-key order from the first pass, correctly producing a combined sort by (primary, secondary) without needing a single comparator that handles both keys at once. An unstable sort would silently scramble that secondary ordering among equal-primary-key elements.
What does hashed sharding trade away in exchange for fixing the monotonic-key hot-shard problem?
Hashed sharding computes a hash of the shard key value and assigns chunks by hash range instead of by the raw value, which scatters even monotonically increasing keys roughly evenly across shards, since consecutive input values hash to essentially unrelated output values. The trade-off is range-query locality: a query filtering a range of the original shard key values (like "the last 24 hours" on a timestamp key) can no longer be routed to one contiguous set of shards, because the corresponding hashed values are scattered unpredictably across the whole cluster, turning what would have been a single-shard query under range sharding into a broadcast query touching every shard.
GitOps Principles
Why treating Git as the single source of truth for cluster state, instead of running kubectl/terraform apply by hand, changes how deployments, rollbacks, and audits actually work.
What does the Kubernetes control loop actually do?
Every Kubernetes controller (Deployment, ReplicaSet, etc.) runs a reconciliation loop: it continuously compares the desired state (what you declared in a manifest, stored in etcd) against the observed actual state of the cluster, and takes action to close any gap. If you declared 3 replicas and only 2 Pods are running, the ReplicaSet controller creates one more. This is the same declarative, converge-toward-desired-state model as Terraform, but running continuously and automatically rather than on-demand.
What is an Internal Developer Platform (IDP), concretely?
An IDP is the layer, often a combination of a self-service portal/CLI, templated infrastructure (via Terraform modules, Kubernetes operators, or similar), and standardized CI/CD pipelines, that lets a product engineer provision what they need (a new service, a database, a queue) without filing a ticket or becoming an expert in the underlying infrastructure. It sits between raw cloud/Kubernetes primitives and the product engineers who need to consume them, and its quality is measured the same way any product's is: by whether its users (internal engineers) actually prefer using it over working around it.
Why does explicitly telling a model it's allowed to say "I don't know" measurably reduce hallucination, and what's a second, complementary technique for the same problem?
Without that explicit permission, a model under an implicit expectation to always produce a confident, complete answer will sometimes fill a real information gap with a plausible-sounding but fabricated one; stating outright that uncertainty is an acceptable answer removes that pressure and lets the model surface "I don't have enough information" instead of guessing. A complementary technique for long documents is asking the model to first extract direct, word-for-word quotes relevant to the task before generating any analysis, grounding its response in verifiable text it actually has in front of it, and then citing which quote supports each claim, rather than generating an answer freely and hoping it stayed faithful to the source.
A banking system typically favors CP behavior during a partition, while a chat application typically favors AP. What does each system actually do differently when a partition occurs, and why does the choice fit each use case?
A CP system, during a partition, pauses or rejects requests that can't be guaranteed consistent, a bank stopping a transfer rather than risking two nodes independently approving withdrawals against the same balance, since a duplicated or lost transaction is a correctness failure worse than a temporary outage. An AP system keeps responding during the partition, accepting the risk of temporarily inconsistent state, a chat app still accepting and displaying messages on both sides of a network split, reconciling them once the partition heals, because staying available and eventually consistent matters more to users than every message reappearing everywhere in a strict, immediate order.
If a microtask itself queues another microtask while it's running, does that new microtask wait for the next event loop iteration, or does it still run before the next macrotask?
It still runs before the next macrotask. The rule isn't "run the microtasks that were queued when this iteration started", it's "drain the microtask queue completely," and if executing a microtask adds another one, that new one is still part of the queue being drained. This means a chain of microtasks that keep scheduling more microtasks can, in principle, starve the event loop from ever reaching the next macrotask (a real, documented way to accidentally block timers and rendering), which is different from a single flat batch of microtasks all queued up front.
What is the difference between GROUP BY aggregation and a window function like `ROW_NUMBER() OVER (...)`?
`GROUP BY` collapses every row in a group into a single output row per group, you lose access to the individual rows once you've aggregated. A window function computes its result (a rank, a running total, a row number) per row while keeping every individual row in the output, `PARTITION BY` defines the grouping for that calculation, but nothing is collapsed. This is why "give me each order plus that customer's running total" needs a window function, while "give me one row per customer with their total" is a plain `GROUP BY`.
What do LCP, INP, and CLS each measure, and why are all three needed instead of one overall "speed" number?
LCP (Largest Contentful Paint) measures loading performance, specifically how quickly the largest visible element renders, "good" is 2.5 seconds or less. INP (Interaction to Next Paint) measures interactivity/responsiveness, the delay between a user interaction and the browser's next visual response, "good" is 200 milliseconds or less. CLS (Cumulative Layout Shift) measures visual stability, how much content unexpectedly shifts around during the page's lifecycle, "good" is a score of 0.1 or less. A single overall number couldn't distinguish a page that loads fast but jumps around from one that's stable but slow to interact with, three separate metrics are needed because loading, interactivity, and stability are genuinely different failure modes.
What is an "LLM-graded" eval, and when would you reach for it instead of exact-match or similarity-based grading?
An LLM-graded eval uses a separate model call to judge a subjective quality of the output, tone, empathy, professionalism, on a numeric scale or binary classification, rather than checking it against one fixed correct answer. Exact-match grading only works when there's one right answer (a category label); similarity-based grading (cosine similarity between embeddings) works when wording can vary but meaning should match a reference. LLM-graded evals are the right tool specifically for qualities that are inherently subjective and hard to define with a fixed rule or reference string, at the cost of being noisier and more expensive to run than a simple string comparison.
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.
What does AKS (Azure Kubernetes Service) manage for you compared to running Kubernetes yourself on VMs?
AKS manages the Kubernetes control plane (API server, etcd, scheduler) at no direct cost for the control plane itself; you only pay for the worker nodes, which still run as VMs you have some visibility into but don't have to manually install or upgrade Kubernetes onto. Running Kubernetes yourself on plain VMs means standing up and maintaining the entire control plane, including its high availability and upgrade process, which is a substantial and ongoing operational burden. AKS trades some control-plane visibility for removing that burden, which is why it's the default choice for running Kubernetes on Azure unless there's a specific reason to self-manage.
Why does reusing the same idempotency key with different request parameters return an error instead of just processing the new parameters?
An idempotency key is a promise that a specific, exact operation happened once; if the same key showed up with different parameters, honoring the new parameters would silently violate that promise; either the original operation's recorded result no longer describes what the key represents, or the client made a mistake by rIeusing a key it should have generated fresh for a genuinely different request. Rejecting the mismatched reuse as an error, rather than guessing which parameters were "correct" or silently processing the new ones, surfaces that client-side mistake immediately instead of masking it.
Why would a system use a sliding window rate limiter instead of a token bucket, and what problem does it fix?
A naive fixed window (say, "100 requests per minute, resetting on the minute") allows a client to send 100 requests in the last second of one window and another 100 in the first second of the next, 200 requests in a two-second span despite the stated 100/minute limit, an artifact of the window boundary rather than actual demand. A sliding window rate limiter instead evaluates the limit over a continuously moving time range rather than fixed, discrete buckets, which avoids that boundary-doubling effect at the cost of typically more state to track (timestamps of recent requests, not just a single counter) compared to a token bucket's simpler accumulator model.