Giter VIP home page Giter VIP logo

terraform-up-and-running-code's Introduction

Terraform: Up & Running Code

This repo contains the code samples for the book Terraform: Up and Running, by Yevgeniy Brikman.

Looking for the 1st, 2nd, or 3rd edition?

Terraform: Up & Running is now on its 3rd edition; all the code in master is for this edition. If you're looking for code examples for other editions, please see the following branches:

Quick start

All the code is in the code folder. The code examples are organized first by the tool or language and then by chapter. For example, if you're looking at an example of Terraform code in Chapter 2, you'll find it in the code/terraform/02-intro-to-terraform-syntax folder; if you're looking at an OPA (Rego) example in Chapter 9, you'll find it in the code/opa/09-testing-terraform-code folder.

Since this code comes from a book about Terraform, the vast majority of the code consists of Terraform examples in the code/terraform folder.

For instructions on running the code, please consult the README in each folder, and, of course, the Terraform: Up and Running book.

License

This code is released under the MIT License. See LICENSE.txt.

terraform-up-and-running-code's People

Contributors

brikis98 avatar jessegersensonchess avatar singhcoder avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

terraform-up-and-running-code's Issues

chapter 3 issue

Hello, i am currently using this book to learn Terraform.
I am currently Chapter 3, sub section: shared storage for state files.
I have entered the terrafrorm codes to create s3 bucket, dynamodb and to initialise remote backend but i keep getting errors.
please help me
this is my code

provider "aws" {
  region = "eu-west-1"
}
resource "aws_s3_bucket" "terraform_state" {
  bucket = "test-2020-bucket"

  lifecycle {
    prevent_destroy = true
  }


  versioning {
    enabled = true
  }

  server_side_encryption_configuration {
    rule {
      apply_server_side_encryption_by_default {
        sse_algorithm = "AES256"
      }
    }
  }
}

resource "aws_dynamodb_table" "locks-2020" {
  name         = "test-2020"
  billing_mode = "PAY_PER_REQUEST"
  hash_key     = "LockID"

  attribute {
    name = "LockID"
    type = "S"
  }

  tags = {
    Name = "dynamodb-table-1"
    Environment = "development"
  }
}

terraform {
  backend "s3" {
    bucket         = "terraform-test-"
    key            = "global/s3/terraform.tfstate"
    region         = "eu-west-1"
    dynamodb_table = "terraform-test"
    encrypt        = true
  }

}

Screenshot 2019-12-27 at 22 17 57

Error deleting S3 Bucket

at the end of chapter 3, after I ran terragrunt apply, I got this error:

  • aws_s3_bucket.terraform_state: Error deleting S3 Bucket: BucketNotEmpty: The bucket you tried to delete is not empty. You must delete all versions in the bucket.

what does it mean?
my server cluster access' the database.and I can open the browser.but I got the error.

chapter 03/04 data.terraform_remote_state.db

Using the code from chapter 03 and 04 I keep getting the following error:

data.terraform_remote_state.db: Refreshing state...
data.aws_availability_zones.all: Refreshing state...
Error running plan: 1 error(s) occurred:

  • data.template_file.user_data: 1 error(s) occurred:

  • data.template_file.user_data: Resource 'data.terraform_remote_state.db' does not have attribute 'address' for variable 'data.terraform_remote_state.db.address'

page 36 Chef Diagram adjustment

Hi!

Great work on getting a 2nd edition out and updated for 0.12. Just thought I'd flag up the the diagram on page 36 - The nomenclature isn't quite consistent with how chef would phrase this - see https://docs.chef.io/chef_overview.html. If you change out the chef users machine to chef workstation, the And the diagram the the target nodes could be labelled @app Server, each Running Chef-Client", that'd make more sense in reference to the published architecture.

Feel free to talk about how application automation is different from CM or IAC provisioning tools - there's a habitat provisioner for terraform just for that. ;)

Thanks,
Chris

Chef-infra_diagram

Tags args requires equals sign.

terraform-up-and-running-code/code/terraform/02-intro-to-terraform-syntax/one-server/
main.tf

Terraform 0.12 tags arguement requires an equals sign.

tags {
Name = "terraform-example"
}

tags = {
Name = "terraform-example"
}

Ch.2 webserver cluster instance duplicate error

Hello @brikis98

While wrapping up Ch.2, I have encountered the following error
`Error applying plan:

1 error(s) occurred:

  • aws_security_group.instance: Error creating Security Group: InvalidGroup.Duplicate: The security group 'terraform-example-instance' already exists for VPC '<vpc_id>
    status code: 400, request id: a7232801-b51d-4263-b69a-2ed4f17d08ea

Terraform does not automatically rollback in the face of errors.
Instead, your Terraform state file has been partially updated with
any resources that successfully completed. Please address the error
above and apply again to incrementally change your infrastructure.
`
I am not sure if this related to the version of terraform(see below) or a typo within my main.tf(which I have compared to your examples here)

terraform -v
Terraform v0.7.10

Your version of Terraform is out of date! The latest version
is 0.10.1. You can update by downloading from www.terraform.io

One-webserver example, unable to connect to the remote server

Hi I'm having some trouble with the curl.
This is the apply:

 aws_security_group.instance:**
 Creating...
  description:                         "" => "Managed by Terraform"
  egress.#:                            "" => "<computed>"
  ingress.#:                           "" => "1"
  ingress.516175195.cidr_blocks.#:     "" => "1"
  ingress.516175195.cidr_blocks.0:     "" => "0.0.0.0/0"
  ingress.516175195.from_port:         "" => "8080"
  ingress.516175195.protocol:          "" => "tcp"
  ingress.516175195.security_groups.#: "" => "0"
  ingress.516175195.self:              "" => "false"
  ingress.516175195.to_port:           "" => "8080"
  name:                                "" => "terraform-example-instance"
  owner_id:                            "" => "<computed>"
  vpc_id:                              "" => "<computed>"
aws_security_group.instance: Creation complete
aws_instance.example: Creating...
  ami:                              "" => "ami-09447c6f"
  associate_public_ip_address:      "" => "<computed>"
  availability_zone:                "" => "<computed>"
  ebs_block_device.#:               "" => "<computed>"
  ephemeral_block_device.#:         "" => "<computed>"
  instance_state:                   "" => "<computed>"
  instance_type:                    "" => "t2.micro"
  ipv6_addresses.#:                 "" => "<computed>"
  key_name:                         "" => "Prova"
  network_interface_id:             "" => "<computed>"
  placement_group:                  "" => "<computed>"
  private_dns:                      "" => "<computed>"
  private_ip:                       "" => "<computed>"
  public_dns:                       "" => "<computed>"
  public_ip:                        "" => "<computed>"
  root_block_device.#:              "" => "<computed>"
  security_groups.#:                "" => "<computed>"
  source_dest_check:                "" => "true"
  subnet_id:                        "" => "<computed>"
  tags.%:                           "" => "1"
  tags.Name:                        "" => "terraform-example"
  tenancy:                          "" => "<computed>"
  user_data:                        "" => "718365511cc3eeeb60b714adc44151cf32eaed5d"
  vpc_security_group_ids.#:         "" => "1"
  vpc_security_group_ids.927859495: "" => "sg-5dd56824"
aws_instance.example: Still creating... (10s elapsed)
aws_instance.example: Still creating... (20s elapsed)
aws_instance.example: Provisioning with 'local-exec'...
aws_instance.example: Creation complete
Apply complete! Resources: 1 added, 0 changed, 1 destroyed.

And this is the Instance:

resource "aws_instance" "example" {
  ami           = "ami-09447c6f"
  instance_type = "t2.micro"

  vpc_security_group_ids = ["${aws_security_group.instance.id}"]

    user_data = <<-EOF
            #!/bin/bash
            echo "Hello, World">> index.html
            nohup busybox httpd -f -p "8080"  &
          EOF

  tags {
    Name = "terraform-example"
  }

}

Issue getting first proof of concept running

Hey there,

Running though the book as my new gig is running terraform but i seem to be running into an issue with the initial busybox webserver,

its not a huge deal as i get what its meant to do, but figured id mention it as its the first example that may deter devs that have a less exp from going further thinking they may have done something wrong

attached is what i came up with incase its something silly on my part

provider "aws" {
  region = "us-east-2"
}

resource "aws_instance" "example1" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"

  tags = {
    Name = "example1"
  }

  vpc_security_group_ids = [aws_security_group.example1_instance.id]
  key_name               = "phyzical-ssh-key"
  user_data              = <<-EOF
                            #!/bin/bash
                            echo "Hello, World" > index.html
                            nohup busybox http -f -p 8080 &
                            EOF
}

resource "aws_security_group" "example1_instance" {
  name = "example1-instance"

  ingress {
    from_port   = 8080
    to_port     = 8080
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["123.123.123.123/32"]
  }
}

resource "aws_key_pair" "phyzical-ssh-key" {
  key_name   = "phyzical-ssh-key"
  public_key = file("~/.ssh/id_rsa.pub")
}

output "instance_ip" {
  description = "The public ip for ssh access"
  value       = aws_instance.example1.public_ip
}

if i jump on the server that is initialized and try to manually start busybox i get the following;

sudo busybox http -f -p 8080

http: applet not found

my google fu suggests its PATH issues/ compile issues with the image itself. but i could not succeed and have decided just progress further on in the book

Chapter 2 - webserver cluster - Terraform warning

terraform plan displays the following in 02-intro-to-terraform-syntax/webserver-cluster

Warning: "condition.0.values": [DEPRECATED] use 'host_header' or 'path_pattern' attribute instead
  on main.tf line 113, in resource "aws_lb_listener_rule" "asg":
 113: resource "aws_lb_listener_rule" "asg" {

Terraform v0.12.10
+ provider.aws v2.43.0
macOS 10.15.2

How do I get rid of this message?

Simple webserver example is not working

@brikis98 I am trying to run the example of a single webserver:

provider "aws" {
    region = "eu-west-3"
}

resource "aws_instance" "example" { 
    ami = "ami-03bca18cb3dc173c9"
    instance_type = "t2.micro"
    vpc_security_group_ids = ["${aws_security_group.instance.id}"]
    user_data = <<-EOF
                #!/bin/bash
                echo "Hello World">> index.html
                nohup busybox httpd -f -p "8080" &
                EOF
   tags {
        Name = "terraform-example"
    }
}

resource "aws_security_group" "instance" {
    name = "terraform-example-instance"

    ingress {
        from_port = 8080
        to_port = 8080
        protocol = "tcp"
        cidr_blocks = ["0.0.0.0/0"]
    }
}

output "public_ip" {
  value = "${aws_instance.example.public_ip}"
}

originally in the 2017 edition book the port number is without quotes (tried both options).

However still does not work.
curl http://35.181.26.107:8080
curl: (7) Failed to connect to 35.181.26.107 port 8080: Connection refused
Can you maybe take a look ?

Error launching source instance: InvalidAMIID.NotFound: The image id '[ami-0c55b159cbfafe1f0]'

Hello.

Using Deploy a Single Server as an example, I get an error.

`aws_instance.example: Creating...

Error: Error launching source instance: InvalidAMIID.NotFound: The image id '[ami-0c55b159cbfafe1f0]' does not exist
status code: 400, request id: f5e8a0a2-0de9-4476-ad8b-c3473f93532c

on main.tf line 5, in resource "aws_instance" "example":
5: resource "aws_instance" "example" {`

Destroying a module attempts to destroy read-only remote state too

I'm following the design approach in "Read-Only State" in Chapter 3, to pull in data from global IAM configuration. The problem I have is that if I try to destroy a configuration group, it also wants to destroy the remote state too. e.g. here is the destroy plan:

- module.server.aws_instance.instance
- module.server.aws_key_pair.keypair
- module.server.aws_route53_health_check.check
- module.server.aws_route53_record.geo
- module.server.aws_route53_record.record
- module.server.aws_security_group.production
- module.server.data.template_file.user_data
- module.server.data.terraform_remote_state.iam

(check out the last line)

In the module's main.tf, the data source is configured like this:

data "terraform_remote_state" "iam" {
  backend = "s3"

  config {
    bucket = "mybucket"
    key    = "global/iam/terraform.tfstate"
    region = "us-east-1"
  }
}

Is there a way to get this to work such that destroy will work?

metadat in terraform

Hi,

Is it possible to edit a bootstrap file in terraform?(like cloudformation)
I'd like to add endpoint of RDS to my wordpress_bootstrap bash file when my instance comes up.

user_data

I generate new bash script and put this line in my bash:
declare instance_address = $(curl http://169.254.169.254/latest/meta-data/public-hostname)

after (terraform plan)I got this error:
Error refreshing state: 1 error(s) occurred:

  • data.template_file.user_data: failed to render : 49:86: unknown variable accessed: instance_address

what is the problem?

Terraform can't change AWS region

Not sure if that's an expected behavior or kind of bug, but when I change an AWS region after the first instance was already deployed, the old instance is not deleted.

Here is an example. Consider the script from the 2nd chapter:

provider "aws" {
  region = "us-east-1"
}

resource "aws_instance" "example" {
  ami           = "ami-40d28157"
  instance_type = "t2.micro"
  vpc_security_group_ids = ["${aws_security_group.instance.id}"]

  user_data = <<-EOF
              #!/bin/bash
              echo "Hello World!" > index.html
              nohup busybox httpd -f -p 8080 &
              EOF

  tags {
    Name = "terraform-example"
  }
}

resource "aws_security_group" "instance" {
  name = "terraform-example-instance"

  ingress = {
    from_port   = 8080
    to_port     = 8080
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

If you run terraform apply everything is fine. If you change anything, then these changes will be detected. However, try to replace region with something else like:

provider "aws" {
  region = "eu-west-1"
}

In this case, terraform plan doesn't say that one instance is destroyed and a new one created. It tries to create the second instance instead, and fails with error due to same ID or something.

Probably this moment should be mentioned somewhere in the book if this issue still exists in new versions of the Terraform, or probably the "provider" section is not covered with guarantee of being idempotent?

[Errata] Chapter 3, Page 74, MySQL database cannot be destroyed

Using the resource definition in Chapter 3, page 74 to create a MySQL db works fine, but due to missing parameters (and possible existing bugs in Terraform that there are open issues for) you will not be able to destroy the MySQL instance:

resource "aws_db_instance" "example" {
  engine = "mysql"
  allocated_storage = 10
  instance_class = "db.t2.micro"
  name = "example_database"
  username = "admin"
  password = "${var.db_password}"
}

The reason this cant be destroyed is because this resource (per documentation) expects the final_snapshot_identifier and/or the skip_final_snapshot parameters to be defined, as the default is to take a snapshot on destroy. However since we havent defined the snapshot identifier it throws an error. Unfortunately, adding skip_final-snapshot = true after having created the resource doesnt work (which may or may not be a bug according to the existing issue hashicorp/terraform#5417).

Therefore be sure to use the following for all examples:

resource "aws_db_instance" "example" {
  engine = "mysql"
  allocated_storage = 10
  instance_class = "db.t2.micro"
  name = "example_database"
  username = "admin"
  password = "${var.db_password}"
  skip_final_snapshot = true
}

02/one-webserver fails to repsond to curl

This fails to respond to any curl or browser.
Image is ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-20200112 (ami-07ebfd5b3428b6f4d)

terraform {
  required_version = ">= 0.12, < 0.13"
}

provider "aws" {
  region = "us-east-1"

  # Allow any 2.x version of the AWS provider
  version = "~> 2.0"
}

resource "aws_instance" "example" {
  ami                    = "ami-07ebfd5b3428b6f4d"
  instance_type          = "t2.micro"
  vpc_security_group_ids = [aws_security_group.instance.id]

  user_data = <<-EOF
              #!/bin/bash
              echo "Hello, World" > index.html
              nohup busybox httpd -f -p 8080 &
              EOF

  tags = {
    Name = "terraform-example"
  }
}

resource "aws_security_group" "instance" {

  name = var.security_group_name

  ingress {
    from_port   = 8080
    to_port     = 8080
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

variable "security_group_name" {
  description = "The name of the security group"
  type        = string
  default     = "terraform-example-instance"
}

output "public_ip" {
  value       = aws_instance.example.public_ip
  description = "The public IP of the Instance"
}

connection refused

curl http://18.234.77.22:8080
curl: (7) Failed to connect to 18.234.77.22 port 8080: Connection refused

Simple examples assume that account has default VPC

Simple examples silently assume that account (region) has default VPC. Simple examples use us-east-1, the oldest AWS region, so there is a chance that older account is "EC2-clasic" and doesn't have default VPC and related infrastructure.
That is difficult for beginner to fix these issues.

https://docs.aws.amazon.com/vpc/latest/userguide/default-vpc.html

That is my case, simple examples fail when I try them in region us-east-1. It is "difficult" to modify examples to use vpc-id, etc. The easiest workaround is to use different region, like us-east-2 (Ohio), that should have default VPC because it was added recently and default VPC is always there.

terragrunt version

Hi, amazing book !
Which version of terragrunt has been used with this book ? Would like to be as close as possible to examples.
Thanks :)

Default AWS Setup (availability_zones)

I've come across this problem, and a google seems to suggest others are too.
While something like the following is supposed to get your availability_zones, and use them, it can bail out if it finds a zone without a default subnet:

data "aws_availability_zones" "available" {
  state = "available"
}

I think your book uses 'all' instead? - Neither work.

This was because my account (maybe others, unsure with AWS) had access to us-east-1b, but that particular dc didn't have a default subnet.

I got around this problem using a hardcoded list:

variable "avail_zones" {
  description = "A list of availabilty zones to use:"
  type        = "list"
  default     = ["us-east-1a", "us-east-1d", "us-east-1e"]
}

I don't know if this is the best way to go around the problem (not if you don't like hard-coding things, and who does?) but it was the best I could see initially.


I don't know if it may be worth a note to this effect in the release version of the book?

Parsing error: heredoc not terminated

Hi Yevgeniy,

Thank you for the great book.

While trying to run the Single Web Server example from chapter 2, I've got a parsing error regarding heredoc <<-EOF ... EOF with terraform version 0.9.3:

Failed to load root config module: Error parsing ./TerraformBook/chapter2/single_server/main.tf: At 30:1: heredoc not terminated

I have to delete the hyphen in <<-EOF to make it pass which seems to be confirmed by the documentation of HCL: https://github.com/hashicorp/hcl#syntax

I'm on macOS.

Chapter 4 - database output

I didn't see any reference to this in the chapter, but after following the suggested exercise to move the mysql configuration into a module and deploy for prod (pg 116), the webserver-cluster deployments will fail as the address and port outputs aren't being called by the prod and stage configurations. You need to add an outputs.tf to both prod and stage configurations for mysql so that the webservice-cluster deployments can read the values from the mysql remote state.

Cannot connect to web server from chapter 2

curl fails to work like in the book

provider "aws" {
    version = "~> 2.0"
    region = "us-east-1"
}

resource "aws_instance" "example" {
    ami                     = "ami-0fc61db8544a617ed"
    instance_type           = "t2.micro" 
    vpc_security_group_ids  = [aws_security_group.inst.id]

    user_data = <<-EOF
                #!/bin/bash
                echo "Hello, world" > index.html
                nohup busybox https -f -p 8080 &
                EOF
}


resource "aws_security_group" "inst" {
    name = "terra_inst"
    ingress {
        from_port   = 8080
        to_port     = 8080
        protocol    = "tcp"
        cidr_blocks =["0.0.0.0/0"]
    }
}
curl http://54.152.181.11:8080
curl: (7) Failed to connect to 54.152.181.11 port 8080: Connection refused

Unable to deploy healthy instances once I start using variables in user_data

Following both your book and your updated git, I am unable to deploy healthy instances using the remote_state variables. I'm at a complete loss for what I'm missing.

resource "aws_launch_configuration" "example" {
    image_id = "${var.web_image_id}"
    instance_type = "t2.micro"
    security_groups = ["${aws_security_group.instance.id}"]
    user_data = <<-EOF
        #!/bin/bash
        echo "Hello,World" >> index.html
        echo "${data.terraform_remote_state.db.address}" >> index.html
        echo "${data.terraform_remote_state.db.port}" >> index.html
        nohup busybox httpd -f -p "${var.server_port}" &
        EOF

My remote_state:

data "terraform_remote_state" "db" {
  backend = "s3"

  config{
      bucket = "terraforming-up-and-running-state"
      key = "stage/data-stores/mysql/terraform.tfstate"
      region = "us-east-1"
      profile = "personal"
      shared_credentials_file = "/Users/Alexm/.aws/credentials"
  }
}

I check the .tfstate file for my database deployment and it shows the correct outputs.

Navigating to the IPs of the EC2 instances directly show nothing. My var.tf is as follows:
variable "server_port" {
    description = "The port the server will use for HTTP requests"
    default = 8080
}
variable "web_image_id" {
    description = "Image ID for web servers"
    default = "ami-07b4156579ea1d7ba"
}

I've spent hours looking through your documents and code and can't figure it out.

Heredoc leading whitespace in user data

On my system (macOS Sierra) using terraform version 0.9.3 I need to completely remove any leading whitespace otherwise the user data is not executed.

The following format does not work:

resource "aws_instance" "example" {
  tags {
    Name = "terraform-example"
  }
  ami = "ami-f4cc1de2"
  instance_type = "t2.micro"
  vpc_security_group_ids = ["${aws_security_group.webserver.id}"]
  user_data = <<EOF
    #!/bin/bash
    echo "Hello, Terraform!" > index.html
    nohup busybox httpd -f -p 8080 &
    EOF
}

Whereas it works without the leading whitespace:

resource "aws_instance" "example" {
  tags {
    Name = "terraform-example"
  }
  ami = "ami-f4cc1de2"
  instance_type = "t2.micro"
  vpc_security_group_ids = ["${aws_security_group.webserver.id}"]
  user_data = <<EOF
#!/bin/bash
echo "Hello, Terraform!" > index.html
nohup busybox httpd -f -p 8080 &
EOF
}

Chapter 7 - dep add step doesn't appear to work.

dep ensure -add github.com/gruntwork-io/terratest/modules/[email protected]

results in the pictured errors so I'm stuck quite early.
Not sure if I'm being dumb and missing a step.

Also I don't know Go at all, should I just skip the whole terratest thing or is there a "Enough Go to use Terratest" thing I can do ?
thank you !

image

image

Chapter 2 error

I get an error doing the first example (one-server):

Error launching source instance: VPCIdNotSpecified: No defau
lt VPC for this user

Any hints?

Chapter 4 - plage 126 - error - This object does not have an attribute named "address".

I am reading the book and working using the code from this repository. I am on page 126 and get the error detailed below. What I think this means is that chapter 4 expects (some) things from previous chapters to be there. If this is the case, is there a (simple) way of implementing all the pre-requisites - maybe manually? I am also confused about using terraform destroy as this sometimes returns an error when attempting to destroy the s3 bucket containing the terraform state. Will chapter 4 still work if the bucket is destroyed?

pwd 04-terraform-module/modules/stage/services/webserver-cluster
terraform init
terraform plan
Error: Unsupported attribute
  on ../../../modules/services/webserver-cluster/main.tf line 25, in data "template_file" "user_data":
  25:     db_address  = data.terraform_remote_state.db.outputs.address
    |----------------
    | data.terraform_remote_state.db.outputs is object with 2 attributes
This object does not have an attribute named "address".

Error: Unsupported attribute
  on ../../../modules/services/webserver-cluster/main.tf line 26, in data "template_file" "user_data":
  26:     db_port     = data.terraform_remote_state.db.outputs.port
    |----------------
    | data.terraform_remote_state.db.outputs is object with 2 attributes
This object does not have an attribute named "port".

Example using tfvars -> main -> modules

I'm sure I'm missing one singular piece of logic to connect these dots, but I'm trying to create the mechanism described in the section regardling "Larger Teams May Need to Use a Development Pipeline". Specifically I've got tfvars in my specific environment dirs (aka: Figure 6-4). I have my source defined in that tfvars, but init, or get, or plan for that matter, are not downloading anything. It's a constant "no configuration files present".

However, as I wrote this, I finally solved the problem.
The key issue deals with moving to the terraform init method. In your book, although you stated that we would need to make a wrapper to perform terraform init, it was a small logic leap that I missed which is the terraform init /source-dir /target-dir mechanism.

I was assuming (incorrectly) that init should be fed the tfvars and realize/use the source. this is not the case, and init needs to be done "manually" (seperately from tfvars) using the "SAME SOURCE" and choosing our tfvars dir as the destination (or not, but that would make the plan and apply much more difficult command lines).

chapter 3 (workspaces issue)

Chapter 3
Sub section: Isolation via workspace
I have followed this section.
I created the new worksapce called example1.
i run terraform plan and then terraform apply but it did not complete. Instead I got an error
Screenshot 2019-12-31 at 12 09 43

from the book, it is suppose to only apply the EC2 instance but instead it want to create the S3 bucket, DynamoDb table and EC2 instances.

Please help me understand where this is happening

here is my code

provider "aws" {
  region     = "eu-west-1"
  version    = "~>2.0"
}

resource "aws_instance" "example" {
  ami           = "ami-02df9ea15c1778c9c"
  instance_type = "t2.micro"
}

resource "aws_s3_bucket" "terraform_state" {
  bucket = "bucket name"

  lifecycle {
    prevent_destroy = true
  }


  versioning {
    enabled = true
  }

  server_side_encryption_configuration {
    rule {
      apply_server_side_encryption_by_default {
        sse_algorithm = "AES256"
      }
    }
  }
}

resource "aws_dynamodb_table" "locks-2020" {
  name         = "name here"
  billing_mode = "PAY_PER_REQUEST"
  hash_key     = "LockID"

  attribute {
    name = "LockID"
    type = "S"
  }

  tags = {
    Name        = "dynamodb-table-1"
    Environment = "development"
  }
}

terraform {
  backend "s3" {
    bucket         = "bucket name "
    key            = "workspaces-example/terraform.tfstate"
    region         = "eu-west-1"
    dynamodb_table = "name"
    encrypt        = true
  }
}

output "s3_bucket_arn" {
  value       = aws_s3_bucket.terraform_state.arn
  description = "The ARN of the S3 bucket"
}

output "dynamodb_table_name" {
  value       = aws_dynamodb_table.name_here.name
  description = "The name of the DynamoDB"
}


Chapter 2 Target group and health check not working

When we create the target group, with the load balancer and the health check, the result is always unhealthy so it keeps deregistering old vm and spinning new one. But looking at the code, the HTTP health check is done on port 80, while the VM security group, and the httpd are configured on port 8080 only

One-webserver example, getting InvalidParameterCombination.

Terraform v0.8.5

I'm tring the one-webserver example getting the following error when creating VPC.

InvalidParameterCombination: You may only modify the groupSet attribute for VPC instances
	status code: 400

Here is the complete output.

aws_security_group.instance: Creating...
  description:                         "" => "Managed by Terraform"
  egress.#:                            "" => "<computed>"
  ingress.#:                           "" => "1"
  ingress.516175195.cidr_blocks.#:     "" => "1"
  ingress.516175195.cidr_blocks.0:     "" => "0.0.0.0/0"
  ingress.516175195.from_port:         "" => "8080"
  ingress.516175195.protocol:          "" => "tcp"
  ingress.516175195.security_groups.#: "" => "0"
  ingress.516175195.self:              "" => "false"
  ingress.516175195.to_port:           "" => "8080"
  name:                                "" => "terraform-example-instance"
  owner_id:                            "" => "<computed>"
  vpc_id:                              "" => "<computed>"
aws_security_group.instance: Creation complete
aws_instance.example: Creating...
  ami:                               "" => "ami-40d28157"
  associate_public_ip_address:       "" => "<computed>"
  availability_zone:                 "" => "<computed>"
  ebs_block_device.#:                "" => "<computed>"
  ephemeral_block_device.#:          "" => "<computed>"
  instance_state:                    "" => "<computed>"
  instance_type:                     "" => "m3.medium"
  key_name:                          "" => "<computed>"
  network_interface_id:              "" => "<computed>"
  placement_group:                   "" => "<computed>"
  private_dns:                       "" => "<computed>"
  private_ip:                        "" => "<computed>"
  public_dns:                        "" => "<computed>"
  public_ip:                         "" => "<computed>"
  root_block_device.#:               "" => "<computed>"
  security_groups.#:                 "" => "<computed>"
  source_dest_check:                 "" => "true"
  subnet_id:                         "" => "<computed>"
  tags.%:                            "" => "1"
  tags.Name:                         "" => "terraform-example"
  tenancy:                           "" => "<computed>"
  user_data:                         "" => "********"
  vpc_security_group_ids.#:          "" => "1"
  vpc_security_group_ids.3845042208: "" => "sg-07a52311"
aws_instance.example: Still creating... (10s elapsed)
aws_instance.example: Still creating... (20s elapsed)
Error applying plan:

1 error(s) occurred:

* aws_instance.example: InvalidParameterCombination: You may only modify the groupSet attribute for VPC instances
	status code: 400, request id: ce41c068-807d-4301-bb88-b229680e3e19

Terraform does not automatically rollback in the face of errors.
Instead, your Terraform state file has been partially updated with
any resources that successfully completed. Please address the error
above and apply again to incrementally change your infrastructure.

Chapter 4: db_remote_state_* hard-coded in book but variables in examples

I noticed that in chapter 4 in the book the db_remote_state_bucket and db_remote_state_key arguments in the module "webserver_cluster" example are hard-coded (albeit with a place-holder (YOUR_BUCKET_NAME) value for db_remote_state_bucket) but on Github those arguments are variables defined in vars.tf.

Chapter 7 : Terratests

Hi,

I am unable to run terra tests mentioned in chapter 7 because of the below errors. can you please help

/alb_example_test.go:36:30: not enough arguments in call to http_helper.HttpGetWithRetry
have (*"testing".T, string, int, string, int, time.Duration)
want ("prod-grade-infra/vendor/github.com/gruntwork-io/terratest/modules/testing".TestingT, string, *tls.Config, int, string, int, time.Duration)

Chapter 3 (the terraform_remote_state Data source)

Chapter 3 section: The terraform_remote_state Data Source
I am completed this section which taught me how the web sever cluster can access the database address and port via Terraform.
I got the address for the alb dns
but when i curl it on the command line or on a web browser nothing happens it times out
Please can you tell where i went wrong?
what can i do to address this?

Screenshot 2020-01-02 at 11 37 43

page 161-162 slieve typo

"Now you've seen all the tricks the init command should have up its slieve!" should read "Now you've seen all the tricks the init command should have up its sleeve!"

slieve - an Irish mountain / sleeve - the arm of a garment :)

Chapter 2 Error Availability Zones in WebServer Cluster

  • Message:
    Inappropriate value for attribute "availability_zones": element 0: string
    required.

¿ How to fix ?

  • Replace
    availability_zones = ["${data.aws_availability_zones.all.names}"]
  • To
    availability_zones = ["${data.aws_availability_zones.all.names[0]}"]

non default vpc

Hello,

This is a question.
I’m in chapter 6/Production grade/testable module

trying to wrap up every module, I’m facing a little issue here

I don't have a default vpc ( I'm experimenting it on my company's aws account.)
I have my vpc on a separate aws subscription dedicated to lab., so I can retrieve my vpc i.
But, for subnet, I have to create it.
so this :

data "aws_subnet_ids" "default" { 
  vpc_id = data.aws_vpc.default.id
}

won't work since we don't use default vpc.
What is your advice to make it work with my existing vpc ?
Earlier in the book I created subnet like this:

resource "aws_subnet" "my_subnet" {
  count             = 2
  vpc_id            = data.aws_vpc.selected.id
  availability_zone = data.aws_availability_zones.available.names[count.index]
  cidr_block        = cidrsubnet(data.aws_vpc.selected.cidr_block, 12, count.index)

  tags = {
    Name = "sb-vpc-${count.index}"
  }
}

so what is your advice and In which module (based on the book's code) should I add it so that the creation and use are reusable?

thanks for your help.

configure HTTPS in ELB

if I want to use HTTPS(port 443) as a listener in my loadbalancer, I have to change my apache's configuration in back-end(web server)?or I left it same as HTTP. I mean besides network configuration.

chapter 2 user data

I am learning Terraform using this book. I am chapter 2 section: Deploy a single web server.
i followed the code and everything.
but when I curl the public ip:8080,
I have already tried curl http://elastic_instance_public_ip:8080 and
curl https://elastic_instance_public_ip:8080

the result is Operation timed out
How do I solve this issue.

Below is my code:

provider "aws" {
  version = "~>2.0"
  region  = "eu-west-1"

}

resource "aws_instance" "example" {
  ami                    = "ami-01f14919ba412de34"
  instance_type          = "t2.micro"
  vpc_security_group_ids = [aws_security_group.instance.id]

  user_data = <<-EOF
              #!/bin/bash
              echo "Hello Sainsburys" > index.html
              nohup busybox httpd -f -p 8080 &
              EOF

  tags = {
    Name = "test-example"
  }
}

resource "aws_security_group" "instance" {
  name = var.security_group_name

  ingress {
    from_port   = 8080
    to_port     = 8080
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

variable "security_group_name" {
  description = "The name of the security group"
  default     = "terraform-example-instance"
}
output "public_ip" {
  value = aws_instance.example.public_ip
  description = "The public IP of the instance"
}

Examples don't work with TF < 9

I've started with the exercises in chapter 2, but all of them are restricted to terraform < 9. I'm not familiar enough yet with terraform to know if I can just rip that out, and if things should still work.

I also noticed that some of the AMI id's don't resolve.

Backend Config in Chapter 4: Modules

Hey there!

I have a question regarding the backend configuration in Chapter 4: Modules.

As I was following the webserver-cluster example in the book, I noticed that you didn't mention about the remote backend S3 config. The backend config was hardcoded (as shown below in modules/services/webserver-cluster/main.tf), which works fine. But I was thinking of making it more reusable and flexible to accommodate different environments.

# modules/services/webserver-cluster/main.tf

terraform {
    backend "s3" {
        bucket = "bucket-for-tf"
        key = "stage/services/webserver-cluster/terraform.tfstate"
        region = "us-east-1"

        dynamodb_table = "tf-dev-locks"
        encrypt = true
    }
}

In your opinion, which option is the best approach to maintain remote state this scenario (best practice wise)?

Option 1:

  • Define the backend config in modules/services/webserver-cluster/main.tf but have a module input variable to pass the environment.

Example:

# modules/services/webserver-cluster/variables.tf

variable "backend_env" {
  description = "The remote state folder for deploy environment"
  type = string
}
# modules/services/webserver-cluster/main.tf

terraform {
    backend "s3" {
        bucket = "bucket-for-tf"
        key = "${var.backend_env}/services/webserver-cluster/terraform.tfstate"
        region = "us-east-1"

        dynamodb_table = "tf-dev-locks"
        encrypt = true
    }
}

And we can pass the environment value in stage/services/webserver-cluster/main.tf

# stage/services/webserver-cluster/main.tf

module "webserver_cluster" {
    source = "../../../modules/services/webserver-cluster"

    backend_env = "stage"
}

OPTION 2:

  • Define the complete backend config only in stage|prod/services/webserver-cluster/main.tf

Example:

# stage/services/webserver-cluster/main.tf

terraform {
    backend "s3" {
        bucket = "bucket-for-tf"
        key = "stage/services/webserver-cluster/terraform.tfstate"
        region = "us-east-1"

        dynamodb_table = "tf-dev-locks"
        encrypt = true
    }
}

Let me know your thoughts. Thanks so much for your help!

[Errata] Chapter 3, Page 72 Typo

In Chapter 3, page 72, the web server Terraform state file is shown as state/services/webserver-cluster/terraform.tfstate and should be stage/services/webserver-cluster/terraform.tfstate.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.