Weitere ähnliche Inhalte Ähnlich wie Terraform for fun and profit (20) Mehr von Bram Vogelaar (20) Kürzlich hochgeladen (20) Terraform for fun and profit2. ~$ whoami~$ whoami
● I used to be a Molecular Biologist,I used to be a Molecular Biologist,
● Then became a Dev,Then became a Dev,
● Now an Ops.Now an Ops.
● Open Source Consultant @Open Source Consultant @inuits.euinuits.eu
5. ResourcesResources
resourceresource "azurerm_dns_a_record""azurerm_dns_a_record" "foreman""foreman" {{
namename == "foreman""foreman"
zone_namezone_name == "${"${azurerm_dns_zoneazurerm_dns_zone.esoptra_io..esoptra_io.namename}"}"
resource_group_nameresource_group_name == "${"${azurerm_resource_groupazurerm_resource_group.euw1-mgmtdns-rg..euw1-mgmtdns-rg.namename}"}"
ttlttl == 300300
recordsrecords = [= ["${"${azurerm_public_ipazurerm_public_ip.reverseproxy_public_ip..reverseproxy_public_ip.ip_addressip_address}"}"]]
}}
8. modulesmodules
● Basically any subdir is a moduleBasically any subdir is a module
modulemodule "reverseproxy""reverseproxy" {{
sourcesource == "../modules/azure/debian9""../modules/azure/debian9"
azure_region_nameazure_region_name == "${var."${var.azure_region_nameazure_region_name}"}"
blob_endpointblob_endpoint == "${"${azurerm_storage_accountazurerm_storage_account.euw1-forest-storage-acc..euw1-forest-storage-acc.primary_blob_endpointprimary_blob_endpoint}"}"
costcentercostcenter == "${var."${var.costcentercostcenter}"}"
environmentenvironment == "${var."${var.environmentenvironment}"}"
node_namenode_name == "proxy""proxy"
public_ippublic_ip == "${"${azurerm_public_ipazurerm_public_ip.forest_reverseproxy_public_ip..forest_reverseproxy_public_ip.idid}"}"
puppetmaster_ippuppetmaster_ip == "${data."${data.terraform_remote_stateterraform_remote_state..remote_state_mgmtremote_state_mgmt..puppetmaster_ippuppetmaster_ip}"}"
region_nameregion_name == "${var."${var.region_nameregion_name}"}"
resource_groupresource_group == "${"${azurerm_resource_groupazurerm_resource_group.euw1-forest-rg..euw1-forest-rg.namename}"}"
storage_accountstorage_account == "${"${azurerm_storage_accountazurerm_storage_account.euw1-forest-storage-acc..euw1-forest-storage-acc.namename}"}"
subnet_idsubnet_id == "${"${azurerm_subnetazurerm_subnet.euw1-forest-sn-dmz..euw1-forest-sn-dmz.idid}"}"
subnet_namesubnet_name == "${"${azurerm_subnetazurerm_subnet.euw1-forest-sn-dmz..euw1-forest-sn-dmz.namename}"}"
vm_root_usernamevm_root_username == "${var."${var.vm_root_usernamevm_root_username}"}"
vm_root_passwordvm_root_password == "${var."${var.vm_root_passwordvm_root_password}"}"
rolerole == "website""website"
}}
10. variablesvariables
variablevariable "region_name""region_name" {}{}
variablevariable "resource_group""resource_group" {}{}
variablevariable "role""role" {{
defaultdefault == "node""node"
}}
variablevariable "storage_account""storage_account" {}{}
variablevariable "subnet_id""subnet_id" {}{}
variablevariable "subnet_name""subnet_name" {}{}
variablevariable "vm_root_username""vm_root_username" {}{}
variablevariable "vm_root_password""vm_root_password" {}{}
variablevariable "vm_size""vm_size" {{
defaultdefault == "Standard_A1_v2""Standard_A1_v2"
}}
11. Terraform.tfvarsTerraform.tfvars
The 'terraform.tfvars' files will need to have severalThe 'terraform.tfvars' files will need to have several
variables set to be able successfully connect to azure.variables set to be able successfully connect to azure.
arm_client_id = "xxxxxxxxx"arm_client_id = "xxxxxxxxx"
arm_client_secret = "xxxxxxxxx"arm_client_secret = "xxxxxxxxx"
arm_subscription_id = "xxxxxxxxx"arm_subscription_id = "xxxxxxxxx"
arm_tenant_id = "xxxxxxxxx"arm_tenant_id = "xxxxxxxxx"
resource_group_name = "euw1-mgmt-rg-deploy"resource_group_name = "euw1-mgmt-rg-deploy"
storage_account_name = "euw1mgmtsadeploy"storage_account_name = "euw1mgmtsadeploy"
container_name = "euw1-mgmt-sc-remote-state"container_name = "euw1-mgmt-sc-remote-state"
key = "mgmt.azure.tfstate"key = "mgmt.azure.tfstate"
12. OutputsOutputs
resourceresource "azurerm_dns_zone""azurerm_dns_zone" "esoptra_io""esoptra_io" {{
namename == "esoptra.io""esoptra.io"
resource_group_nameresource_group_name == "${"${azurerm_resource_groupazurerm_resource_group.euw1-glbldns-rg..euw1-glbldns-rg.namename}"}"
tagstags {{
environmentenvironment == "${var."${var.environmentenvironment}"}"
costCentercostCenter == "${var."${var.costcentercostcenter}"}"
}}
}}
outputoutput "esoptra_eu_name_servers""esoptra_eu_name_servers" {{
valuevalue == "${"${azurerm_dns_zoneazurerm_dns_zone.esoptra_io..esoptra_io.name_serversname_servers}"}"
}}
13. Output ~ inputOutput ~ input
resourceresource "azurerm_dns_zone""azurerm_dns_zone" "esoptra_io""esoptra_io" {{
namename == "esoptra.io""esoptra.io"
resource_group_nameresource_group_name == "${"${azurerm_resource_groupazurerm_resource_group.euw1-glbldns-rg..euw1-glbldns-rg.namename}"}"
tagstags {{
environmentenvironment == "${var."${var.environmentenvironment}"}"
costCentercostCenter == "${var."${var.costcentercostcenter}"}"
}}
}}
outputoutput "esoptra_eu_name_servers""esoptra_eu_name_servers" {{
valuevalue == "${"${azurerm_dns_zoneazurerm_dns_zone.esoptra_io..esoptra_io.name_serversname_servers}"}"
}}
resourceresource "godaddy_domain_record""godaddy_domain_record" "gd_esoptra_io""gd_esoptra_io" {{
domaindomain == "esoptra.io""esoptra.io"
nameserversnameservers = [= ["${"${azurerm_dns_zoneazurerm_dns_zone.esoptra_io..esoptra_io.name_serversname_servers}"}"]]
}}
14. Terraform initTerraform init
$ terraform init -backend-config=terraform.tfvars$ terraform init -backend-config=terraform.tfvars
$ terraform get$ terraform get
17. Terraform planTerraform plan
● Will go out the $provider get the stateWill go out the $provider get the state
● Compare the state and will tell you if and whatCompare the state and will tell you if and what
will be changedwill be changed
● Be aware changes can be PATCH or DELETEBe aware changes can be PATCH or DELETE
and PUTand PUT
18. Terraform applyTerraform apply
● Where the sausage get made.Where the sausage get made.
● Will fail on error and will tell the operator to go fixWill fail on error and will tell the operator to go fix
19. Remote StateRemote State
datadata "terraform_remote_state""terraform_remote_state" "remote_state_mgmt""remote_state_mgmt" {{
backendbackend == "azure""azure"
configconfig {{
resource_group_nameresource_group_name == "euw1-mgmt-rg-deploy""euw1-mgmt-rg-deploy"
storage_account_namestorage_account_name == "euw1mgmtsadeploy""euw1mgmtsadeploy"
container_namecontainer_name == "euw1-mgmt-sc-remote-state""euw1-mgmt-sc-remote-state"
keykey == "mgmt.azure.tfstate""mgmt.azure.tfstate"
arm_subscription_idarm_subscription_id == "${var."${var.arm_subscription_idarm_subscription_id}"}"
arm_client_idarm_client_id == "${var."${var.arm_client_idarm_client_id}"}"
arm_client_secretarm_client_secret == "${var."${var.arm_client_secretarm_client_secret}"}"
arm_tenant_idarm_tenant_id == "${var."${var.arm_tenant_idarm_tenant_id}"}"
}}
}}
20. The other remote stateThe other remote state
outputoutput "forest_reverseproxy_public_ip""forest_reverseproxy_public_ip" {{
valuevalue == "${"${azurerm_public_ipazurerm_public_ip.forest_reverseproxy_public_ip..forest_reverseproxy_public_ip.ip_addressip_address}"}"
}}
resourceresource "azurerm_dns_a_record""azurerm_dns_a_record" "raet""raet" {{
namename == "raet""raet"
zone_namezone_name == "${data."${data.terraform_remote_stateterraform_remote_state..remote_state_mgmtremote_state_mgmt..esoptra_net_nameesoptra_net_name}"}"
resource_group_nameresource_group_name == "${data."${data.terraform_remote_stateterraform_remote_state..remote_state_mgmtremote_state_mgmt..euw1-glbldns-rg-nameeuw1-glbldns-rg-name}"}"
ttlttl == 300300
recordsrecords = [= ["${"${azurerm_public_ipazurerm_public_ip.forest_reverseproxy_public_ip..forest_reverseproxy_public_ip.ip_addressip_address}"}"]]
}}
21. importsimports
terraform import azurerm_dns_a_record.testterraform import azurerm_dns_a_record.test
/subscriptions/00000000-0000-0000-0000-/subscriptions/00000000-0000-0000-0000-
000000000000/resourceGroups/mygroup1/prov000000000000/resourceGroups/mygroup1/prov
iders/Microsoft.Network/dnsZones/zone1/A/myriders/Microsoft.Network/dnsZones/zone1/A/myr
ecord1ecord1
22. TestingTesting
ruby '2.3.1'ruby '2.3.1'
source 'https://rubygems.org/' dosource 'https://rubygems.org/' do
gem 'test-kitchen'gem 'test-kitchen'
gem 'kitchen-terraform'gem 'kitchen-terraform'
EndEnd
Kitchen {converge, verify,destroy}Kitchen {converge, verify,destroy}
23. cloud-initcloud-init
os_profileos_profile {{
computer_namecomputer_name == "${var."${var.environmentenvironment}${var.}${var.node_namenode_name}"}"
admin_usernameadmin_username == "${var."${var.vm_root_usernamevm_root_username}"}"
admin_passwordadmin_password == "${var."${var.vm_root_passwordvm_root_password}"}"
custom_datacustom_data == "${data."${data.template_filetemplate_file..bootstrap_shbootstrap_sh..renderedrendered}"}"
}}
#!/usr/bin/env bash#!/usr/bin/env bash
apt-get update && sudo apt-get dist-upgrade -yapt-get update && sudo apt-get dist-upgrade -y
apt-get install -y apt-transport-https lsb-release dirmngr ssmtpapt-get install -y apt-transport-https lsb-release dirmngr ssmtp
wget -O - https://raw.githubusercontent.com/petems/puppet-install-wget -O - https://raw.githubusercontent.com/petems/puppet-install-
shell/master/install_puppet_5_agent.sh | shshell/master/install_puppet_5_agent.sh | sh
cat << EOF > /etc/puppetlabs/puppet/csr_attributes.yamlcat << EOF > /etc/puppetlabs/puppet/csr_attributes.yaml
------
extension_requests:extension_requests:
pp_environment: ${environment}pp_environment: ${environment}
pp_network: ${network}pp_network: ${network}
pp_provisioner: terraformpp_provisioner: terraform
pp_region: ${region}pp_region: ${region}
pp_role: ${role}pp_role: ${role}
EOFEOF
echo "${puppetmaster_ip}echo "${puppetmaster_ip} ${puppetmaster_fqdn}" >> /etc/hosts${puppetmaster_fqdn}" >> /etc/hosts
/opt/puppetlabs/bin/puppet agent -t --environment=mgmt/opt/puppetlabs/bin/puppet agent -t --environment=mgmt
24. ContactContact
Bram VogelaarBram Vogelaar
+31 6 46 62 60 78+31 6 46 62 60 78
bram.vogelaar@inuits.eubram.vogelaar@inuits.eu
@attachmentgenie@attachmentgenie
Inuits BEInuits BE
Essensteenweg 31Essensteenweg 31
2930 Brasschaat2930 Brasschaat
BelgiumBelgium
Inuits NLInuits NL
Maashaven Zuidzijde 2Maashaven Zuidzijde 2
3081 AE Rotterdam3081 AE Rotterdam
NetherlandsNetherlands