Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Applying Graph Theory to Infrastructure As Code

Applying Graph Theory to Infrastructure As Code

As given at HashiConf EU 2016 in Amsterdam

Graphs are mathematical structures used to model relationships between objects. Modern infrastructures can be thought of as graphs — compute resource depend on network resources, which in turn depend on access control resources, and so on. At a certain scale, the relationships between all resources in an infrastructure become impractical to reason about.

Terraform builds a graph to model the relationships between resources so operators can safely manage and change infrastructure resources across bare metal, IaaS, PasS, and SaaS. Terraform models and potentially prevents that simple change with unforeseen consequences so operators don't have to.

In this talk, we will explore the graph theory at the heart of Terraform's orchestration engine.

Paul Hinze

June 14, 2016
Tweet

More Decks by Paul Hinze

Other Decks in Technology

Transcript

  1. 535 :global_includes, 536 :gmail_domain 537 ].each do |key| 538 params[:account][:settings].try(:delete,

    key) 539 end 540 end 541 542 if params[:account][:settings] && params[:account][:settings].has_key?(:trusted_referers) 543 if trusted_referers = params[:account][:settings].delete(:trusted_referers) 544 @account.trusted_referers = trusted_referers if @account.root_account? 545 end 546 end 547 548 if sis_id = params[:account].delete(:sis_source_id) 549 if [email protected]_account? && sis_id != @account.sis_source_id && @account.root_account.grant 550 if sis_id == '' 551 @account.sis_source_id = nil 552 else 553 @account.sis_source_id = sis_id 554 end 555 end 556 end 557 558 process_external_integration_keys 559 560 can_edit_email = params[:account][:settings].try(:delete, :edit_institution_email) 561 if @account.root_account? && !can_edit_email.nil? 562 @account[:settings][:edit_institution_email] = value_to_boolean(can_edit_email) 563 end 564 565 if @account.update_attributes(params[:account]) 566 format.html { redirect_to account_settings_url(@account) } 567 format.json { render :json => @account } 568 else 569 flash[:error] = t(:update_failed_notice, "Account settings update failed") 570 format.html { redirect_to account_settings_url(@account) } 571 format.json { render :json => @account.errors, :status => :bad_request } 572 end 573 end 574 end 575 end 576 577 def settings 578 if authorized_action(@account, @current_user, :read) 579 @available_reports = AccountReport.available_reports if @account.grants_right?(@current_user, @se 580 if @available_reports 581 @last_complete_reports = {} 582 @last_reports = {} 583 if AccountReport.connection.adapter_name == 'PostgreSQL' 584 scope = @account.account_reports.select("DISTINCT ON (report_type) account_reports.*").order( 585 @last_complete_reports = scope.last_complete_of_type(@available_reports.keys, nil).preload(:a 586 @last_reports = scope.last_of_type(@available_reports.keys, nil).index_by(&:report_type) 587 else 588 @available_reports.keys.each do |report| 589 @last_complete_reports[report] = @account.account_reports.last_complete_of_type(report).fir 590 @last_reports[report] = @account.account_reports.last_of_type(report).first 591 end 592 end 593 end 594 load_course_right_side 595 @account_users = @account.account_users 596 ActiveRecord::Associations::Preloader.new(@account_users, user: :communication_channels).run 597 order_hash = {} 598 @account.available_account_roles.each_with_index do |role, idx| 599 order_hash[role.id] = idx 600 end 601 @account_users = @account_users.select(&:user).sort_by{|au| [order_hash[au.role_id] || CanvasSort 602 @alerts = @account.alerts HASHICORP
  2. 535 :global_includes, 536 :gmail_domain 537 ].each do |key| 538 params[:account][:settings].try(:delete,

    key) 539 end 540 end 541 542 if params[:account][:settings] && params[:account][:settings].has_key?(:trusted_referers) 543 if trusted_referers = params[:account][:settings].delete(:trusted_referers) 544 @account.trusted_referers = trusted_referers if @account.root_account? 545 end 546 end 547 548 if sis_id = params[:account].delete(:sis_source_id) 549 if [email protected]_account? && sis_id != @account.sis_source_id && @account.root_account.grant 550 if sis_id == '' 551 @account.sis_source_id = nil 552 else 553 @account.sis_source_id = sis_id 554 end 555 end 556 end 557 558 process_external_integration_keys 559 560 can_edit_email = params[:account][:settings].try(:delete, :edit_institution_email) 561 if @account.root_account? && !can_edit_email.nil? 562 @account[:settings][:edit_institution_email] = value_to_boolean(can_edit_email) 563 end 564 565 if @account.update_attributes(params[:account]) 566 format.html { redirect_to account_settings_url(@account) } 567 format.json { render :json => @account } 568 else 569 flash[:error] = t(:update_failed_notice, "Account settings update failed") 570 format.html { redirect_to account_settings_url(@account) } 571 format.json { render :json => @account.errors, :status => :bad_request } 572 end 573 end 574 end 575 end 576 577 def settings 578 if authorized_action(@account, @current_user, :read) 579 @available_reports = AccountReport.available_reports if @account.grants_right?(@current_user, @se 580 if @available_reports 581 @last_complete_reports = {} 582 @last_reports = {} 583 if AccountReport.connection.adapter_name == 'PostgreSQL' 584 scope = @account.account_reports.select("DISTINCT ON (report_type) account_reports.*").order( 585 @last_complete_reports = scope.last_complete_of_type(@available_reports.keys, nil).preload(:a 586 @last_reports = scope.last_of_type(@available_reports.keys, nil).index_by(&:report_type) 587 else 588 @available_reports.keys.each do |report| 589 @last_complete_reports[report] = @account.account_reports.last_complete_of_type(report).fir 590 @last_reports[report] = @account.account_reports.last_of_type(report).first 591 end 592 end 593 end 594 load_course_right_side 595 @account_users = @account.account_users 596 ActiveRecord::Associations::Preloader.new(@account_users, user: :communication_channels).run 597 order_hash = {} 598 @account.available_account_roles.each_with_index do |role, idx| 599 order_hash[role.id] = idx 600 end 601 @account_users = @account_users.select(&:user).sort_by{|au| [order_hash[au.role_id] || CanvasSort 602 @alerts = @account.alerts HASHICORP Infrastructure as Code HASHICORP
  3. 535 :global_includes, 536 :gmail_domain 537 ].each do |key| 538 params[:account][:settings].try(:delete,

    key) 539 end 540 end 541 542 if params[:account][:settings] && params[:account][:settings].has_key?(:trusted_referers) 543 if trusted_referers = params[:account][:settings].delete(:trusted_referers) 544 @account.trusted_referers = trusted_referers if @account.root_account? 545 end 546 end 547 548 if sis_id = params[:account].delete(:sis_source_id) 549 if [email protected]_account? && sis_id != @account.sis_source_id && @account.root_account.grant 550 if sis_id == '' 551 @account.sis_source_id = nil 552 else 553 @account.sis_source_id = sis_id 554 end 555 end 556 end 557 558 process_external_integration_keys 559 560 can_edit_email = params[:account][:settings].try(:delete, :edit_institution_email) 561 if @account.root_account? && !can_edit_email.nil? 562 @account[:settings][:edit_institution_email] = value_to_boolean(can_edit_email) 563 end 564 565 if @account.update_attributes(params[:account]) 566 format.html { redirect_to account_settings_url(@account) } 567 format.json { render :json => @account } 568 else 569 flash[:error] = t(:update_failed_notice, "Account settings update failed") 570 format.html { redirect_to account_settings_url(@account) } 571 format.json { render :json => @account.errors, :status => :bad_request } 572 end 573 end 574 end 575 end 576 577 def settings 578 if authorized_action(@account, @current_user, :read) 579 @available_reports = AccountReport.available_reports if @account.grants_right?(@current_user, @se 580 if @available_reports 581 @last_complete_reports = {} 582 @last_reports = {} 583 if AccountReport.connection.adapter_name == 'PostgreSQL' 584 scope = @account.account_reports.select("DISTINCT ON (report_type) account_reports.*").order( 585 @last_complete_reports = scope.last_complete_of_type(@available_reports.keys, nil).preload(:a 586 @last_reports = scope.last_of_type(@available_reports.keys, nil).index_by(&:report_type) 587 else 588 @available_reports.keys.each do |report| 589 @last_complete_reports[report] = @account.account_reports.last_complete_of_type(report).fir 590 @last_reports[report] = @account.account_reports.last_of_type(report).first 591 end 592 end 593 end 594 load_course_right_side 595 @account_users = @account.account_users 596 ActiveRecord::Associations::Preloader.new(@account_users, user: :communication_channels).run 597 order_hash = {} 598 @account.available_account_roles.each_with_index do |role, idx| 599 order_hash[role.id] = idx 600 end 601 @account_users = @account_users.select(&:user).sort_by{|au| [order_hash[au.role_id] || CanvasSort 602 @alerts = @account.alerts HASHICORP
  4. Terraform's Internals: Provider API Separa>on Core Providers Providers Providers Upstream

    APIs Plugins Diff() Apply() Refresh() Create() Read() Update() Delete()
  5. Terraform's Internals: Core Concepts Config: Target Reality State: Current Reality

    Diff: {Config - State} Plan: Presents Diff Apply: Resolves Diff