Terraform基礎知識

## Terraformブロック種類
- [terraform](#terraformブロック)
- [provider](#providerブロック)
- [locals](#localsブロック)
- [variable](#variableブロック)
- [data](#dataブロック)
- [module](#moduleブロック)
- [resource](#resourceブロック)
- [output](#outputブロック)
- [check](#checkブロック)
- [run](#terraformブロック)


### terraformブロック
```terraform
terraform {
  required_version = "~> 1.6"
  required_providers {
    aws = {
      source = "hashicorp/aws"
    }
    random = {
      source  = "hashicorp/random"
      version = "3.5.1"
    }
  }
}
```

### providerブロック
```terraform
provider "aws" {

  # 記述方式なら以下の二つ、環境変数やdefaltプロファイル方式もある
  profile = "my-profile"
  
  access_key = "xxxx"
  secret_key = "xxxx"

  
  region  = "ap-northeast-1"
}
```

### localsブロック
```terraform
locals {
  project = "aquaring"
}
```

### variableブロック
```terraform
variable "env" {
  type        = string
  default     = "dev"
  description = "my first terraform"
}
```

### dataブロック
```terraform
data "aws_ami" "projetc_ami" {
  most_recent = true
  owners      = ["self", "amazon"]

  filter {
    name   = "name"
    values = ["al2023-ami-*-kernel-6.1-x86_64"]
  }
  filter {
    name   = "root-device-type"
    values = ["ebs"]
  }
  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }
}
```

### moduleブロック
```terraform
module "vpc" {
  source = "terraform-aws-modules/vpc/aws"

  name = "my-vpc"
  cidr = "10.0.0.0/16"

  azs             = ["ap-northeast-1a", "ap-northeast-1c", "ap-northeast-1d"]
  private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
  public_subnets  = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"]

  enable_nat_gateway = false
  enable_vpn_gateway = false

  tags = {
    Terraform = "true"
    Environment = "dev"
  }
}
```

### resourceブロック
```terraform
resource "aws_instance" "helloTerraform" {
  instance_type = "t3.micro"
  ami           = data.aws_ami.projetc_ami.id
  subnet_id     = module.vpc.public_subnets[0]

  tags = {
    Name = local.project
    Env  = var.env
  }
}

```

### outputブロック
```terraform
output "ami_id" {
    value = aws_instance.helloTerraform.id
}
```

### checkブロック
```terraform
check "health_check" {
  data "http" "terraform_io" {
    url = "https://www.terraform.io"
  }

  assert {
    condition = data.http.terraform_io.status_code == 200
    error_message = "${data.http.terraform_io.url} returned an unhealthy status code"
  }
}
```

### runブロック
```terraform
# valid_string_concat.tftest.hcl

variables {
  bucket_prefix = "test"
}

run "valid_string_concat" {

  command = plan

  assert {
    condition     = aws_s3_bucket.bucket.bucket == "test-bucket"
    error_message = "S3 bucket name did not match expected"
  }

}

```

## terraform CLI

```bash
# init
$ terraform init
$ terraform init -upgrade
$ terraform init -backend-config=dev.tfbackend

$ terraform fmt
$ terraform validate
$ terraform plan

# apply
$ terraform apply -auto-approve
$ terraform apply -target="aws_instance.helloTerraform"
$ terraform apply -var="env=staging"
$ terraform apply -var-file="dev.tfvars"

# destroy
$ terraform destroy
```

## terraformファイル分け
- versions.tf
  - terraformブロック
- providers.tf
  - providerブロック
- variables.tf
  - input values
- output.tf
  - output values
- main.tf 
  - localsブロック
  - resourceブロック