{"id":30288,"date":"2026-01-06T14:41:45","date_gmt":"2026-01-06T09:11:45","guid":{"rendered":"https:\/\/opstree.com\/blog\/?p=30288"},"modified":"2026-01-06T14:53:17","modified_gmt":"2026-01-06T09:23:17","slug":"terraform-with-s3-and-dynamodb","status":"publish","type":"post","link":"https:\/\/opstree.com\/blog\/2026\/01\/06\/terraform-with-s3-and-dynamodb\/","title":{"rendered":"Terraform state locking with S3 and DynamoDB explained"},"content":{"rendered":"<h2 id=\"introduction\" aria-level=\"2\"><b><span data-contrast=\"auto\">Introduction<\/span><\/b><span data-ccp-props=\"{&quot;134245418&quot;:true,&quot;335559738&quot;:200,&quot;335559739&quot;:120}\">\u00a0<\/span><\/h2>\n<p><span data-contrast=\"auto\">When managing infrastructure-as-code using Terraform, the\u2002state file is a key\u00a0component, as it keeps track of what resources are associated with your\u00a0configuration and how they are configured relative to one another. Teams will suffer from corrupted state and conflicting updates if they are left on their own to store and coordinate\u00a0state.As\u00a0teams compete for overall dominance, resources are neglected.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><!--more--><\/p>\n<p><span data-contrast=\"auto\">One of the primary mechanics to prevent these issues is state locking \u2013 making it so that only one Terraform operation can\u00a0modify\u00a0state\u2002at a time. On\u2002AWS\u00a0this used to be done by using <a href=\"https:\/\/opstree.com\/blog\/2024\/11\/05\/amazon-s3-security-essentials-protect-your-data-with-these-key-practices\/\" target=\"_blank\" rel=\"noopener\">Amazon S3<\/a> (for the state file) and DynamoDB (for the lock). Terraform itself\u2002has also now added native S3 lock support, so you no longer need a DynamoDB table for locking.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/p>\n<p><!-- ===== TABLE OF CONTENTS START ===== --><\/p>\n<div style=\"background: #f8fafc; padding: 18px; border: 1px solid #e2e8f0; border-radius: 6px; font-family: Inter, Arial, sans-serif; margin: 20px 0;\">\n<h2 style=\"margin-top: 0; font-size: 18px;\">Table of Contents<\/h2>\n<ol style=\"margin: 0; padding-left: 18px; line-height: 1.6;\">\n<li><a style=\"text-decoration: none; color: #2563eb;\" href=\"#introduction\">Introduction<br \/>\n<\/a><\/li>\n<li><a style=\"text-decoration: none; color: #2563eb;\" href=\"#what-is-state-locking\">What Is State Locking and Why Does It Matter?<br \/>\n<\/a><\/li>\n<li><a style=\"text-decoration: none; color: #2563eb;\" href=\"#old-method-s3-dynamodb\">The \u201cOld\u201d Method: S3 + DynamoDB Locking<br \/>\n<\/a><\/li>\n<li><a style=\"text-decoration: none; color: #2563eb;\" href=\"#new-method-s3-native-locking\">The \u201cNew\u201d Method: Native S3 State Locking<br \/>\n<\/a><\/li>\n<li><a style=\"text-decoration: none; color: #2563eb;\" href=\"#side-by-side-comparison\">Side-by-Side Comparison<br \/>\n<\/a><\/li>\n<li><a style=\"text-decoration: none; color: #2563eb;\" href=\"#why-this-change-matters\">Why This Change Matters<br \/>\n<\/a><\/li>\n<li><a style=\"text-decoration: none; color: #2563eb;\" href=\"#when-not-to-switch\">When Should You Not Switch (Yet)?<br \/>\n<\/a><\/li>\n<li><a style=\"text-decoration: none; color: #2563eb;\" href=\"#next-steps\">Next Steps for Readers<br \/>\n<\/a><\/li>\n<li><a style=\"text-decoration: none; color: #2563eb;\" href=\"#conclusion\">Conclusion<br \/>\n<\/a><\/li>\n<li><a style=\"text-decoration: none; color: #2563eb;\" href=\"#faqs\">Frequently Asked Questions<\/a><\/li>\n<\/ol>\n<\/div>\n<h2 id=\"what-is-state-locking\" aria-level=\"2\"><b><span data-contrast=\"auto\">What is state locking\u00a0 and why does it matter?<\/span><\/b><span data-ccp-props=\"{&quot;134245418&quot;:true,&quot;335559738&quot;:200,&quot;335559739&quot;:120}\">\u00a0<\/span><\/h2>\n<ul>\n<li><span data-contrast=\"auto\">Terraform keeps its model of your infrastructure in\u2002a state file (usually\u00a0<\/span><b><span data-contrast=\"auto\">terraform.tfstate<\/span><\/b><span data-contrast=\"auto\">). The file tracks resource IDs, attributes,\u2002dependencies, and much more.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<li><span data-contrast=\"auto\">When different people or CI\/CD processes share a remote state, however,\u00a0there\u2019s\u00a0no coordination between\u00a0them\u00a0so\u2002they may both apply changes at the same time. That can lead to:<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<\/ul>\n<p><span data-contrast=\"auto\">\u00a0 &#8211; both read the same old value, update it in conflicting\u2002ways.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">\u00a0 &#8211; one write overwriting another\u2019s changes<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">\u00a0 &#8211; corrupted or failed\u2002leading to the potential of drift or worse.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/p>\n<ul>\n<li aria-setsize=\"-1\" data-leveltext=\"\u2022\" data-font=\"OpenSymbol\" data-listid=\"2\" data-list-defn-props=\"{&quot;335551671&quot;:0,&quot;335552541&quot;:1,&quot;335559685&quot;:709,&quot;335559991&quot;:283,&quot;469769226&quot;:&quot;OpenSymbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\u2022&quot;,&quot;469777815&quot;:&quot;multilevel&quot;}\" data-aria-posinset=\"2\" data-aria-level=\"1\"><span data-contrast=\"auto\">By the law of State locking A State lock prevents concurrent writes: the first process &#8220;acquires&#8221; a lock, reads state, applies changes to it, then\u2002write back state and &#8220;releases&#8221; the lock. Still others wait or they don\u2019t, and die when the lock does.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<li aria-setsize=\"-1\" data-leveltext=\"\u2022\" data-font=\"OpenSymbol\" data-listid=\"2\" data-list-defn-props=\"{&quot;335551671&quot;:0,&quot;335552541&quot;:1,&quot;335559685&quot;:709,&quot;335559991&quot;:283,&quot;469769226&quot;:&quot;OpenSymbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\u2022&quot;,&quot;469777815&quot;:&quot;multilevel&quot;}\" data-aria-posinset=\"2\" data-aria-level=\"1\"><span data-contrast=\"auto\">When working in a team environment (with multiple engineers, or\u2002automated pipelines) state locking is not optional if you want\u00a0secure, repeatable infrastructure changes.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<\/ul>\n<div style=\"border: 1px solid #d1d5db; padding: 16px; margin: 20px 0; background-color: #f0f4f8;\">\n<p style=\"margin: 0; font-weight: 600; font-size: 16px;\">Are you looking for <a href=\"https:\/\/opstree.com\/services\/database-and-data-engineering\/\">data engineering solutions<\/a> that scale while aligning technical execution with real business outcomes?<\/p>\n<\/div>\n<h2 id=\"old-method-s3-dynamodb\" aria-level=\"2\"><b><span data-contrast=\"auto\">The \u201cold\u201d method: S3 + DynamoDB locking<\/span><\/b><span data-ccp-props=\"{&quot;134245418&quot;:true,&quot;335559738&quot;:200,&quot;335559739&quot;:120}\">\u00a0<\/span><\/h2>\n<h3 aria-level=\"3\"><b><span data-contrast=\"auto\">How it worked<\/span><\/b><span data-ccp-props=\"{&quot;134245418&quot;:true,&quot;335559738&quot;:140,&quot;335559739&quot;:120}\">\u00a0<\/span><\/h3>\n<ul>\n<li><span data-contrast=\"auto\">S3 is\u00a0utilised\u00a0as the remote backend: Terraform uses a designated S3 bucket and key to store\u00a0terraform.tfstate\u00a0(as well as potentially workspace-specific variations).<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<li><span data-contrast=\"auto\">You use a partition key like\u00a0LockID\u00a0to generate a DynamoDB table (like terraform-locks).<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<li><span data-contrast=\"auto\">In your backend configuration you specify something like:<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<\/ul>\n<p><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\"> <img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-30289 size-large\" src=\"https:\/\/opstree.com\/blog\/wp-content\/uploads\/2026\/01\/10000001000004AB000000CD50698871-1024x176.png\" alt=\"\" width=\"840\" height=\"144\" srcset=\"https:\/\/opstree.com\/blog\/wp-content\/uploads\/2026\/01\/10000001000004AB000000CD50698871-1024x176.png 1024w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2026\/01\/10000001000004AB000000CD50698871-300x51.png 300w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2026\/01\/10000001000004AB000000CD50698871-768x132.png 768w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2026\/01\/10000001000004AB000000CD50698871.png 1195w\" sizes=\"(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><\/span><\/p>\n<ul>\n<li aria-setsize=\"-1\" data-leveltext=\"\u2022\" data-font=\"OpenSymbol\" data-listid=\"3\" data-list-defn-props=\"{&quot;335551671&quot;:0,&quot;335552541&quot;:1,&quot;335559685&quot;:709,&quot;335559991&quot;:283,&quot;469769226&quot;:&quot;OpenSymbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\u2022&quot;,&quot;469777815&quot;:&quot;multilevel&quot;}\" data-aria-posinset=\"3\" data-aria-level=\"1\"><span data-contrast=\"auto\">At run time:<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<\/ul>\n<ol>\n<li><span data-contrast=\"auto\"><a href=\"https:\/\/opstree.com\/blog\/2020\/03\/18\/terraform-workspace-multiple-environment\/\" target=\"_blank\" rel=\"noopener\">Terraform<\/a> writes an entry in DynamoDB (conditional write) in an attempt to obtain the lock.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<li><span data-contrast=\"auto\">If it is successful, it reads the state from S3, calculates the plan, and\u00a0makes adjustments.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<li><span data-contrast=\"auto\">Terraform updates S3 with the new state.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<li><span data-contrast=\"auto\">Terraform\u00a0deletes\u00a0the DynamoDB item to release the lock.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<li><span data-contrast=\"auto\">Another\u00a0process will either fail or wait if it tries while the lock is in place.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<\/ol>\n<h3 aria-level=\"3\"><b><span data-contrast=\"auto\">Strengths<\/span><\/b><span data-ccp-props=\"{&quot;134245418&quot;:true,&quot;335559738&quot;:140,&quot;335559739&quot;:120}\">\u00a0<\/span><\/h3>\n<ul>\n<li><span data-contrast=\"auto\">Great: DynamoDB\u2002offers strong consistency and conditional writes, you can implement robust locking<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<li><span data-contrast=\"auto\">Ideal for larger teams or\u2002high concurrency workflows.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<li><span data-contrast=\"auto\">Known and accepted practice.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<\/ul>\n<h3 aria-level=\"3\"><b><span data-contrast=\"auto\">Limitations<\/span><\/b><span data-ccp-props=\"{&quot;134245418&quot;:true,&quot;335559738&quot;:140,&quot;335559739&quot;:120}\">\u00a0<\/span><\/h3>\n<ul>\n<li><span data-contrast=\"auto\">Needs\u2002one more\u00a0AWS\u00a0resource (the DynamoDB table) to configure,\u00a0maintain, secure and cost-control.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<li><span data-contrast=\"auto\">That\u2019s\u00a0more IAM permissions to grant (in S3 and\u2002DynamoDB) and more moving parts.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<li><span data-contrast=\"auto\">A bit more complicated to bootstrap\u2002(create bucket, table), and\u00a0migrate from\u00a0local-state.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<li><span data-contrast=\"auto\">Locks can become orphaned and need to be manually unlocked if mis-configured\u2002(timeout, permissions).<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<\/ul>\n<div style=\"border: 1px solid #d1d5db; padding: 16px; margin: 20px 0; background-color: #f0f4f8;\">\n<p style=\"margin: 0; font-weight: 600; font-size: 16px;\">Case Study : <a href=\"https:\/\/opstree.com\/case-study\/27-aws-cost-reduction-through-database-optimization-for-a-fintech-platform\/\" target=\"_blank\" rel=\"noopener\">27% AWS Cost Reduction Through Database Optimization for a Fintech Platform<\/a><\/p>\n<\/div>\n<h2 id=\"new-method-s3-native-locking\" aria-level=\"2\"><b><span data-contrast=\"auto\">The \u201cnew\u201d method: Native S3 state locking<\/span><\/b><span data-ccp-props=\"{&quot;134245418&quot;:true,&quot;335559738&quot;:200,&quot;335559739&quot;:120}\">\u00a0<\/span><\/h2>\n<h3 aria-level=\"3\"><b><span data-contrast=\"auto\">What changed<\/span><\/b><span data-ccp-props=\"{&quot;134245418&quot;:true,&quot;335559738&quot;:140,&quot;335559739&quot;:120}\">\u00a0<\/span><\/h3>\n<ul>\n<li><span data-contrast=\"auto\">For terraform, the backend S3 now has a new setting\u00a0<\/span><b><span data-contrast=\"auto\">use_lockfile\u00a0= true<\/span><\/b><span data-contrast=\"auto\">\u00a0that\u00a0allows to\u00a0lock in\u00a0<\/span><b><span data-contrast=\"auto\">s3 only<\/span><\/b><span data-contrast=\"auto\">.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<li><span data-contrast=\"auto\">Now, you\u00a0don\u2019t\u00a0have to rely on a\u2002DynamoDB table for locking \u2013 Terraform has an S3 object (a \u201clock file\u201d, like `\u2026\/terraform.\u00a0tfstate.\u00a0tflock) for coordination.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<li><span data-contrast=\"auto\">This is now justifiable as S3 now has stronger consistency guarantees (read-after-write) and\u2002conditional writes (so \u201conly create this lock object if it doesn\u2019t already exist\u201d).<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<\/ul>\n<h3 aria-level=\"3\"><b><span data-contrast=\"auto\">How it works<\/span><\/b><span data-ccp-props=\"{&quot;134245418&quot;:true,&quot;335559738&quot;:140,&quot;335559739&quot;:120}\">\u00a0<\/span><\/h3>\n<ul>\n<li aria-setsize=\"-1\" data-leveltext=\"\u2022\" data-font=\"OpenSymbol\" data-listid=\"7\" data-list-defn-props=\"{&quot;335551671&quot;:0,&quot;335552541&quot;:1,&quot;335559685&quot;:709,&quot;335559991&quot;:283,&quot;469769226&quot;:&quot;OpenSymbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\u2022&quot;,&quot;469777815&quot;:&quot;multilevel&quot;}\" data-aria-posinset=\"0\" data-aria-level=\"1\"><span data-contrast=\"auto\">In your backend config:<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<\/ul>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-30290 size-large\" src=\"https:\/\/opstree.com\/blog\/wp-content\/uploads\/2026\/01\/10000001000004AB000000CD9B30F5A1-1024x176.png\" alt=\"\" width=\"840\" height=\"144\" srcset=\"https:\/\/opstree.com\/blog\/wp-content\/uploads\/2026\/01\/10000001000004AB000000CD9B30F5A1-1024x176.png 1024w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2026\/01\/10000001000004AB000000CD9B30F5A1-300x51.png 300w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2026\/01\/10000001000004AB000000CD9B30F5A1-768x132.png 768w, https:\/\/opstree.com\/blog\/wp-content\/uploads\/2026\/01\/10000001000004AB000000CD9B30F5A1.png 1195w\" sizes=\"(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><\/p>\n<ul>\n<li aria-setsize=\"-1\" data-leveltext=\"\u2022\" data-font=\"OpenSymbol\" data-listid=\"7\" data-list-defn-props=\"{&quot;335551671&quot;:0,&quot;335552541&quot;:1,&quot;335559685&quot;:709,&quot;335559991&quot;:283,&quot;469769226&quot;:&quot;OpenSymbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\u2022&quot;,&quot;469777815&quot;:&quot;multilevel&quot;}\" data-aria-posinset=\"1\" data-aria-level=\"1\"><span data-contrast=\"auto\">At runtime:<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<\/ul>\n<ol>\n<li><span data-contrast=\"auto\">Terraform attempts to lock\u2002with the creation of a lock object (path\/to\/terraform.\u00a0tfstate.\u00a0tflock) in the same S3 bucket with a unique name and conditional write \u201ccreate\u2002only if not exists\u201d.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<li><span data-contrast=\"auto\">If the creation\u00a0completed\u2002 lock\u00a0obtained.\u00a0Otherwise\u00a0the lock is held by\u2002a different\u00a0process, and\u00a0Terraform either waits or exits with failure.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<li><span data-contrast=\"auto\">Terraform pulls down\u00a0state\u00a0file from the S3 bucket, calculates a\u00a0plan\u00a0and then makes changes.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<li><span data-contrast=\"auto\">Terraform writes the new state\u2002to the S3 object at the location given by key.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<li><span data-contrast=\"auto\">Terraform removes\u2002the lock\u00a0file (<\/span><b><span data-contrast=\"auto\">.\u00a0tflock\u00a0object<\/span><\/b><span data-contrast=\"auto\">) to unlock the\u2002lock.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<li><span data-contrast=\"auto\">Should the process fail without a chance to\u00a0delete\u00a0the lock file you might have\u2002do\u00a0it yourself (e.g., terraform force-unlock).<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<\/ol>\n<h3 aria-level=\"3\"><b><span data-contrast=\"auto\">Benefits<\/span><\/b><span data-ccp-props=\"{&quot;134245418&quot;:true,&quot;335559738&quot;:140,&quot;335559739&quot;:120}\">\u00a0<\/span><\/h3>\n<ul>\n<li><span data-contrast=\"auto\">Simplified architecture: Only S3, no DynamoDB\u2002table, fewer moving pieces.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<li><span data-contrast=\"auto\">Less expensive, fewer resources to\u2002track and\u00a0maintain.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<li><span data-contrast=\"auto\">Simpler configuration, less IAM permissions to set\u2002up.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<li><span data-contrast=\"auto\">Particularly appealing for smaller teams or installations with fewer bells\u2002and whistles.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<\/ul>\n<h3 aria-level=\"3\"><b><span data-contrast=\"auto\">Considerations<\/span><\/b><span data-ccp-props=\"{&quot;134245418&quot;:true,&quot;335559738&quot;:140,&quot;335559739&quot;:120}\">\u00a0<\/span><\/h3>\n<ul>\n<li><span data-contrast=\"auto\">Because the\u2002feature is relatively new, you will want to thoroughly validate it in your environment , especially if you have high concurrency or complex automation pipelines.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<li><span data-contrast=\"auto\">You still must make sure that your S3 bucket is properly configured (versioning, encryption, permissions) because the state\u2002file is still important.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<li><span data-contrast=\"auto\">You&#8217;ll\u00a0also need to\u2002manually deal with the unlocking if locks get orphaned (the lock flag\u00a0doesn&#8217;t\u00a0get removed).<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<li><span data-contrast=\"auto\">Bigger organizations who already use DynamoDB locking might need a\u2002migration path of some kind.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<\/ul>\n<h2 id=\"side-by-side-comparison\" aria-level=\"2\"><b><span data-contrast=\"auto\">Side-by-side comparison<\/span><\/b><span data-ccp-props=\"{&quot;134245418&quot;:true,&quot;335559738&quot;:200,&quot;335559739&quot;:120}\">\u00a0<\/span><\/h2>\n<p><span data-contrast=\"auto\">Here is a practical comparison to help you\u00a0decide between the two approaches:<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/p>\n<div style=\"overflow-x: auto; width: 100%; margin: 20px 0;\">\n<table style=\"width: 100%; min-width: 700px; border-collapse: collapse; border: 1px solid #e5e7eb; font-size: 14px;\">\n<thead>\n<tr style=\"background: #f8fafc;\">\n<th style=\"border: 1px solid #e5e7eb; padding: 12px; text-align: left;\">Feature<\/th>\n<th style=\"border: 1px solid #e5e7eb; padding: 12px; text-align: left;\">S3 + DynamoDB (Legacy)<\/th>\n<th style=\"border: 1px solid #e5e7eb; padding: 12px; text-align: left;\">S3 Native Locking<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"border: 1px solid #e5e7eb; padding: 12px;\">Lock storage<\/td>\n<td style=\"border: 1px solid #e5e7eb; padding: 12px;\">DynamoDB item<\/td>\n<td style=\"border: 1px solid #e5e7eb; padding: 12px;\">.tflock object in S3 bucket<\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1px solid #e5e7eb; padding: 12px;\">Additional AWS resource<\/td>\n<td style=\"border: 1px solid #e5e7eb; padding: 12px;\">Yes \u2013 DynamoDB table<\/td>\n<td style=\"border: 1px solid #e5e7eb; padding: 12px;\">No (S3 only)<\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1px solid #e5e7eb; padding: 12px;\">Setup complexity<\/td>\n<td style=\"border: 1px solid #e5e7eb; padding: 12px;\">Higher<\/td>\n<td style=\"border: 1px solid #e5e7eb; padding: 12px;\">Lower<\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1px solid #e5e7eb; padding: 12px;\">Cost<\/td>\n<td style=\"border: 1px solid #e5e7eb; padding: 12px;\">Extra cost for DynamoDB reads\/writes<\/td>\n<td style=\"border: 1px solid #e5e7eb; padding: 12px;\">Minimal (just S3 operations)<\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1px solid #e5e7eb; padding: 12px;\">Dependencies \/ maintenance<\/td>\n<td style=\"border: 1px solid #e5e7eb; padding: 12px;\">More moving parts<\/td>\n<td style=\"border: 1px solid #e5e7eb; padding: 12px;\">Fewer dependencies<\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1px solid #e5e7eb; padding: 12px;\">Maturity \/ adoption<\/td>\n<td style=\"border: 1px solid #e5e7eb; padding: 12px;\">Long-established<\/td>\n<td style=\"border: 1px solid #e5e7eb; padding: 12px;\">Relatively newer<\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1px solid #e5e7eb; padding: 12px;\">Ideal for<\/td>\n<td style=\"border: 1px solid #e5e7eb; padding: 12px;\">Large teams \/ high concurrency<\/td>\n<td style=\"border: 1px solid #e5e7eb; padding: 12px;\">Smaller teams \/ simpler workflows<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<h2 id=\"why-this-change-matters\" aria-level=\"2\"><b><span data-contrast=\"auto\">Why this change matters<\/span><\/b><span data-ccp-props=\"{&quot;134245418&quot;:true,&quot;335559738&quot;:200,&quot;335559739&quot;:120}\">\u00a0<\/span><\/h2>\n<ul>\n<li><b><span data-contrast=\"auto\">Operational overhead:\u00a0<\/span><\/b><span data-contrast=\"auto\">Less <a href=\"https:\/\/opstree.com\/aws-partner\/\" target=\"_blank\" rel=\"noopener\">AWS services<\/a> and IAM roles\u00a0leads\u00a0to more simple\u00a0setups, fewer mistakes, and less\u2002operational burden.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<li><b><span data-contrast=\"auto\">Cost Effectiveness:<\/span><\/b><span data-contrast=\"auto\">\u00a0Save from DynamoDB Table operations (even though\u00a0its\u00a0very minimal)\u2002and\u00a0it\u2019s\u00a0provisioning\/throughput.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<li><b><span data-contrast=\"auto\">Agility:<\/span><\/b><span data-contrast=\"auto\">\u00a0It reduces friction for teams to\u2002spin-up\u00a0new\u00a0environments(dev\/test).<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<li><b><span data-contrast=\"auto\">Future proofing:<\/span><\/b><span data-contrast=\"auto\">\u00a0Also\u00a0for full\u00a0dislosure, the\u00a0dynamodb_table argument is deprecated\u2002in the S3 backend documentation , so future versions may exclude these.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<li><b><span data-contrast=\"auto\">Migration\u2002signal:\u00a0<\/span><\/b><span data-contrast=\"auto\">For those of you that have been using the old table based locking approach, this would be a good time to consider whether or not it makes sense for you to move over to native S3 locking.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<\/ul>\n<h2 id=\"when-not-to-switch\" aria-level=\"2\"><b><span data-contrast=\"auto\">When should you <\/span><\/b><b><i><span data-contrast=\"auto\">not<\/span><\/i><\/b><b><span data-contrast=\"auto\">\u00a0switch (yet)?<\/span><\/b><span data-ccp-props=\"{&quot;134245418&quot;:true,&quot;335559738&quot;:200,&quot;335559739&quot;:120}\">\u00a0<\/span><\/h2>\n<ul>\n<li><span data-contrast=\"auto\">And if your team has an extremely high degree of concurrent\u2002Terraform operations (or many\u00a0many\u00a0pipelines\/users) and\u00a0you\u2019ve\u00a0already\u00a0optimized\u00a0DynamoDB locking with advanced patterns like timeouts or\u00a0monitoring\u00a0you may still want to stick with the tried-and-true.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<li><span data-contrast=\"auto\">If you\u2002have a complex custom locking logic (across accounts, some external tools that are\u00a0building\u00a0on top of the lock table in DynamoDB) migration could require you some more work.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<li><span data-contrast=\"auto\">If your company\u00a0requires\u00a0full audit\/ logging of lock operations (ie: via DynamoDB logs) , then you\u2019ll\u00a0want to investigate how S3 lock files will work in with\u2002this.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<li><span data-contrast=\"auto\">If\u00a0you\u2019re\u00a0on a version of Terraform that does not yet have complete and native support for S3 locking (versioning,\u2002compatibility).<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<\/ul>\n<h2 id=\"next-steps\" aria-level=\"2\"><b><span data-contrast=\"auto\">Next steps for readers<\/span><\/b><span data-ccp-props=\"{&quot;134245418&quot;:true,&quot;335559738&quot;:200,&quot;335559739&quot;:120}\">\u00a0<\/span><\/h2>\n<ul>\n<li><span data-contrast=\"auto\">Audit your existing Terraform backend config: Are you using\u2002dynamodb_table? Would you be willing to entertain\u00a0use_lockfile\u2002= true?<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<li><span data-contrast=\"auto\">Make\u2002sure your S3 bucket is versioned, encrypted and has good IAM policies (this is important whether\u00a0we\u2019re\u00a0talking\u00a0DynamoDB or native S3).<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<li><span data-contrast=\"auto\">Plan a test migration path: can we try native S3 locking in non-prod,\u00a0observe\u00a0behavior\u00a0etc.Once\u00a0all are\u00a0implemented and the plugin is wired up to use this new architecture. So, if something goes\u2002wrong during implementation, we\u00a0won&#8217;t\u00a0proceed\u00a0to\u00a0next\u00a0step.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<li><span data-contrast=\"auto\">Monitor your\u2002Terraform version and AWS provider version for compatibility checks.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<li><span data-contrast=\"auto\">Keep an eye on your\u00a0team\u2019s workflows\u00a0If\u00a0state locking with native S3 is running properly, plan for full migration to S3\u00a0If\u00a0not, you\u2002may continue using the current approach while evaluating the performance.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<\/ul>\n<h2><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><b><span id=\"conclusion\" data-contrast=\"auto\">Conclusion<\/span><\/b><span data-ccp-props=\"{&quot;134245418&quot;:true,&quot;335559738&quot;:200,&quot;335559739&quot;:120}\">\u00a0<\/span><\/h2>\n<p><span data-contrast=\"auto\">State Locking is\u2002the first principle of\u00a0safe,\u00a0multi-user Terraform usage. The AWS landscape is going to\u00a0change:\u00a0whereas\u00a0one\u00a0needed\u00a0a separate DynamoDB table, henceforth we can\u2002do everything within S3 with native locking. For many companies\u2002that\u00a0translates\u00a0into\u00a0<\/span><b><span data-contrast=\"auto\">reduced complexity, cost saving and easier\u00a0architecturial\u00a0design<\/span><\/b><span data-contrast=\"auto\">. However, the legacy DynamoDB\u2002approach is sturdy and\u00a0understood\u00a0making it a perfectly valid\u00a0option, especially in mature or high-concurrency setups.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/p>\n<h2 aria-level=\"3\"><b><span data-contrast=\"auto\">References &amp; sources<\/span><\/b><span data-ccp-props=\"{&quot;134245418&quot;:true,&quot;335559738&quot;:140,&quot;335559739&quot;:120}\">\u00a0<\/span><\/h2>\n<ul>\n<li aria-setsize=\"-1\" data-leveltext=\"\u2022\" data-font=\"OpenSymbol\" data-listid=\"13\" data-list-defn-props=\"{&quot;335551671&quot;:0,&quot;335552541&quot;:1,&quot;335559685&quot;:709,&quot;335559991&quot;:283,&quot;469769226&quot;:&quot;OpenSymbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\u2022&quot;,&quot;469777815&quot;:&quot;multilevel&quot;}\" data-aria-posinset=\"0\" data-aria-level=\"1\"><b><span data-contrast=\"auto\">Official Terraform documentation: S3 backend \u2013 state locking.<\/span><\/b><br \/>\n<span data-contrast=\"auto\">HashiCorp Developer &#8211; <\/span><a href=\"https:\/\/developer.hashicorp.com\/terraform\/language\/backend\/s3\" target=\"_blank\" rel=\"nofollow noopener\"><span data-contrast=\"auto\">https:\/\/developer.hashicorp.com\/terraform\/language\/backend\/s3<\/span><\/a><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<\/ul>\n<ul>\n<li aria-setsize=\"-1\" data-leveltext=\"\u2022\" data-font=\"OpenSymbol\" data-listid=\"13\" data-list-defn-props=\"{&quot;335551671&quot;:0,&quot;335552541&quot;:1,&quot;335559685&quot;:709,&quot;335559991&quot;:283,&quot;469769226&quot;:&quot;OpenSymbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\u2022&quot;,&quot;469777815&quot;:&quot;multilevel&quot;}\" data-aria-posinset=\"1\" data-aria-level=\"1\"><b><span data-contrast=\"auto\">Terraform backend configuration overview.<\/span><\/b><br \/>\n<span data-contrast=\"auto\">HashiCorp Developer &#8211; <\/span><a href=\"https:\/\/developer.hashicorp.com\/terraform\/language\/backend\" target=\"_blank\" rel=\"nofollow noopener\"><span data-contrast=\"auto\">https:\/\/developer.hashicorp.com\/terraform\/language\/backend<\/span><\/a><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<\/ul>\n<ul>\n<li aria-setsize=\"-1\" data-leveltext=\"\u2022\" data-font=\"OpenSymbol\" data-listid=\"13\" data-list-defn-props=\"{&quot;335551671&quot;:0,&quot;335552541&quot;:1,&quot;335559685&quot;:709,&quot;335559991&quot;:283,&quot;469769226&quot;:&quot;OpenSymbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\u2022&quot;,&quot;469777815&quot;:&quot;multilevel&quot;}\" data-aria-posinset=\"2\" data-aria-level=\"1\"><b><span data-contrast=\"auto\">AWS Prescriptive Guidance: Terraform backend best practices.<\/span><\/b><br \/>\n<span data-contrast=\"auto\">Amazon Web Services &#8211; <\/span><a href=\"https:\/\/docs.aws.amazon.com\/prescriptive-guidance\/latest\/terraform-aws-provider-best-practices\/backend.html?utm_source=chatgpt.com\" target=\"_blank\" rel=\"noopener\"><span data-contrast=\"auto\">https:\/\/docs.aws.amazon.com\/prescriptive-guidance\/latest\/terraform-aws-provider-best-practices\/backend.html<\/span><\/a><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/li>\n<\/ul>\n<p><strong>Related Searches &#8211;<\/strong> <a href=\"https:\/\/opstree.com\/services\/devops-and-devsecops-services\/\" target=\"_blank\" rel=\"noopener\">DevOps as a Service Provider<\/a> | <a href=\"https:\/\/opstree.com\/blog\/2023\/06\/20\/database-migration-service-in-aws\/\">AWS Database Migration Services<\/a> | <a href=\"https:\/\/opstree.com\/blog\/2025\/10\/27\/data-engineering-companies\/\">Data Engineering Company in India<\/a><\/p>\n<h2 id=\"faqs\" data-start=\"2095\" data-end=\"2137\"><strong id=\"faqs\" data-start=\"2100\" data-end=\"2137\">Frequently Asked Questions\u00a0<\/strong><\/h2>\n<h3><span data-contrast=\"auto\">Q1.\u00a0<\/span><b><span data-contrast=\"auto\">Does native S3 locking require me to\u00a0immediately\u00a0cease using DynamoDB?<\/span><\/b><\/h3>\n<p><span data-contrast=\"auto\">No, native S3 locking is not required. You can proceed if you already have a functional S3 + DynamoDB setup that satisfies your requirements. However, you should think about a migration strategy because Terraform&#8217;s S3 backend documentation deprecates the dynamodb_table option.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/p>\n<h3><b><span data-contrast=\"auto\">Q2. Which Terraform version is\u00a0required\u00a0for native S3 locking?<\/span><\/b><\/h3>\n<p><span data-contrast=\"auto\">Native S3 state locking is available in Terraform versions that support the <\/span><b><span data-contrast=\"auto\">use_lockfile\u00a0= true<\/span><\/b><span data-contrast=\"auto\">\u00a0backend\u00a0option. The feature was first introduced as experimental around version\u00a0<\/span><b><span data-contrast=\"auto\">1.10.0<\/span><\/b><span data-contrast=\"auto\">\u00a0and became\u00a0generally available\u00a0in later releases.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/p>\n<h3><span data-contrast=\"auto\">Q3.\u00a0<\/span><b><span data-contrast=\"auto\">During migration, is it possible to simultaneously activate native S3 locking and DynamoDB locking?<\/span><\/b><\/h3>\n<p><span data-contrast=\"auto\">For transition safety, you can temporarily set both dynamodb_table and use_lockfile = true in your backend configuration.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/p>\n<h3><span data-contrast=\"auto\">Q4.\u00a0<\/span><b><span data-contrast=\"auto\">What should I do if a lock file (.tflock) in S3 is abandoned (orphaned)?<\/span><\/b><\/h3>\n<p><span data-contrast=\"auto\">If Terraform force-unlock is supported, you can use it or manually remove the lock file from the S3 bucket. Before forcing an unlock, always make sure you know who is holding the lock.<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/p>\n<h3><span data-contrast=\"auto\">Q5.\u00a0<\/span><b><span data-contrast=\"auto\">Does native S3 locking alter the IAM permissions I\u00a0require?<\/span><\/b><\/h3>\n<p><span data-contrast=\"auto\">The state file and the lock file (lock file *.tflock, for example) still require S3 permissions (s3:GetObject, s3:PutObject, and s3:DeleteObject).<\/span><span data-ccp-props=\"{&quot;201341983&quot;:0,&quot;335559739&quot;:140,&quot;335559740&quot;:276}\">\u00a0<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction\u00a0 When managing infrastructure-as-code using Terraform, the\u2002state file is a key\u00a0component, as it keeps track of what resources are associated with your\u00a0configuration and how they are configured relative to one another. Teams will suffer from corrupted state and conflicting updates if they are left on their own to store and coordinate\u00a0state.As\u00a0teams compete for overall dominance, &hellip; <a href=\"https:\/\/opstree.com\/blog\/2026\/01\/06\/terraform-with-s3-and-dynamodb\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Terraform state locking with S3 and DynamoDB explained&#8221;<\/span><\/a><\/p>\n","protected":false},"author":244582708,"featured_media":30293,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[768739361],"tags":[2513561,764654971,7290753,768739342,768739602,343865,3021235,768739407],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/opstree.com\/blog\/wp-content\/uploads\/2026\/01\/Blog-Image-Template-8.png","jetpack_likes_enabled":false,"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/pfDBOm-7Sw","jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts\/30288"}],"collection":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/users\/244582708"}],"replies":[{"embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/comments?post=30288"}],"version-history":[{"count":5,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts\/30288\/revisions"}],"predecessor-version":[{"id":30296,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/posts\/30288\/revisions\/30296"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/media\/30293"}],"wp:attachment":[{"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/media?parent=30288"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/categories?post=30288"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/opstree.com\/blog\/wp-json\/wp\/v2\/tags?post=30288"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}