<< Photos

An intro to Docker, Terraform, and Amazon ECS - Comment

This talk is a very quick intro to Docker, Terraform, and Amazon's EC2 Container Service (ECS). In just 15 minutes, you'll see how to take two apps (a Rails frontend and a Sinatra backend), package them as Docker containers, run them using Amazon ECS, and to define all of the infrastructure-as-code using Terraform.

Topics covered:


1. A quick intro to Docker, Terraform, and Amazon ECS TERRAFORM Amazon ECS
2. In this talk, we’ll show how to deploy two apps:
3. A Rails Frontend and a Sinatra Backend
4. Slides and code from this talk: ybrikman.com/speaking
5. require 'sinatra' get "/" do "Hello, World!" end The sinatra backend just returns “Hello, World”.
6. class ApplicationController < ActionController::Base def index url = URI.parse(backend_addr) req = Net::HTTP::Get.new(url.to_s) res = Net::HTTP.start(url.host, url.port) {|http| http.request(req) } @text = res.body end end The rails frontend calls the sinatra backend…
7. Rails Frontend Response from the backend: And renders the response as HTML.
8. We’ll package the two apps as Docker containers…
9. Amazon ECS Deploy those Docker containers using Amazon ECS…
10. TERRAFORM And define our infrastructure-as- code using Terraform.
11. I’m Yevgeniy Brikman ybrikman.com
12. Co-founder of Gruntwork gruntwork.io
13. gruntwork.io We offer DevOps as a Service
14. gruntwork.io And DevOps as a Library
15. PAST LIVES
16. Author of Hello, Startup hello-startup.net
17. And Terraform: Up & Running terraformupandrunning.com
18. 1. Docker 2. Terraform 3. ECS 4. Recap Outline
19. 1. Docker 2. Terraform 3. ECS 4. Recap Outline
20. Docker allows you to build and run code in containers
21. Containers are like lightweight Virtual Machines (VMs)
22. Like an isolated process that happens to be an entire OS
23. > docker run –it ubuntu bash root@12345:/# echo "I'm in $(cat /etc/issue)” I'm in Ubuntu 14.04.4 LTS Running an Ubuntu image in a Docker container
24. > time docker run ubuntu echo "Hello, World" Hello, World real 0m0.183s user 0m0.009s sys 0m0.014s Containers boot quickly, with minimal CPU/memory overhead
25. You can define a Docker image as code in a Dockerfile
26. FROM gliderlabs/alpine:3.3 RUN apk --no-cache add ruby ruby-dev RUN gem install sinatra --no-ri --no-rdoc RUN mkdir -p /usr/src/app COPY . /usr/src/app WORKDIR /usr/src/app EXPOSE 4567 CMD ["ruby", "app.rb"] Here is the Dockerfile for the Sinatra backend
27. FROM gliderlabs/alpine:3.3 RUN apk --no-cache add ruby ruby-dev RUN gem install sinatra --no-ri --no-rdoc RUN mkdir -p /usr/src/app COPY . /usr/src/app WORKDIR /usr/src/app EXPOSE 4567 CMD ["ruby", "app.rb"] It specifies dependencies, code, config, and how to run the app
28. > docker build -t gruntwork/sinatra-backend . Step 0 : FROM gliderlabs/alpine:3.3 ---> 0a7e169bce21 (...) Step 8 : CMD ruby app.rb ---> 2e243eba30ed Successfully built 2e243eba30ed Build the Docker image
29. > docker run -it -p 4567:4567 gruntwork/sinatra-backend INFO WEBrick 1.3.1 INFO ruby 2.2.4 (2015-12-16) [x86_64-linux-musl] == Sinatra (v1.4.7) has taken the stage on 4567 for development with backup from WEBrick INFO WEBrick::HTTPServer#start: pid=1 port=4567 Run the Docker image
30. > docker push gruntwork/sinatra-backend The push refers to a repository [docker.io/gruntwork/sinatra- backend] (len: 1) 2e243eba30ed: Image successfully pushed 7e2e0c53e246: Image successfully pushed 919d9a73b500: Image successfully pushed (...) v1: digest: sha256:09f48ed773966ec7fe4558 size: 14319 You can share your images by pushing them to Docker Hub
31. Now you can reuse the same image in dev, stg, prod, etc
32. > docker pull rails:4.2.6 And you can reuse images created by others.
33. FROM rails:4.2.6 RUN mkdir -p /usr/src/app COPY . /usr/src/app WORKDIR /usr/src/app RUN bundle install EXPOSE 3000 CMD ["rails", "start"] The rails-frontend is built on top of the official rails Docker image
34. rails_frontend: image: gruntwork/rails-frontend ports: - "3000:3000" links: - sinatra_backend sinatra_backend: image: gruntwork/sinatra-backend ports: - "4567:4567" Define your entire dev stack as code with docker-compose
35. rails_frontend: image: gruntwork/rails-frontend ports: - "3000:3000" links: - sinatra_backend sinatra_backend: image: gruntwork/sinatra-backend ports: - "4567:4567" Docker links provide a simple service discovery mechanism
36. > docker-compose up Starting infrastructureascodetalk_sinatra_backend_1 Recreating infrastructureascodetalk_rails_frontend_1 sinatra_backend_1 | INFO WEBrick 1.3.1 sinatra_backend_1 | INFO ruby 2.2.4 (2015-12-16) sinatra_backend_1 | Sinatra has taken the stage on 4567 rails_frontend_1 | INFO WEBrick 1.3.1 rails_frontend_1 | INFO ruby 2.3.0 (2015-12-25) rails_frontend_1 | INFO WEBrick::HTTPServer#start: port=3000 Run your entire dev stack with one command
37. 1. Docker 2. Terraform 3. ECS 4. Recap Outline
38. Terraform is a tool for provisioning infrastructure
39. Terraform supports many providers (cloud agnostic)
40. And many resources for each provider
41. You define infrastructure as code in Terraform templates
42. provider "aws" { region = "us-east-1" } resource "aws_instance" "example" { ami = "ami-408c7f28" instance_type = "t2.micro" } This template creates a single EC2 instance in AWS
43. > terraform plan + aws_instance.example ami: "" => "ami-408c7f28" instance_type: "" => "t2.micro" key_name: "" => "" private_ip: "" => "" public_ip: "" => "" Plan: 1 to add, 0 to change, 0 to destroy. Use the plan command to see what you’re about to deploy
44. > terraform apply aws_instance.example: Creating... ami: "" => "ami-408c7f28" instance_type: "" => "t2.micro" key_name: "" => "" private_ip: "" => "" public_ip: "" => "” aws_instance.example: Creation complete Apply complete! Resources: 1 added, 0 changed, 0 destroyed. Use the apply command to apply the changes
45. Now our EC2 instance is running!
46. resource "aws_instance" "example" { ami = "ami-408c7f28" instance_type = "t2.micro" tags { Name = "terraform-example" } } Let’s give the EC2 instance a tag with a readable name
47. > terraform plan ~ aws_instance.example tags.#: "0" => "1" tags.Name: "" => "terraform-example" Plan: 0 to add, 1 to change, 0 to destroy. Use the plan command again to verify your changes
48. > terraform apply aws_instance.example: Refreshing state... aws_instance.example: Modifying... tags.#: "0" => "1" tags.Name: "" => "terraform-example" aws_instance.example: Modifications complete Apply complete! Resources: 0 added, 1 changed, 0 destroyed. Use the apply command again to deploy those changes
49. Now our EC2 instance has a tag!
50. resource "aws_elb" "example" { name = "example" availability_zones = ["us-east-1a", "us-east-1b"] instances = ["${aws_instance.example.id}"] listener { lb_port = 80 lb_protocol = "http" instance_port = "${var.instance_port}" instance_protocol = "http” } } Let’s add an Elastic Load Balancer (ELB).
51. resource "aws_elb" "example" { name = "example" availability_zones = ["us-east-1a", "us-east-1b"] instances = ["${aws_instance.example.id}"] listener { lb_port = 80 lb_protocol = "http" instance_port = "${var.instance_port}" instance_protocol = "http” } } Terraform supports variables, such as var.instance_port
52. resource "aws_elb" "example" { name = "example" availability_zones = ["us-east-1a", "us-east-1b"] instances = ["${aws_instance.example.id}"] listener { lb_port = 80 lb_protocol = "http" instance_port = "${var.instance_port}" instance_protocol = "http" } } As well as dependencies like aws_instance.example.id
53. resource "aws_elb" "example" { name = "example" availability_zones = ["us-east-1a", "us-east-1b"] instances = ["${aws_instance.example.id}"] listener { lb_port = 80 lb_protocol = "http" instance_port = "${var.instance_port}" instance_protocol = "http" } } It builds a dependency graph and applies it in parallel.
54. After running apply, we have an ELB!
55. > terraform destroy aws_instance.example: Refreshing state... (ID: i-f3d58c70) aws_elb.example: Refreshing state... (ID: example) aws_elb.example: Destroying... aws_elb.example: Destruction complete aws_instance.example: Destroying... aws_instance.example: Destruction complete Apply complete! Resources: 0 added, 0 changed, 2 destroyed. Use the destroy command to delete all your resources
56. For more info, check out The Comprehensive Guide to Terraform
57. 1. Docker 2. Terraform 3. ECS 4. Recap Outline
58. EC2 Container Service (ECS) is a way to run Docker on AWS
59. ECS Overview EC2 Instance ECS Cluster ECS Scheduler ECS Agent ECS Tasks ECS Task Definition { "cluster": "example", "serviceName": ”foo", "taskDefinition": "", "desiredCount": 2 } ECS Service Definition { "name": "example", "image": "foo/example", "cpu": 1024, "memory": 2048, "essential": true, }
60. ECS Cluster: several servers managed by ECS EC2 Instance ECS Cluster
61. Typically, the servers are in an Auto Scaling Group Auto Scaling Group EC2 Instance
62. Each server must run the ECS Agent ECS Agent EC2 Instance ECS Cluster
63. ECS Task: Docker container(s) to run, resources they need { "name": "example", "image": "foo/example", "cpu": 1024, "memory": 2048, "essential": true, } ECS Agent EC2 Instance ECS Task Definition ECS Cluster
64. ECS Service: long-running ECS Task & ELB settings { "name": "example", "image": "foo/example", "cpu": 1024, "memory": 2048, "essential": true, } { "cluster": "example", "serviceName": ”foo", "taskDefinition": "", "desiredCount": 2 } ECS Agent EC2 Instance ECS Task Definition ECS Service Definition ECS Cluster
65. ECS Scheduler: Deploys Tasks across the ECS Cluster { "name": "example", "image": "foo/example", "cpu": 1024, "memory": 2048, "essential": true, } { "cluster": "example", "serviceName": ”foo", "taskDefinition": "", "desiredCount": 2 } ECS Agent ECS Tasks EC2 Instance ECS Task Definition ECS Service Definition ECS Scheduler ECS Cluster
66. You can associate an ALB or ELB with each ECS service { "name": "example", "image": "foo/example", "cpu": 1024, "memory": 2048, "essential": true, } { "cluster": "example", "serviceName": ”foo", "taskDefinition": "", "desiredCount": 2 } ECS Agent ECS Tasks EC2 Instance ECS Task Definition ECS Service Definition ECS Cluster
67. This allows you to distribute load across your ECS Tasks { "name": "example", "image": "foo/example", "cpu": 1024, "memory": 2048, "essential": true, } { "cluster": "example", "serviceName": ”foo", "taskDefinition": "", "desiredCount": 2 } ECS Agent ECS Tasks EC2 Instance ECS Task Definition ECS Service Definition ECS Cluster
68. You can also use it as a simple form of service discovery { "name": "example", "image": "foo/example", "cpu": 1024, "memory": 2048, "essential": true, } { "cluster": "example", "serviceName": ”foo", "taskDefinition": "", "desiredCount": 2 } ECS Agent ECS Tasks EC2 Instance ECS Task Definition ECS Service Definition ECS Cluster
69. Let’s deploy our apps on ECS using Terraform
70. Define the ECS Cluster as an Auto Scaling Group (ASG) EC2 Instance ECS Cluster
71. resource "aws_ecs_cluster" "example_cluster" { name = "example-cluster" } resource "aws_autoscaling_group" "ecs_cluster_instances" { name = "ecs-cluster-instances" min_size = 5 max_size = 5 launch_configuration = "${aws_launch_configuration.ecs_instance.name}" }
72. Ensure each server in the ASG runs the ECS Agent ECS Agent EC2 Instance ECS Cluster
73. # The launch config defines what runs on each EC2 instance resource "aws_launch_configuration" "ecs_instance" { name_prefix = "ecs-instance-" instance_type = "t2.micro" # This is an Amazon ECS AMI, which has an ECS Agent # installed that lets it talk to the ECS cluster image_id = "ami-a98cb2c3” } The launch config runs AWS ECS Linux on each server in the ASG
74. Define an ECS Task for each microservice { "name": "example", "image": "foo/example", "cpu": 1024, "memory": 2048, "essential": true, } ECS Agent EC2 Instance ECS Task Definition ECS Cluster
75. resource "aws_ecs_task_definition" "rails_frontend" { family = "rails-frontend" container_definitions =

Posted by :  peter88 Post date :  2020-01-06 15:43
Category :  Technology Views :  378

Comment - Previous - Next - Bookmark This
Social Bookmark or Share this page

peter88 last post Image
- Wallpaper dump that wont break your computer
- My personal wallpaper collection
- My Wallpapers - enjoy them as I have!
- Wallpaper Drop! Get'em while they're hot!
- Big-ass Wallpaper Dump 1000 Images
- 1234 High Resolution Backgrounds
- 4,333 Desktop Backgrounds 1920x1080 or Higher
- 3176 Images of High Resolution Wallpaper Dump
- 575 Wallpapers (All 1080p, No watermarks)
- Small Map Dump
- Map Dump based on Survey
- Interesting maps/information dump (Roman Edition)
- Sizeable Map Dump
- Random map dump
- Interesting maps/information dump


New Comment