Software isn't done until you deliver it to the user. 
We've been discussing what done means at my Scrum team lately. There were a lot of suggestions. One of us said that when the code is ready for review, at least the implementation part is done. Others said that we could not specify a task as done until we test it on production and see it working as expected. "Done" means that we don't have anything left to do with it. That's why the above quote explains what "Done" means in terms of software simply.
You have a small feature to implement. You write the code. Someone from your team reviews it and gives feedback. You take your code back, polish it, maybe refactor it to meet your team's criteria. Then you move on to the QA. Oh, something just doesn't look right. You fix it and push it again. Cool! Now your work passes the QA. You merge your PR and deploy it to production.
The scenario above touches two main points at the end:
Continuous Integration (CI) where you integrate your work as frequently and as soon as possible. Having small changes in your work helps, because this way, your code does not get too different from the main branch.
Continuous Deployment (CD)  where you not only keep your integrated work deployable at all times, but you also deploy your main branch to production with each integration automatically.
CI and CD approach aims to deliver software faster. They pretty much succeed at this job. However, your software isn't the only thing that is delivered quickly and frequently. Your third party libraries get updated regularly. Your cloud provider issues updates to its infrastructure. Your data gets bigger by the day. Your network needs may change as you expand. So, basically, how do you scale?
The Devops movement encourages software developers, operations staff, and everyone else involved in delivery to work together - avoiding hand-offs that add delays and brittleness. Infrastructure-As-Code takes advantage of our cloud age ability to rapidly deploy and provision new servers. 
Infrastructure-As-Code (IaC) lets you define your infrastructure with code so that you can configure your provisions and replicate it at a later point. With version control, you can reverse your infra to an older state if something goes wrong. It makes your operations reliable and scalable. You don't have to worry about upgrading or maintaining a single server you have.
CI is up to me. I need to integrate my work as frequently as possible. CD is up to our deployment rules. I want to deploy my work as often as possible. Now with IaC, I also get control over where my code gets deployed. That is the main reason why I decided to learn more about Terraform . And that is why I want to summarize what I've learned while practicing Terraform.
- Part 1: Introduction
- Part 2: Creating the Server
- Part 3: Provisioning the Server
- Part 4: Managing Terraform State
- Part 5: Cleaner Code with Terraform Modules
- Part 6: Loops with Terraform
- Part 7: Conditionals with Terraform
- Part 8: Testing Terraform Code
: Terraform Up & Running: Writing Infrastructure as Code by Yevgeniy Brikman (2nd edition)
: Not to be confused with Continuous Delivery where you keep your work deployable at all times but make the deployments manually from time to time.
: Software Delivery Guide by Martin Fowler
: Terraform is one of the most popular IaC tools. Popularity and adoption are key to keep the IaC tool up-to-date with various providers.
Cover picture by Lucas Myers
PS: Also checkout Terraforming on Wikipedia!