How to add a new resource to an existing resource group in Terraform - azure

This would appear to be a fairly simple and basic scenario but I'm frankly at a loss on how to get around this using Terraform and would appreciate any suggestions.
The issue is this. In Azure, I have a number of resource groups, each containing a number of resources, including virtual networks, subnets, storage accounts, etc. What I would now like to do is add new resources to one or two of the resource groups. Typical example, I would like to provision a new virtual machine in each of the resource groups.
Now, so far all of the documentation and blogs I seem to come across only provide guidance on how to create resources whereby you also create a new resource group, vnet, subnet, from scratch. This is definitely not what I wish to do.
All I'm looking to do is get Terraform to add a single virtual machine to an existing resource group, going on to configure it to connect to existing networking resources such as a VNet, Subnet, etc. Any ideas?

I tested for ECS by destroying the launch configuration.
terraform destroy -target module.ecs.module.ec2_alb.aws_launch_configuration.launchcfg
I recreated the launch configuration and it worked:
terraform plan -target=module.ecs.module.ec2_alb.aws_launch_configuration
terraform apply -target=module.ecs.module.ec2_alb.aws_launch_configuration
Also, you can go read more on Terraform target here: https://learn.hashicorp.com/tutorials/terraform/resource-targeting

If you just want to be able to reference your existing resources in your TF script, you normally would use data sources in TF to fetch their information.
So for resource group, you would use data source azurerm_resource_group, for vnet there is azurerm_virtual_network and so forth.
These data sources would allow you to only reference and get details of existing resources, not to manage them in your TF script. Thus if you would like to actually manage these resources using TF (modify, delete, etc), you would have to import them first to TF.

Related

Migrate a data block to resource block in Terraform

Initially resources in our authentication provider were created manually through the provider web console. It worked and things went to production this way. The problem is that the configuration is increasing in complexity and I'd like to manage it through terraform files instead of continuing through the provider Web console (no backup, no way to recreate everything easily , etc.)
I initially thought of modelling my configuration with data block for the existing resources and use new resources block for the new resources we need to create. Then I wanted to migrate from the data blocks to terraform managed resources (aka resource block). Is it possible through moved block or something else? Is it possible to do it without having to recreate a new managed resource and destroy the data resource which is most likely to cause down time or disruption to the end-user?
In order to manage the resources which were initially created manually or out of terraform scope by any means, Terraform cli offers import as a native solution by Hashicorp.
Every resource has its own way of importing syntax (starting with terraform import ) which you can find at the bottom of any terraform resource definition.
As an example:
Azurerm windows_virtual_machine Import
terraform import azurerm_windows_virtual_machine.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.Compute/virtualMachines/machine1
Downside of Native import: You have to import all resources one by one and sometimes just for one resource(solution) you have to make multiple import calls
as an example for a windows virtual machine, you might import
azurerm_virtual_machine_extension
azurerm_managed_disk
azurerm_virtual_machine_data_disk_attachment
as separate. It strongly depends on how would you like them to manage them at the end.
BUT
There are few open-source tools available that help If you have lots of resources that you want to bring under terraform management in a lot easier and faster way.
If you working with Azure resources then aztfy is the recommended tool as it is natively from Azure.
It does generate the terraform code, additionally, it has a feature where you can import the azure resource group, it automatically imports and generates config for the resources that the resource group is holding. Not to mention but the tool gives you a nice terminal-based-UI experience.
For other hyperscalers, there are two choices.
terracognita: can generate modules too as per their docs.
terraformer: Developed by Google people but not an official product.

How to import a remote resource while performing an apply in Terraform?

I'm using Terraform to create some resources. One of the side effects of creating the resource is the creation of another resource (let's call this B). The issue is that I can't access B to edit it in terraform because terraform considers it as "out of the state". I can't also import B in the state before the terraform apply is started because B does not exist.
Is there any solution to add (import) a remote resource to the state while running the apply command?
I'm thinking about this as a general question, if there was no solution I can also share the details of the resources I'm creating.
More details:
When I create a "Storage Account" on Azure using Terraform and enable static_website, Azure automatically creates a storage_container named $web. I need to edit one of the attributes of the $web container but Terraform tells me it is not in the current state and needs to be imported. Storage Account is A, Container is B
Unfortunately I do not have an answer to your specific question of importing a resource during an apply. The fundamental premise of Terraform is that it manages resources from creation. Therefore, you need to have a (in this case, azurerm_storage_container) resource declared, before you can import the current state of that resource into your state.
In an ideal world you would be able to explicitly create the container first and specify that the storage account uses that, but a quick look in the docs does not suggest that is an option (and I think is something you have already tried). If it is not exposed in Terraform, that is likely because it is not exposed by the Azure API (Disclaimer: not an Azure user)
The only (bad) answer I can think to suggest, is that you define an azurerm_storage_container data resource in your code, dependent on the the azurerm_storage_account resource, that will be able to pull back the details of the created container. You could then potentially have a null_resource that calls a local-exec provisioner that can fire a CLI command, using the params taken from the data resource to allow you to use the Azure CLI tools to edit the container.
I really hope someone else can come along with a better answer tho :|

Apply NSG/ASG by default on new subnets (Azure)

We manage an Azure subscription operated by several countries. Each of them is quite independant about they can do (create/edit/remove resources). A guide of good practices has been sent to them, but we (security team) would like to ensure a set of NSG is systematically applied for every new subnet/vnet created.
Giving a look to Azure Triggers, I am not sure that subnet creation belongs to the auditable events. I also was told to give a look to Azure policy, but once again I am not sure this will match our expectations which are : For every new vnet/subnet, automatically apply a set of predefined NSG.
Do you have any idea about a solution for our need ?
I have done work like this in the past (not this exact issue) and the way I solved it was with an Azure Function that walked the subscription and looked for these kinds of issues. You could have the code run as a Managed Identity with Reader rights on the subscription to report issues, or as a Contributor to update the setting. Here's some code that shows how you could do this with PowerShell https://github.com/Azure/azure-policy/tree/master/samples/Network/enforce-nsg-on-subnet
You could consider using a Policy that has a DeployIfNotExists Action, to deploy an ARM template that contains all the data for the NSG. https://learn.microsoft.com/en-us/azure/governance/policy/samples/pattern-deploy-resources
You can get the ARM template by creating the NSG and getting the template:
GettingNSGTemplate
Note also that creating a subnet is audited, you can see it in the Activity Log for the VNet. See the screen shot.
AddingASubnet

How Can I Recursively Compare Azure Resource Groups?

I have one resource group that I set up with the portal and another that I tried to configure the same way using Terraform.
Each group contains
Application Gateway with Web App Firewall
Virtual networks and subnets
VMs and associated storage
Public IPs, NSGs, NIC etc
Is there a way for me to compare the two sets of configurations?
For you, I assume you want to create the same resources with the same configurations in another group through Terraform. On my side, there are not many things you need to care about. Just according to the configuration of the resources to create the terraform script.
each resource region
the public IP and the NIC allocation method
NSG rules
vnet and the subnet address prefix
application gateway properties and the rules
The above points are that I think you need to care about. And the properties of the resources in Terraform also need to according to. I think there is no other way to compare two sets of configurations. If you really want, you can compare the template of each group when you create them. The group template shows below:
No, i dont think there is a reasonable straight forward way of doing this, you can create a powershell script that would get resources in each resource group and then try and compare properties, but its hard to give some sort of estimation how accurate it would be, there is a Compare-Object cmdlet in powershell, which might help you with that.

Create multiple server using Terraform on Azure

I am creating multiple servers on Azure using Terraform template in a same Azure "Resource group", However when i try to run the template for individual servers each time, it is deleting the previous server while creating for next one.
Any idea how i can i reuse the same template for creating multiple server in a same Resource Group.
Thanks.
Terraform is intended to be idempotent, meaning that reapplying the same template makes no changes. If you edit the template, Terraform will edit the environment to reflect any changes or deletions.
If you need multiple VMs, you have at least two options:
Define multiple VM resources in your template.
Define a VM scale set and simply specify the number of VMs that you need.
I was able to achieve this, Here is what i did.
I created 2 separate .tf files under different folders.
1) For creating Resource group, NSG, Storage account, Vnet
2) For creating public ip, network interface and VM itself.
So i could use second configuration file for creating multiple server by just changing the values though parameters

Resources