As a novice, iam trying to set up some structure for terraform projects. We as a team will be using terraform for building infrastructure for Aws ,azure and containers. I will be building infra for dedicated application teams and also cloud services individually.my challenge is set up a consistent directory structure which can be used to build all types of cloud and also for dedicated application teams. how can i set up a standard directory structure and how can i manage state file for application teams and individually services
THanks for all your knowledge and lessons to me on this
I can see one generic and one specific question here!
Generic Question: how can i set up a standard directory structure (sic)
This purely depends on how your infrastructure is and what cloud services it uses. I would recommend you to start going through this link to get an idea.
Specific Question: how can i manage state file for application teams and individually services (sic)
As you might be aware, your state file has the details about your infrastructure's state in its entirety and must be stored safely. Besides, since multiple teams are going to be using the Terraform code to update the infrastructure, do save the state file in an S3 bucket (or equivalent object storage service in a different cloud) and have it fetched every time someone runs terraform plan or terraform apply. Reference
Related
I'm currently busy with an internship. In this internship I need to create a program which automatically creates "snapshots" of the current state of Azure Resources (And sometimes their dependencies) which need to be deployed to another environment. e.g. Acceptance -> Production. These snapshots must then be deployed to the new environment at a later date which has been coordinated with the client.
A solution can consists out of >100 Azure resources, ranging from API Managers, to LogicApps, CosmosDB's, etc. When a customer accepts or says "ok" to a few resources (= a part of the total solution) a snapshot needs to be made of that resource, in the specific state when the client said OK. That means that I also have to create a snapshot of the dependencies of that specific resource (LogicApp can depend on a CosmosDB, Keyvault etc).
And I can't just take a reference to the resource in the Acceptance environment, I need to bring that dependency over to production as well, seeing as it might be possible that another developer will continue working on said dependency which might break things.
I am bit of at a loss as to which direction to take here. I don't have a lot of experience with ARM (Templates) and I have been making several prototypes for a month now.
I have first tried to generate my own ARM (and Bicep) files through gathering information from the Azure Rest API, but I soon discovered this is not viable because I cannot extract all of the information from that API to create said ARM file.
I then looked into modifying the generated ARM files from Azure itself. Whilst this is an option, it contains a lot of information which I do not need or want to transfer over to another environment. It is also very hard to determine which parts of the generated ARM file must be deleted, updated, copied or left alone. And then I still need to recursively get the ARM templates of the dependencies and go through those in an automated way as well.
Is modifying existing ARM templates the best route to go here? Or does a similar product already exist which might help achieve my goal?
Thank you!!
In this case, I would not go with the approach to modify exported ARM templates but I would go with approach of Infrastructure as Code i.e., I would created ARM templates as granular as possible i.e., may be one template per resource at the least and store that infrastructure code in a source repository and if required version it to use it in different environments. The reason for recommending one template per resource is to take care of the dependencies in a complex environment. I know this might look like a bigger activity for the first-time implementation but once the templates are integrated into any continuous integration and continuous deployment (CI/CD) tool like Azure DevOps then all of it can be automated with the help of release pipelines for fast and reliable application and infrastructure updates. For more information in this regard, please refer this and this Azure documents.
I know it's possible to combine multiple providers in a single Terraform project.
Would it be possible though, to declare different statefile per provider? In our use-case we will be deploying infrastructure with its part in the client's cloud provider account and other part within our cloud provider account.
We'd like to keep the statefiles separated (client's TF state vs our TF state), in order to allow smoother future migrations of either our part of the infra or client's part of the infra.
We also know that this can be achieved using Terragrunt on top of Terraform, but for the moment we'd prefer to avoid introducing a new tool into our stack. Hence looking for a TF-only solution (if such exists).
The simplest solution would be to use separate folders for your and your client's infrastructure.
Is there a specific reason why you would want to keep them in one folder? Even if you need to share some values, you can easily read them by using terraform_remote_state
I have a query to setup multiple environments at a time so that we can discreetly test multiple projects at once. Ideally we should be able to spin these environments up and down as necessary.
We have microservice based architecture and are mostly using azure PAAS services in our infrastructure.
Currently i have tried to automate our infrastructure through terraform its almost done but next step is deployment of code as services are not containerized so tried using azure pipelines but its a huge task, can i get any better idea for this that how we could do this.
Should look at leveraging Azure Pipeline Templates Once this is defined then can reuse it everywhere. For instance with terraform created a template for doing the plan and apply that just needs to be fed in the directory the terraform is located in. This saved time across all projects as we just need to reference our template and the rest was taken care of.
In terms of your other question with the ability to spin up and spin down this can be easily done if the application is architected with that in mind. Keep in mind for deployment certain things where names must be unique: storage account, app service and things that are potentially shared: i.e. network.
The other piece to consider is how to ensure these ad hoc environments are actually being spun down. Would recommend something like a tagging strategy or process that cleans up resources that haven't been deployed in x amount of days.
Currently, I'm storing all key/value pairs in Application Settings, but I'm not happy with this approach. What is the recommended way to store settings for dev, test, stage, and prod? I need to make sure that prod settings are not visible to developers. Is there a way to create 4 different JSON files and define access permissions on them? Or do I need to create 4 different Function apps (or subscriptions)?
Azure App Configuration is a relatively new service that sounds like it could help in terms of managing the config values centrally with more control than individual instance App Settings.
Beyond that, you could perhaps build segregation by limiting devs to pushing code only and not accessing the hosting environment (Azure portal, etc). The layer in between would be something like Azure DevOps or Github Actions that has access to Azure, while devs are limited to pushing code that triggers deployment.
Also worth reminding ourselves that devs ultimately have a lot of access by virtue of writing the code. If they want to get at runtime data, they can, somehow. If you consider the devs untrusted, you may have bigger problems. If it's just a matter of preventing mistakes, a solid devops process is the key.
CloudFormation doesn't provide tools for orchestrating deployment of several/many stacks. For example consider a microservice/layered architecture where many stacks need to be deployed together to replicate an environment. With cloudformation you need to use a tool like stacker or something home grown to solve the problem.
Does Terraform offer a multi-stack deployment orchestration solution?
Terraform operates on a directory level so you can simply define both stacks at the same place as a big group of resources or as modules.
In Terraform, if you need to deploy multiple resources together at the same time then you would typically use a module and then present a smaller surface area for configuring that module. This also extends to creating modules of modules.
So if you had a module that you created that deployed one service that contained a load balancer, service of some form (such as an ECS task definition; Kubernetes pod, service, deployment etc definition; an AMI) and a database and another module that contained a queue and another service you could then create an over-arching module that contains both of those modules so they are deployed at the same time with a smaller amount of configuration that may be shared between them.
Modules also allow you to define the source location as remote such as a git location or from a Terraform registry (both the public one or a private one) which means the Terraform code for the modules don't have to be stored in the same place or checked out/cloned into the same directory.