Saturday, January 4, 2025

 

Some of the best practices for IaC derive from the software development tenets such as using version control to prevent manual changes and enabling managing, testing, reviewing, and bringing it to production.  Also, like software development, a culture of collaborative development in version-controlled repositories enables individual features to be brought into the code with little disruption to others. Some practices like structuring the project do not apply rigorously to IaC where small projects might decide to keep everything in one folder and larger ones in many folders. Most of the other best practices are rather specific to IaC. Some of these are listed below.

1.      Using remote state: State is as important as version control and ranks among the top best practices specific to IaC because it helps the compiler know what the incremental changes are from what it remembers as having “applied” last time to the infrastructure. A state that support state locking and stored elsewhere to the version control helps it to be treated as immutable and for its backups. It’s even helpful to enable versioning if stored on the public cloud storage accounts for quick and easy state recovery.

2.      Using existing shared and community modules: Instead of writing our own modules for everything and reinventing the wheel, this helps to save time and harness the power of the community. Some are provided by the IaC provider.

3.      Import existing infrastructure: When parts of the infrastructure are created manually, this best practice keeps the IaC in sync with the changes and helps to avoid further manual changes by pushing out the subsequent changes through the pipeline to update code and state together.

4.      Avoiding variables hardcoding: assigning a value to a variable makes it brittle when the IaC must be repurposed or deployed differently. Instead reading it from some data source dynamically helps to keep it in sync when IaC changes.

5.      Always formatting and validating: just like the compiler is unavoidable, striving to use the format and validate tools help to keep the IaC clean and catch any issues that were missed since it is declarative.

6.      Using consistent naming conventions:  This doesn’t require us to be dogmatic but finding something that is comfortable does help. The consistency makes every part of the IaC easy to understand and follow along from project to project.

7.      Tagging the resources: The public clouds offer sufficient documentation for the merits of tagging  and capturing it in IaC along with the consistency definitely helps. Access control policies and cost management features can be implemented using tags.

8.      Writing policy as code: Although policies stand apart from resources, they can and should be captured in code for systems to be operational and secure from deployment onwards. It is also easy to verify the rules when they are in code.

9.      Implementing a secrets management strategy: This comes helpful to preventing disclosure of secrets in files, logs and pipeline artifacts. If necessary, they could be passed in as environment variables although a better option would be store it as a secret.

10.  Enabling debugging and troubleshooting: These features such as enhanced logging on demand can be helpful to narrow down problematic code.

11.  Building modules wherever possible: When there is no community module available, this practice encourages rapid development by just instantiating the object with a suitable set of parameters.

12.  Using loops and conditionals:  Since there can be multiple instances of the code to be managed, using built-in operators and functions can be quite nifty and keep the code readable. Count and foreach are some examples.

13.  Using functions: Along with the above practice, functions are even readily available from the IaC Provider and help to enforce the Do-not Repeat Yourself aka DRY principle. There is a large library of functions to explore and use by virtue of the built-ins from an IaC provider.

14.  Using Dynamic Blocks: Just like the benefits of using functions, this helps to provide flexibility in building resources so that the addition of say, a new rule, does not require to change the configuration.

15.  Using workspaces: this provides a scope for all the definitions so that they can be reused in their entirety, say for different environments.

16.  Maintaining lifecycle of resources:  Determining what changes to recognize can help with keeping the resource definitions and associated change output more manageable.

17.  Using variable validations:  This does a pretty good job of validating inputs especially when the system must fail fast and display helpful error messages before actual deployments.

18.  Leveraging helper tools: Usually, there are many more tools available for use with IaC and pipelines outside the compiler, formatter and validator. Leveraging these can save time and cost.

19.  Using IDE Extensions: This comes helpful when the code is authored in an Integrated Development Environment so that mistakes can be caught as early as when IaC is authored.

20.  Keeping UpToDate with the documentations from the IaC provider because nothing is set in stone, and change is the only constant. The advisories help to prevent mistakes going ahead and are worth reading.

#codingexercise: CodingExercise-01-04-2025.docx

No comments:

Post a Comment