<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Lars Magelssen</title>
    <description>The latest articles on DEV Community by Lars Magelssen (@larma).</description>
    <link>https://dev.to/larma</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2689923%2F88a7ffdb-8690-4a0d-909c-ad78409d7194.jpeg</url>
      <title>DEV Community: Lars Magelssen</title>
      <link>https://dev.to/larma</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/larma"/>
    <language>en</language>
    <item>
      <title>Flameshot - My favorite screeshot app</title>
      <dc:creator>Lars Magelssen</dc:creator>
      <pubDate>Tue, 02 Sep 2025 11:47:44 +0000</pubDate>
      <link>https://dev.to/larma/flameshot-my-favorite-screeshot-app-4kn7</link>
      <guid>https://dev.to/larma/flameshot-my-favorite-screeshot-app-4kn7</guid>
      <description>&lt;p&gt;tl;dr: Use Flameshot to take screenshots and edit them directly before saving to a file or to the clipboard. Download at &lt;a href="https://flameshot.org/#download" rel="noopener noreferrer"&gt;flameshot.org/download&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Flameshot
&lt;/h2&gt;

&lt;p&gt;Flameshot is my favorite screenshot app and I have been using it for years.&lt;br&gt;
I've shown this app to lots of co-workers over the years since I find it super&lt;br&gt;
practical. I have to admit that windows and mac has stepped up their&lt;br&gt;
screenshot tools the last years, so everything isn't as unique as it was the&lt;br&gt;
first time i tried out Flameshot. Still I find it the best tool for taking&lt;br&gt;
screenshots and I use it daily.&lt;/p&gt;

&lt;p&gt;Recently Flameshot got a new update after 3 years (last was in June 2022). So I thought this was the perfect time to introduce my favorite screenshot tool and talk about some of the new changes.&lt;/p&gt;
&lt;h2&gt;
  
  
  How does it work?
&lt;/h2&gt;

&lt;p&gt;So with Flameshot you press a hotkey to trigger a screenshot. Then you mark the&lt;br&gt;
part of the screen you want to capture. The cool part is all the tools you have&lt;br&gt;
at your disposal to draw, write, mark, pixelate,  etc..&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F38siluhlkbbp7faxnni0.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F38siluhlkbbp7faxnni0.gif" alt=" " width="880" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I find this perfect for sending a quick screenshot to a co-worker to show something. Adding text and an arrow or circling what ever I'm trying to show make it super practical.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8vqzggxuo66epyjfit3e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8vqzggxuo66epyjfit3e.png" alt=" " width="800" height="245"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Command Line Interface
&lt;/h2&gt;

&lt;p&gt;Flameshot comes with a CLI. With this you can programmatically take screenshots.&lt;br&gt;
This is great for automating screenshots in scripts or integrating it into&lt;br&gt;
workflows. On Linux it is very fast and efficient to be able to specify the&lt;br&gt;
screenshot command and bind it to a shortcut. You could for example have&lt;br&gt;
different shortcuts for taking screenshot saving them in specific directories.&lt;/p&gt;

&lt;p&gt;To take a screenshot from the CLI, simply run the command &lt;code&gt;flameshot gui&lt;/code&gt; in the terminal. Add the &lt;code&gt;--help&lt;/code&gt; flag to see the different options.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flameshot gui &lt;span class="nt"&gt;--help&lt;/span&gt;
Usage: flameshot gui &lt;span class="o"&gt;[&lt;/span&gt;gui-options]

Per default runs Flameshot &lt;span class="k"&gt;in &lt;/span&gt;the background and adds a tray icon &lt;span class="k"&gt;for &lt;/span&gt;configuration.

Options:
  &lt;span class="nt"&gt;-p&lt;/span&gt;, &lt;span class="nt"&gt;--path&lt;/span&gt; &amp;lt;path&amp;gt;             Existing directory or new file to save to
  &lt;span class="nt"&gt;-c&lt;/span&gt;, &lt;span class="nt"&gt;--clipboard&lt;/span&gt;               Save the capture to the clipboard
  &lt;span class="nt"&gt;-d&lt;/span&gt;, &lt;span class="nt"&gt;--delay&lt;/span&gt; &amp;lt;milliseconds&amp;gt;    Delay &lt;span class="nb"&gt;time &lt;/span&gt;&lt;span class="k"&gt;in &lt;/span&gt;milliseconds
  &lt;span class="nt"&gt;--region&lt;/span&gt; &amp;lt;WxH+X+Y or string&amp;gt;  Screenshot region to &lt;span class="k"&gt;select&lt;/span&gt;
  &lt;span class="nt"&gt;--last-region&lt;/span&gt;                 Repeat screenshot with previously selected region
  &lt;span class="nt"&gt;-r&lt;/span&gt;, &lt;span class="nt"&gt;--raw&lt;/span&gt;                     Print raw PNG capture
  &lt;span class="nt"&gt;-g&lt;/span&gt;, &lt;span class="nt"&gt;--print-geometry&lt;/span&gt;          Print geometry of the selection &lt;span class="k"&gt;in &lt;/span&gt;the format WxH+X+Y. Does nothing &lt;span class="k"&gt;if &lt;/span&gt;raw is specified
  &lt;span class="nt"&gt;-u&lt;/span&gt;, &lt;span class="nt"&gt;--upload&lt;/span&gt;                  Upload screenshot
  &lt;span class="nt"&gt;--pin&lt;/span&gt;                         Pin the capture to the screen
  &lt;span class="nt"&gt;-s&lt;/span&gt;, &lt;span class="nt"&gt;--accept-on-select&lt;/span&gt;        Accept capture as soon as a selection is made
  &lt;span class="nt"&gt;-h&lt;/span&gt;, &lt;span class="nt"&gt;--help&lt;/span&gt;                    Displays this &lt;span class="nb"&gt;help&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The new update v13.0.0
&lt;/h2&gt;

&lt;p&gt;To see all changes checkout the &lt;a href="https://github.com/flameshot-org/flameshot/releases/tag/v13.0.0" rel="noopener noreferrer"&gt;release notes&lt;/a&gt;, but here are some of the most interesting changes in this update.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;New Features:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The pixelation feature has been replaced with a new "secure" implementation that only uses pixels outside of the area to be redacted.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkdlodlnrf5l5zbhdiyx8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkdlodlnrf5l5zbhdiyx8.png" alt=" " width="800" height="328"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Screenshot dimensions are now interactively shown in the capture widget.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpj1f20zum7qf9dqqejyt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpj1f20zum7qf9dqqejyt.png" alt=" " width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pinned images can now be rotated and made transparent.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyqe86fu8yilhm17dtzc3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyqe86fu8yilhm17dtzc3.png" alt=" " width="630" height="259"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A grid can be enabled and resized to have annotations snap to grid&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fydva0vbygify6c4zb45n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fydva0vbygify6c4zb45n.png" alt=" " width="800" height="416"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Changes:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The tabs in the configuration has been reordered by importance to users.&lt;/li&gt;
&lt;li&gt;Flameshot will exit with exit code 1 if canceled (Used to be 0).&lt;/li&gt;
&lt;li&gt;Imgur uploader is disabled by default.&lt;/li&gt;
&lt;li&gt;Snap packages are likely to be dropped.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to fix error on macOS after update
&lt;/h2&gt;

&lt;p&gt;After I upgraded to version 13, when trying to create a screenshot everything would disappear from the screen and I would only see my desktop background.&lt;/p&gt;

&lt;p&gt;This an mac specific error that occurs since the app no longer recognizes its permissions to capture the screen.&lt;/p&gt;

&lt;p&gt;To fix this, simply remove the old permissions, restart your system, run Flameshot and give the permissions again when prompted.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8ahu2h6h5iv9niivhrvr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8ahu2h6h5iv9niivhrvr.png" alt=" " width="714" height="624"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Flameshot is an awesome free and open source software tool and I highly recommend using it. &lt;a href="https://flameshot.org/#download" rel="noopener noreferrer"&gt;Download&lt;/a&gt; it today!&lt;/p&gt;

</description>
      <category>flameshot</category>
      <category>cli</category>
      <category>opensource</category>
      <category>macos</category>
    </item>
    <item>
      <title>Terraform with remote state in S3</title>
      <dc:creator>Lars Magelssen</dc:creator>
      <pubDate>Mon, 18 Aug 2025 12:01:54 +0000</pubDate>
      <link>https://dev.to/larma/terraform-with-remote-state-in-s3-19na</link>
      <guid>https://dev.to/larma/terraform-with-remote-state-in-s3-19na</guid>
      <description>&lt;p&gt;&lt;strong&gt;tl;dr:&lt;/strong&gt; You can use S3 to store your Terraform state file remote. To migrate a local state file, add a &lt;code&gt;backend "s3" {}&lt;/code&gt; block to your Terraform configuration and run &lt;code&gt;terraform init -migrate-state&lt;/code&gt;. You no longer need to use DynamoDB for state locking, as S3 now has native support for this with &lt;code&gt;use_lockfile = true&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Table of Contents
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;What is remote state?&lt;/li&gt;
&lt;li&gt;State locking&lt;/li&gt;
&lt;li&gt;Set AWS as a Terraform backend&lt;/li&gt;
&lt;li&gt;Migrating local state to S3&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What is remote state?
&lt;/h2&gt;

&lt;p&gt;When you run &lt;code&gt;terraform apply&lt;/code&gt;, terraform will create a state file. When ever&lt;br&gt;
you make a change to your terraform configuration and apply it, terraform will&lt;br&gt;
check the difference between the config and the state before makeing the needed&lt;br&gt;
changes.&lt;/p&gt;

&lt;p&gt;By default this state file is created in the same directory you ran the apply&lt;br&gt;
command. How ever, this creates some problems when there are multiple people&lt;br&gt;
working on the same project. So make it possible for multiple people to work on&lt;br&gt;
the same terraform project then need to share the same state file. This can be&lt;br&gt;
done by storing the state file in the cloud.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu3ak5sx4ytlhkwut6lyf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu3ak5sx4ytlhkwut6lyf.png" alt=" " width="800" height="488"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this post I will go over how to use AWS as a backend and store the terraform&lt;br&gt;
state file in Amazon S3. I will also go over how to migrate the state if you&lt;br&gt;
already have a local state file.&lt;/p&gt;
&lt;h2&gt;
  
  
  State locking
&lt;/h2&gt;

&lt;p&gt;Let's say you have multiple people working on the same terraform configuration sharing a remote state. There need to be made a new EC2 resource. Two people create this and run &lt;code&gt;terraform apply&lt;/code&gt; at the same time. They will both use the same state which says there are no EC2 instances, and both instances will be created. This way they ended up with twice as many instances as intended.&lt;/p&gt;

&lt;p&gt;To prevent this we have state locking. This locks the state when an update is made so that only one can apply changes at the time. It's like transaction locks in SQL.&lt;/p&gt;

&lt;p&gt;Up until early this year (2025) you had to use DynamoDB to manage the state locking. As of Terraform version 1.11 this is no longer needed, which makes this whole setup a lot simpler using S3 native locking.&lt;/p&gt;
&lt;h2&gt;
  
  
  Set AWS as a Terraform backend
&lt;/h2&gt;

&lt;p&gt;To use S3 to store the state you simply need to set AWS as a backend in you Terraform configuration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;terraform&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;backend&lt;/span&gt; &lt;span class="s2"&gt;"s3"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"mybucket"&lt;/span&gt;         &lt;span class="c1"&gt;# Bucket name&lt;/span&gt;
    &lt;span class="nx"&gt;key&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"path/to/my/key"&lt;/span&gt;   &lt;span class="c1"&gt;# The state file&lt;/span&gt;
    &lt;span class="nx"&gt;region&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;        &lt;span class="c1"&gt;# Region where the bucket is&lt;/span&gt;
    &lt;span class="nx"&gt;use_lockfile&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;         &lt;span class="c1"&gt;# Enable S3 native locking&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are using a mac and installed terraform with brew, make sure you have&lt;br&gt;
used the hashicorp tap to get the newest version. If you have an older version&lt;br&gt;
than 1.11, you need to upgrade.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew uninstall terraform
brew tap hashicorp/tap
brew &lt;span class="nb"&gt;install &lt;/span&gt;hashicorp/tap/terraform
terraform version
&lt;span class="c"&gt;# Output&lt;/span&gt;
Terraform v1.12.2
on darwin_arm64
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ok, let's give it a go!&lt;/p&gt;

&lt;p&gt;First we will create a bucket. I will do this in the AWS console.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw6bd3wdlwc8rbglq8fyk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw6bd3wdlwc8rbglq8fyk.png" alt=" " width="800" height="515"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note the region, make sure it is as intended. We'll give the bucket a name and leave everything else as default. Or on second thought, let's enable versioning. This is suggested by Terraform to be able to restore an old state if something should go wrong.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnlb25jrai3o013yw5g8m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnlb25jrai3o013yw5g8m.png" alt=" " width="756" height="334"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that we have our bucket ready (with a typo and everything... sigh...) let's write some terraform code.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;main.tf&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;terraform&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;required_version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&amp;gt;= 1.11.0"&lt;/span&gt;

  &lt;span class="nx"&gt;required_providers&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;aws&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;source&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"hashicorp/aws"&lt;/span&gt;
      &lt;span class="nx"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"~&amp;gt; 6.0"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;backend&lt;/span&gt; &lt;span class="s2"&gt;"s3"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;bucket&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"demo-bucket-for-storeing-my-tf-state-file"&lt;/span&gt;
    &lt;span class="nx"&gt;key&lt;/span&gt;          &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"state-files/demo-project"&lt;/span&gt;
    &lt;span class="nx"&gt;region&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"eu-west-1"&lt;/span&gt;
    &lt;span class="nx"&gt;use_lockfile&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"aws"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;region&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"eu-west-1"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_s3_bucket"&lt;/span&gt; &lt;span class="s2"&gt;"this"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"my-bucket-that-does-not-have-a-typo-in-its-name"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In our terminal we will change directory into the folder containing our&lt;br&gt;
terraform project. And initiate it with &lt;code&gt;terraform init&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz2n4kd8ftdeyb8x287g2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz2n4kd8ftdeyb8x287g2.png" alt=" " width="800" height="545"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Looks good. Let's apply our configuration with &lt;code&gt;terraform apply&lt;/code&gt; and confirm with &lt;code&gt;yes&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Plan: 1 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_s3_bucket.this: Creating...
aws_s3_bucket.this: Creation complete after 2s [id=my-bucket-that-does-not-have-a-typo-in-its-name]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Success. Now, back to the console to confirm everything is as expected.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8hvfkih07lsl100pfnp4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8hvfkih07lsl100pfnp4.png" alt=" " width="800" height="247"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yes, here is the bucket we created with terraform. Now let's check out our state bucket.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0p5axi0zr0pynbq03qjb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0p5axi0zr0pynbq03qjb.png" alt=" " width="800" height="310"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Oh yeah! There it is, our state file.&lt;/p&gt;

&lt;h3&gt;
  
  
  Clean up
&lt;/h3&gt;

&lt;p&gt;Delete the bucket we created with the command &lt;code&gt;terraform destroy --auto-approve&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Migrating local state to S3
&lt;/h2&gt;

&lt;p&gt;Now, that was easy enough, but what about our project that we have already started. The one with a local state file. If we have one. How can we migrate this over to our newly created, typo-in-name-having bucket?&lt;/p&gt;

&lt;p&gt;Let's see if we can figure this our together. In our terminal we will navigate over to our terraform project that has a local state file. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We can use the command &lt;code&gt;tree&lt;/code&gt; to list the content of the directory. I'll add a &lt;code&gt;-a&lt;/code&gt; flag to show hidden files, and a &lt;code&gt;-L 1&lt;/code&gt; flag to only show the first level of the directory tree.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;tree &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="nt"&gt;-L&lt;/span&gt; 1
&lt;span class="nb"&gt;.&lt;/span&gt;
├── .terraform
├── .terraform.lock.hcl
├── main.tf
└── terraform.tfstate

2 directories, 3 files&lt;span class="sb"&gt;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In our &lt;em&gt;main.tf&lt;/em&gt; file we add the backend part in the terraform block. Just as we did before.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;terraform&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="c1"&gt;# ...&lt;/span&gt;
  &lt;span class="nx"&gt;backend&lt;/span&gt; &lt;span class="s2"&gt;"s3"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;bucket&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"demo-bucket-for-storeing-my-tf-state-file"&lt;/span&gt;
    &lt;span class="nx"&gt;key&lt;/span&gt;          &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"state-files/demo-old-project-state-file"&lt;/span&gt;
    &lt;span class="nx"&gt;region&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"eu-west-1"&lt;/span&gt;
    &lt;span class="nx"&gt;use_lockfile&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="c1"&gt;# ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;# ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great, now we should simply have to run &lt;code&gt;terraform apply&lt;/code&gt; to apply our new backend.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzd79wyfvn41c0monfuuy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzd79wyfvn41c0monfuuy.png" alt=" " width="800" height="470"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hmm.. That didn't work. Ok, let's do what it tells us:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform init &lt;span class="nt"&gt;-migrate-state&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fstbmprn7e05h3zambzth.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fstbmprn7e05h3zambzth.png" alt=" " width="800" height="592"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Was that really it? That simple!? Let's have a look in our S3 bucket.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8440viail6u27ubislox.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8440viail6u27ubislox.png" alt=" " width="800" height="325"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There it is! Ok, before we end this, let's test some stuff to make sure&lt;br&gt;
everything works as we want it to. Then we can clean up if needed.&lt;/p&gt;

&lt;p&gt;First, let's try to delete the local state file and apply some changes to &lt;em&gt;main.tf&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;rm &lt;/span&gt;terraform.tfstate terraform.tfstate.backup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we add a new bucket in our &lt;em&gt;main.tf&lt;/em&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;
&lt;span class="c1"&gt;#...&lt;/span&gt;
&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_s3_bucket"&lt;/span&gt; &lt;span class="s2"&gt;"this"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"a-bucket-with-a-unique-name-that-i-will-soon-delete"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;#...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then let's run &lt;code&gt;terraform apply&lt;/code&gt; and see what happens. If terraform use the state file in our S3 bucket, it should see the first bucket that we have already created and only try to add one new bucket.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Plan: 1 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only &lt;span class="s1"&gt;'yes'&lt;/span&gt; will be accepted to approve.

  Enter a value: &lt;span class="nb"&gt;yes

&lt;/span&gt;aws_s3_bucket.that: Creating...
aws_s3_bucket.that: Creation &lt;span class="nb"&gt;complete &lt;/span&gt;after 2s &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;a-bucket-with-a-unique-name-that-i-will-soon-delete]

Apply &lt;span class="nb"&gt;complete&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt; Resources: 1 added, 0 changed, 0 destroyed.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Perfect. We confirmed that terraform is looking at the state file stored in our S3 bucket, and not the local file we used to use.&lt;/p&gt;

&lt;h3&gt;
  
  
  Clean up
&lt;/h3&gt;

&lt;p&gt;I am going to destroy our terraform resources with &lt;code&gt;terraform destroy&lt;/code&gt;, and then navigating to the AWS S3 Console and manually deleting the bucket we created to store our state files. Make sure you do the same if you don't intent on using what we just created.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;We have successfully used AWS to store our terraform state file in S3 with&lt;br&gt;
native state locking without using DynamoDB. We have also seen how easy it is&lt;br&gt;
to migrate the state of an already initiated project. Hope this was helpful.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.hashicorp.com/terraform/language/backend/s3" rel="noopener noreferrer"&gt;terraform documentation - S3 backend&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket" rel="noopener noreferrer"&gt;terraform registry&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/hashicorp/terraform/blob/v1.11/CHANGELOG.md" rel="noopener noreferrer"&gt;terraform v1.11 changelog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>terraform</category>
      <category>aws</category>
      <category>s3</category>
      <category>cli</category>
    </item>
  </channel>
</rss>
