{"id":2073,"date":"2024-06-05T09:44:32","date_gmt":"2024-06-05T07:44:32","guid":{"rendered":"https:\/\/robermb.com\/blog\/?p=2073"},"modified":"2024-06-05T10:10:41","modified_gmt":"2024-06-05T08:10:41","slug":"terraform-lifecycle-rules","status":"publish","type":"post","link":"https:\/\/robermb.com\/blog\/geeks\/terraform-lifecycle-rules\/","title":{"rendered":"Terraform LifeCycle Rules"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Managing Resource Lifecycle in Terraform<\/h2>\n\n\n\n<p>When managing infrastructure with <strong>Terraform<\/strong>, controlling the <strong>lifecycle<\/strong> of resources is crucial, especially in production environments. Terraform provides several lifecycle parameters to control how resources are created, updated, and deleted. Three key lifecycle parameters are\u00a0<code><strong>create_before_destroy<\/strong><\/code>,\u00a0<code><strong>prevent_destroy<\/strong><\/code>, and\u00a0<code><strong>ignore_changes<\/strong><\/code>.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">create_before_destroy<\/h4>\n\n\n\n<p>The\u00a0<strong>create_before_destroy<\/strong>\u00a0parameter ensures that a new resource is created before the old one is destroyed. This is useful when downtime needs to be minimized or completely avoided. For example, when updating an instance, you might want to ensure the new instance is up and running before the old one is terminated.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">prevent_destroy<\/h4>\n\n\n\n<p>The\u00a0<strong>prevent_destroy<\/strong>\u00a0parameter prevents a resource from being destroyed. This can be critical for resources that should not be deleted, such as production databases or persistent storage.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">ignore_changes<\/h4>\n\n\n\n<p>The\u00a0<strong>ignore_changes<\/strong>\u00a0parameter specifies which attributes of a resource should be ignored when Terraform plans and applies changes. This can be useful when certain attributes are managed outside of Terraform or when they change frequently and you do not want Terraform to revert those changes.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Example Scenario: Managing an AWS EC2 Instance and S3 Bucket<\/h2>\n\n\n\n<p>Suppose we have an AWS EC2 instance and an S3 bucket. We want to ensure the EC2 instance is replaced with minimal downtime, the S3 bucket is never deleted, and some attributes of both resources are managed outside Terraform.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">EC2 Instance Configuration<\/h4>\n\n\n\n<p>We want the new EC2 instance to be created before the old one is destroyed. Also, the&nbsp;<code>instance_type<\/code>&nbsp;should be ignored if changed outside of Terraform.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>provider \"aws\" {\n  region = \"us-west-2\"\n}\n\nresource \"aws_instance\" \"example\" {\n  ami           = \"ami-0c55b159cbfafe1f0\"\n  instance_type = \"t2.micro\"\n\n  tags = {\n    Name = \"example-instance\"\n  }\n\n  lifecycle {\n    create_before_destroy = true\n    ignore_changes = &#91;\n      instance_type\n    ]\n  }\n}<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">S3 Bucket Configuration<\/h4>\n\n\n\n<p>We want to prevent the S3 bucket from being destroyed and ignore changes to the\u00a0<code>Environment<\/code>\u00a0tag if modified outside Terraform.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>resource \"aws_s3_bucket\" \"example_bucket\" {\n  bucket = \"example-unique-bucket-name\"\n  acl    = \"private\"\n\n  tags = {\n    Name        = \"example-bucket\"\n    Environment = \"production\"\n  }\n\n  lifecycle {\n    prevent_destroy = true\n    ignore_changes = &#91;\n      tags&#91;\"Environment\"]\n    ]\n  }\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Detailed Breakdown<\/h2>\n\n\n\n<ol>\n<li><strong>Provider Configuration<\/strong>: Specifies the AWS region.<\/li>\n\n\n\n<li><strong>EC2 Instance Configuration<\/strong>:\n<ul>\n<li><code>ami<\/code>: The AMI ID for the instance.<\/li>\n\n\n\n<li><code>instance_type<\/code>: The type of instance (e.g.,\u00a0<code>t2.micro<\/code>).<\/li>\n\n\n\n<li><code>tags<\/code>: A set of tags to assign to the instance.<\/li>\n\n\n\n<li><code>create_before_destroy<\/code>: Ensures the new instance is created before the old one is destroyed.<\/li>\n\n\n\n<li><code>ignore_changes<\/code>: Ignores changes to the\u00a0<code>instance_type<\/code>\u00a0attribute.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>S3 Bucket Configuration<\/strong>:\n<ul>\n<li><code>bucket<\/code>: The unique name of the S3 bucket.<\/li>\n\n\n\n<li><code>acl<\/code>: The access control list for the bucket.<\/li>\n\n\n\n<li><code>tags<\/code>: A set of tags to assign to the bucket.<\/li>\n\n\n\n<li><code>prevent_destroy<\/code>: Prevents the bucket from being destroyed.<\/li>\n\n\n\n<li><code>ignore_changes<\/code>: Ignores changes to the\u00a0<code>Environment<\/code>\u00a0tag.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Applying the Configuration<\/h2>\n\n\n\n<p>To apply this configuration, use the following Terraform commands:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Initialize the configuration\nterraform init\n\n# Apply the configuration\nterraform apply<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Updating the EC2 Instance<\/h2>\n\n\n\n<p>If you need to update the EC2 instance, for example, changing the instance type, modify the\u00a0<code>instance_type<\/code>\u00a0parameter:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>resource \"aws_instance\" \"example\" {\n  ami           = \"ami-0c55b159cbfafe1f0\"\n  instance_type = \"t2.small\"  # Updated instance type\n\n  tags = {\n    Name = \"example-instance\"\n  }\n\n  lifecycle {\n    create_before_destroy = true\n    ignore_changes = &#91;\n      instance_type\n    ]\n  }\n}<\/code><\/pre>\n\n\n\n<p>After updating, apply the changes:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>terraform apply<\/code><\/pre>\n\n\n\n<p>Terraform will create a new instance of type&nbsp;<code>t2.small<\/code>&nbsp;before terminating the existing&nbsp;<code>t2.micro<\/code>&nbsp;instance, ensuring continuous availability. Any changes to the&nbsp;<code>instance_type<\/code>&nbsp;attribute made outside of Terraform will be ignored.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>Using\u00a0<code><strong>create_before_destroy<\/strong><\/code>,\u00a0<code><strong>prevent_destroy<\/strong><\/code>, and\u00a0<code><strong>ignore_changes<\/strong><\/code>\u00a0<strong>lifecycle<\/strong> <strong>parameters<\/strong> in Terraform allows you to manage resources with greater control and confidence. These parameters are essential tools for <strong>maintaining high availability<\/strong>, <strong>preventing<\/strong> <strong>accidental<\/strong> <strong>deletion<\/strong> of critical resources, and <strong>accommodating<\/strong> <strong>external<\/strong> <strong>management<\/strong> of specific attributes.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Managing Resource Lifecycle in Terraform When managing infrastructure with Terraform, controlling the lifecycle of resources is crucial, especially in production &hellip; <a href=\"https:\/\/robermb.com\/blog\/geeks\/terraform-lifecycle-rules\/\" class=\"more-link\">More <span class=\"screen-reader-text\">Terraform LifeCycle Rules<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":2031,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[103,2],"tags":[112,126,131],"_links":{"self":[{"href":"https:\/\/robermb.com\/blog\/wp-json\/wp\/v2\/posts\/2073"}],"collection":[{"href":"https:\/\/robermb.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/robermb.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/robermb.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/robermb.com\/blog\/wp-json\/wp\/v2\/comments?post=2073"}],"version-history":[{"count":12,"href":"https:\/\/robermb.com\/blog\/wp-json\/wp\/v2\/posts\/2073\/revisions"}],"predecessor-version":[{"id":2087,"href":"https:\/\/robermb.com\/blog\/wp-json\/wp\/v2\/posts\/2073\/revisions\/2087"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/robermb.com\/blog\/wp-json\/wp\/v2\/media\/2031"}],"wp:attachment":[{"href":"https:\/\/robermb.com\/blog\/wp-json\/wp\/v2\/media?parent=2073"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/robermb.com\/blog\/wp-json\/wp\/v2\/categories?post=2073"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/robermb.com\/blog\/wp-json\/wp\/v2\/tags?post=2073"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}