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

Cologne.rb - A brief introduction to Terraform ...

Cologne.rb - A brief introduction to Terraform and Packer

A short introduction into Terraform and Packer.

Dirk Breuer

July 15, 2015
Tweet

More Decks by Dirk Breuer

Other Decks in Technology

Transcript

  1. Challenges • Increasingly complex infrastructure to setup • Multiple environments

    for testing and production • Evolution / Changing of infrastructure • Documentation of infrastructure • More then one server involved
  2. Opportunities • Infrastructure on demand • API for all infrastructure

    components (with AWS and others) • Extremely powerful hardware is very cheap • Virtualization
  3. Tools like Puppet and Chef • Stops at machine boundary

    • Mostly imperative (a.k.a. still a lot like scripting) • Converging a system into a new state is NOT trivial
  4. Packer „Packer is a tool for creating machine and container

    images for multiple platforms from a single source configuration.“ – Packer Website (http://www.packer.io)
  5. Packer • Treat server as immutable • Any configuration change

    results in a completely new server • Allows for easier tools then Chef or Puppet • JSON configuration language
  6. Templates { "builders": [], "description": "A packer example template", "min_packer_version":

    "0.8.0", "provisioners": [], "post-processors": [], "variables": [] }
  7. { "builders": [ { "type": "virtualbox-ovf", "boot_wait": "10s", "headless": true,

    "source_path": "builds/fejo-virtualbox-base/fejo-next-base-vbox.ovf", "ssh_username": "vagrant", "ssh_password": "vagrant", "ssh_port": 22, "ssh_wait_timeout": "10000s", "shutdown_command": "echo 'shutdown -P now' > sd.sh; echo 'vagrant'|sudo -S bash 'sd.sh'" }, { "type": "vmware-vmx" } ] }
  8. { "provisioners": [ { "type": "ansible-local", "playbook_file": "ansible/development.yml", "inventory_file": "ansible/inventory",

    "playbook_dir": "ansible", "override": { "virtualbox-ovf": { "command": "sudo ansible-playbook", "extra_arguments": ["-e main_user=vagrant"] } } } ] }
  9. { "builders": [ { "type": "amazon-ebs", "access_key": "{{user `aws_access_key`}}", "secret_key":

    "{{user `aws_secret_key`}}", "region": "eu-central-1", "source_ami": "ami-00dae61d", "instance_type": "t2.micro", "ssh_username": "ubuntu", "ami_name": "dev-{{ timestamp | clean_ami_name }}", "tags": { "Name": "Fejo AWS Staging Box" } } ], „provisioners": [], "variables": { "aws_access_key_id": "", "aws_secret_access_key": "" } }
  10. Terraform „Terraform provides a common configuration to launch infrastructure […].

    Once launched, Terraform safely and efficiently changes infrastructure as the configuration is evolved.“ – Terraform Website (http://www.terraform.io)
  11. Terraform • Describe infrastructure in a declarative way • Keep

    track of changes to the infrastructure • Changing infrastructure is accessible to entire team • Rollback your infrastructure to a previous point • HashiCorp Configuration Language (HCL)
  12. Configuration provider "aws" { access_key = "${var.aws_access_key_id}" secret_key = "${var.aws_secret_access_key}"

    region = "${var.region}" } ! resource "aws_instance" "staging_web" { ami = "${lookup(var.staging_amis, var.region)}" instance_type = "t2.micro" security_groups = ["default"] ! tags { Name = "staging_web" Project = "fejo" Roles = "web,db" Stages = "staging" } }
  13. Example • Setup an ELB • Configure TLS certificate •

    Setup EC2 instance to run the application • Connect the EC2 instance as listener for the ELB • Setup an RDS instance • Setup up required security groups • Register a DNS entry for the ELB
  14. resource "aws_elb" "staging_elb" { depends_on = [„aws_security_group.staging_elb_web", "aws_iam_server_certificate.example"] name =

    "staging-elb" availability_zones = ["eu-central-1a", "eu-central-1b"] ! listener { instance_port = 80 instance_protocol = "http" lb_port = 443 lb_protocol = "https" ssl_certificate_id = "${aws_iam_server_certificate.example.arn}" } ! health_check { target = "HTTP:80/status_check" } ! security_groups = [„${aws_security_group.staging_elb.id}", "${aws_security_group.staging_elb_web.id}"] instances = ["${aws_instance.staging_web.id}"] }
  15. resource "aws_iam_server_certificate" "example" { name = „example_cert" certificate_body = "${file("ansible/certificates/example.pem")}"

    certificate_chain = "${file("ansible/certificates/example-bundle.pem")}" private_key = "${file("ansible/secrets/example.pem")}" }
  16. resource "aws_instance" "staging_web" { depends_on = [„aws_security_group.staging_web", „aws_iam_role.staging_ec2", "aws_security_group.staging_elb_web"] ami

    = "${lookup(var.staging_amis, var.region)}" instance_type = "t2.micro" security_groups = [„default", „${aws_security_group.staging_web.name}", "${aws_security_group.staging_elb_web.name}"] ! iam_instance_profile = "staging-ec2" tags { Name = "staging_web" Project = "fejo" Roles = "web,db" Stages = "staging" } }
  17. resource "aws_db_instance" "staging_db" { depends_on = "aws_security_group.staging_db" identifier = "staging-db"

    allocated_storage = "5" engine = "postgres" engine_version = "9.4.1" storage_type = "gp2" instance_class = "db.t2.small" name = "fejo_staging" username = "${var.db_username}" password = "${var.staging_db_password}" vpc_security_group_ids = ["${aws_security_group.staging_db.id}"] db_subnet_group_name = "${aws_db_subnet_group.staging_db.id}" }
  18. resource "aws_route53_record" "staging_web" { zone_id = „${var.route53_example_com_zone_id}" name = „staging.example.com"

    type = "A" ! alias { name = "${aws_elb.staging_elb.dns_name}" zone_id = "${aws_elb.staging_elb.zone_id}" evaluate_target_health = true } }