SlideShare ist ein Scribd-Unternehmen logo
1 von 24
Terraform for fun and profit
@attachmentgenie
~$ 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
The other IaCThe other IaC
HCLHCL
● Hashicorp Configuration LanguageHashicorp Configuration Language
● Yet another cfgmgmt DSLYet another cfgmgmt DSL
● Desired stateDesired state
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}"}"]]
}}
ProvidersProviders
● https://www.terraform.io/docs/providers/index.htmhttps://www.terraform.io/docs/providers/index.htm
● Many, many, many optionsMany, many, many options
– Cloud providersCloud providers
– Dns providerDns provider
– gitlabgitlab
● Add your own as a pluginAdd your own as a plugin
PluginsPlugins
● https://github.com/terraform-providershttps://github.com/terraform-providers
providerprovider "godaddy""godaddy" {{
keykey == "${var."${var.gd_keygd_key}"}"
secretsecret == "${var."${var.gd_secretgd_secret}"}"
}}
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"
}}
registryregistry
● https://registry.terraform.iohttps://registry.terraform.io
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"
}}
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"
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}"}"
}}
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}"}"]]
}}
Terraform initTerraform init
$ terraform init -backend-config=terraform.tfvars$ terraform init -backend-config=terraform.tfvars
$ terraform get$ terraform get
Terraform fmtTerraform fmt
The solution to tabs vs spacesThe solution to tabs vs spaces
Terraform validateTerraform validate
● Think linting ++Think linting ++
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
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
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}"}"
}}
}}
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}"}"]]
}}
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
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}
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
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

Weitere ähnliche Inhalte

Was ist angesagt?

From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)
Night Sailer
 
Php code for online quiz
Php code for online quizPhp code for online quiz
Php code for online quiz
hnyb1002
 
Corephpcomponentpresentation 1211425966721657-8
Corephpcomponentpresentation 1211425966721657-8Corephpcomponentpresentation 1211425966721657-8
Corephpcomponentpresentation 1211425966721657-8
PrinceGuru MS
 
MongoDB: Replication,Sharding,MapReduce
MongoDB: Replication,Sharding,MapReduceMongoDB: Replication,Sharding,MapReduce
MongoDB: Replication,Sharding,MapReduce
Takahiro Inoue
 
Topological indices (t is) of the graphs to seek qsar models of proteins com...
Topological indices (t is) of the graphs  to seek qsar models of proteins com...Topological indices (t is) of the graphs  to seek qsar models of proteins com...
Topological indices (t is) of the graphs to seek qsar models of proteins com...
Jitendra Kumar Gupta
 
Bash Learning By Examples
Bash Learning By ExamplesBash Learning By Examples
Bash Learning By Examples
Arun Bagul
 

Was ist angesagt? (20)

From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)
 
Alexander Mostovenko "Modern approach to localization in javascript with the ...
Alexander Mostovenko "Modern approach to localization in javascript with the ...Alexander Mostovenko "Modern approach to localization in javascript with the ...
Alexander Mostovenko "Modern approach to localization in javascript with the ...
 
Manifests of Future Past
Manifests of Future PastManifests of Future Past
Manifests of Future Past
 
Mongodb workshop
Mongodb workshopMongodb workshop
Mongodb workshop
 
Php code for online quiz
Php code for online quizPhp code for online quiz
Php code for online quiz
 
Patterns in Terraform 12+13: Data, Transformations and Resources
Patterns in Terraform 12+13: Data, Transformations and ResourcesPatterns in Terraform 12+13: Data, Transformations and Resources
Patterns in Terraform 12+13: Data, Transformations and Resources
 
Perl object ?
Perl object ?Perl object ?
Perl object ?
 
Productive Programming in Groovy
Productive Programming in GroovyProductive Programming in Groovy
Productive Programming in Groovy
 
Corephpcomponentpresentation 1211425966721657-8
Corephpcomponentpresentation 1211425966721657-8Corephpcomponentpresentation 1211425966721657-8
Corephpcomponentpresentation 1211425966721657-8
 
MongoDB: Replication,Sharding,MapReduce
MongoDB: Replication,Sharding,MapReduceMongoDB: Replication,Sharding,MapReduce
MongoDB: Replication,Sharding,MapReduce
 
Topological indices (t is) of the graphs to seek qsar models of proteins com...
Topological indices (t is) of the graphs  to seek qsar models of proteins com...Topological indices (t is) of the graphs  to seek qsar models of proteins com...
Topological indices (t is) of the graphs to seek qsar models of proteins com...
 
groovy databases
groovy databasesgroovy databases
groovy databases
 
Testing stateful, concurrent, and async systems using test.check
Testing stateful, concurrent, and async systems using test.checkTesting stateful, concurrent, and async systems using test.check
Testing stateful, concurrent, and async systems using test.check
 
Inside MongoDB: the Internals of an Open-Source Database
Inside MongoDB: the Internals of an Open-Source DatabaseInside MongoDB: the Internals of an Open-Source Database
Inside MongoDB: the Internals of an Open-Source Database
 
Unit testing pig
Unit testing pigUnit testing pig
Unit testing pig
 
The journey of an (un)orthodox optimization
The journey of an (un)orthodox optimizationThe journey of an (un)orthodox optimization
The journey of an (un)orthodox optimization
 
Bash Learning By Examples
Bash Learning By ExamplesBash Learning By Examples
Bash Learning By Examples
 
MongoDB Aggregation
MongoDB Aggregation MongoDB Aggregation
MongoDB Aggregation
 
Redis for the Everyday Developer
Redis for the Everyday DeveloperRedis for the Everyday Developer
Redis for the Everyday Developer
 
Solr & Lucene @ Etsy by Gregg Donovan
Solr & Lucene @ Etsy by Gregg DonovanSolr & Lucene @ Etsy by Gregg Donovan
Solr & Lucene @ Etsy by Gregg Donovan
 

Ähnlich wie Terraform for fun and profit

Yy
YyYy
Yy
yygh
 
Yy
YyYy
Yy
yygh
 
Nouveau document texte
Nouveau document texteNouveau document texte
Nouveau document texte
Sai Ef
 

Ähnlich wie Terraform for fun and profit (20)

Wsomdp
WsomdpWsomdp
Wsomdp
 
Integrating icinga2 and the HashiCorp suite
Integrating icinga2 and the HashiCorp suiteIntegrating icinga2 and the HashiCorp suite
Integrating icinga2 and the HashiCorp suite
 
Hidden treasures of Ruby
Hidden treasures of RubyHidden treasures of Ruby
Hidden treasures of Ruby
 
Writing Modular Command-line Apps with App::Cmd
Writing Modular Command-line Apps with App::CmdWriting Modular Command-line Apps with App::Cmd
Writing Modular Command-line Apps with App::Cmd
 
Simple Ways To Be A Better Programmer (OSCON 2007)
Simple Ways To Be A Better Programmer (OSCON 2007)Simple Ways To Be A Better Programmer (OSCON 2007)
Simple Ways To Be A Better Programmer (OSCON 2007)
 
Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4
 
C99
C99C99
C99
 
Open Source Search: An Analysis
Open Source Search: An AnalysisOpen Source Search: An Analysis
Open Source Search: An Analysis
 
Yy
YyYy
Yy
 
Yy
YyYy
Yy
 
Nouveau document texte
Nouveau document texteNouveau document texte
Nouveau document texte
 
Nagios Conference 2013 - Sheeri Cabral - Alerting With MySQL and Nagios
Nagios Conference 2013 - Sheeri Cabral - Alerting With MySQL and NagiosNagios Conference 2013 - Sheeri Cabral - Alerting With MySQL and Nagios
Nagios Conference 2013 - Sheeri Cabral - Alerting With MySQL and Nagios
 
Modern Perl
Modern PerlModern Perl
Modern Perl
 
zinno
zinnozinno
zinno
 
Drush. Secrets come out.
Drush. Secrets come out.Drush. Secrets come out.
Drush. Secrets come out.
 
What's New in Perl? v5.10 - v5.16
What's New in Perl?  v5.10 - v5.16What's New in Perl?  v5.10 - v5.16
What's New in Perl? v5.10 - v5.16
 
Perl basics for pentesters part 2
Perl basics for pentesters part 2Perl basics for pentesters part 2
Perl basics for pentesters part 2
 
6 things about perl 6
6 things about perl 66 things about perl 6
6 things about perl 6
 
Cod
CodCod
Cod
 
Fisier.txt
Fisier.txtFisier.txt
Fisier.txt
 

Mehr von Bram Vogelaar

Observability; a gentle introduction
Observability; a gentle introductionObservability; a gentle introduction
Observability; a gentle introduction
Bram Vogelaar
 

Mehr von Bram Vogelaar (20)

Cost reconciliation in a post CMDB world
Cost reconciliation in a post CMDB worldCost reconciliation in a post CMDB world
Cost reconciliation in a post CMDB world
 
Self scaling Multi cloud nomad workloads
Self scaling Multi cloud nomad workloadsSelf scaling Multi cloud nomad workloads
Self scaling Multi cloud nomad workloads
 
Scraping metrics for fun and profit
Scraping metrics for fun and profitScraping metrics for fun and profit
Scraping metrics for fun and profit
 
10 things i learned building nomad-packs
10 things i learned building nomad-packs10 things i learned building nomad-packs
10 things i learned building nomad-packs
 
10 things I learned building Nomad packs
10 things I learned building Nomad packs10 things I learned building Nomad packs
10 things I learned building Nomad packs
 
Easy Cloud Native Transformation with Nomad
Easy Cloud Native Transformation with NomadEasy Cloud Native Transformation with Nomad
Easy Cloud Native Transformation with Nomad
 
Uncomplicated Nomad
Uncomplicated NomadUncomplicated Nomad
Uncomplicated Nomad
 
Observability; a gentle introduction
Observability; a gentle introductionObservability; a gentle introduction
Observability; a gentle introduction
 
Running Trusted Payload with Nomad and Waypoint
Running Trusted Payload with Nomad and WaypointRunning Trusted Payload with Nomad and Waypoint
Running Trusted Payload with Nomad and Waypoint
 
Easy Cloud Native Transformation using HashiCorp Nomad
Easy Cloud Native Transformation using HashiCorp NomadEasy Cloud Native Transformation using HashiCorp Nomad
Easy Cloud Native Transformation using HashiCorp Nomad
 
Securing Prometheus exporters using HashiCorp Vault
Securing Prometheus exporters using HashiCorp VaultSecuring Prometheus exporters using HashiCorp Vault
Securing Prometheus exporters using HashiCorp Vault
 
CICD using jenkins and Nomad
CICD using jenkins and NomadCICD using jenkins and Nomad
CICD using jenkins and Nomad
 
Bootstrapping multidc observability stack
Bootstrapping multidc observability stackBootstrapping multidc observability stack
Bootstrapping multidc observability stack
 
Running trusted payloads with Nomad and Waypoint
Running trusted payloads with Nomad and WaypointRunning trusted payloads with Nomad and Waypoint
Running trusted payloads with Nomad and Waypoint
 
Gamification of Chaos Testing
Gamification of Chaos TestingGamification of Chaos Testing
Gamification of Chaos Testing
 
Puppet and the HashiStack
Puppet and the HashiStackPuppet and the HashiStack
Puppet and the HashiStack
 
Bootstrapping multidc observability stack
Bootstrapping multidc observability stackBootstrapping multidc observability stack
Bootstrapping multidc observability stack
 
Creating Reusable Puppet Profiles
Creating Reusable Puppet ProfilesCreating Reusable Puppet Profiles
Creating Reusable Puppet Profiles
 
Gamification of Chaos Testing
Gamification of Chaos TestingGamification of Chaos Testing
Gamification of Chaos Testing
 
Autoscaling with hashi_corp_nomad
Autoscaling with hashi_corp_nomadAutoscaling with hashi_corp_nomad
Autoscaling with hashi_corp_nomad
 

Kürzlich hochgeladen

Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 

Kürzlich hochgeladen (20)

Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation Strategies
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 

Terraform for fun and profit

  • 1. Terraform for fun and profit @attachmentgenie
  • 2. ~$ 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
  • 3. The other IaCThe other IaC
  • 4. HCLHCL ● Hashicorp Configuration LanguageHashicorp Configuration Language ● Yet another cfgmgmt DSLYet another cfgmgmt DSL ● Desired stateDesired state
  • 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}"}"]] }}
  • 6. ProvidersProviders ● https://www.terraform.io/docs/providers/index.htmhttps://www.terraform.io/docs/providers/index.htm ● Many, many, many optionsMany, many, many options – Cloud providersCloud providers – Dns providerDns provider – gitlabgitlab ● Add your own as a pluginAdd your own as a plugin
  • 7. PluginsPlugins ● https://github.com/terraform-providershttps://github.com/terraform-providers providerprovider "godaddy""godaddy" {{ keykey == "${var."${var.gd_keygd_key}"}" secretsecret == "${var."${var.gd_secretgd_secret}"}" }}
  • 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
  • 15. Terraform fmtTerraform fmt The solution to tabs vs spacesThe solution to tabs vs spaces
  • 16. Terraform validateTerraform validate ● Think linting ++Think linting ++
  • 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