0630-IaC, Terraform

hyejin·2022년 6월 30일
0

AWS CloudFormation(Azure Resource Manager,GCP Deployment Manager)

  • 주요 섹션 설명
    1. Resources(생성) : AWS 인프라의 실질적인 섹션입니다. EC2 인스턴스, S3 버킷, ELB등과 같은 클라우드 포메이션을 이용해 AWS 웹 콘솔에서 실행하는 것으로 거의 모든 리소스 유형을 생성할 수 있습니다. 하지만 신규 또는 최첨단의 AWS 리소스는 즉시 제공되지 않는 경우가 종종 있습니다. 리소스에는 기본 반환값이 있습니다. Ref를 이용해 이 반환값을 얻어올 수 있고 템플릿의 다른 위치에 사용할 수 있습니다. 예를 들어 AWS::EC2::VPC 리소스 유형은 기본 반환값을 갖고 있고 이 값은 VPC의 ID 입니다.

2. Parameters(입력) : 명령줄 도구에 입력하는 매개변수와 동일하게 스택을 만들거나 업데이트할 때 정의하는 입력값입니다. 파라미터는 템플릿의 변경 없이도 스택을 커스터마이즈할 수 있게 해줍니다. AMI ID, VPC ID, Subnet ID등과 같은 매개변수를 사용할 수 있습니다.

3. Output(출력) : 스택이 완료된 후에 결과물을 출력하려고 할때 유용합니다. 예를 들어 ELB의 퍼블릭 URL이나 EC2의 퍼블릭 IP를 출력할 수 있습니다.

4. Mapping(지정) : 리전의 특화된 템플릿에서 어떠한 요소를 참조할 때 필요합니다. 예를 들어 템플릿에 EC2 AMI ID에 대한 매핑을 지정하는 것입니다. AMI ID가 리전에 특화된 리소스이기 때문에 유효한 AMI ID를 리전별로 지정하려고 할때 사용합니다.

CloudFormation

새 메모장에

vi new-vpc.yaml

AWSTemplateFormatVersion: 2010-09-09
Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 192.168.0.0/16
      EnableDnsSupport: true         //true하지 않으면 ping 안나감
      EnableDnsHostnames: true
      InstanceTenancy: default
      Tags:
        - Key: Name
          Value: NEW-VPC
  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: NEW-IGW
  VPCGatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref InternetGateway
  SubnetA:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: ap-northeast-2a
      VpcId: !Ref VPC
      CidrBlock: 192.168.0.0/20
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: NEW-PUBLIC-SUBNET-2A
  SubnetB:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: ap-northeast-2b
      VpcId: !Ref VPC
      CidrBlock: 192.168.16.0/20
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: NEW-PUBLIC-SUBNET-2B
  SubnetC:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: ap-northeast-2c
      VpcId: !Ref VPC
      CidrBlock: 192.168.32.0/20
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: NEW-PUBLIC-SUBNET-2C
  SubnetD:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: ap-northeast-2d
      VpcId: !Ref VPC
      CidrBlock: 192.168.48.0/20
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: NEW-PUBLIC-SUBNET-2D
  RouteTableA:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: NEW-PUBLIC-RTB
  InternetRoute:
    Type: AWS::EC2::Route
    DependsOn: InternetGateway
    Properties:
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway
      RouteTableId: !Ref RouteTableA
  SubnetARouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref RouteTableA
      SubnetId: !Ref SubnetA
  SubnetBRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref RouteTableA
      SubnetId: !Ref SubnetB
  SubnetCRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref RouteTableA
      SubnetId: !Ref SubnetC
  SubnetDRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref RouteTableA
      SubnetId: !Ref SubnetD

new-vpc.yaml로 저장

aws management console

  • CloudFormation > 스택 생성
  • 템플릿 준비 : 준비된 템플릿
  • 템플릿 소스 : 템플릿 파일 업로드 - new-vpc.yaml
  • 스택 이름 : new-vpc

  • VPC 확인

  • DNS 호스트 이름 편집 / DNS 확인 편집 중요

  • 인터넷 게이트웨이는 attached만 확인하면 됨

  • 라우팅 테이블 명시적 연결

new-ec2.yaml

AWSTemplateFormatVersion: 2010-09-09
Mappings:
  RegionMap:
    ap-northeast-2:
      AMIID: ami-0fd0765afb77bcca7
    ap-northeast-1:
      AMIID: ami-0b7546e839d7ace12
Parameters:
  InstanceTypeParameter:
    Type: String
    Default: t2.micro
    Description: Enter instance size. Default is t2.micro
  VPC:
    Type: String
    Default: vpc-01a276b266db7833b
    Description: VPC ID.
  Subnet:
    Type: String
    Default: subnet-01132b9dddcf71d3d
    Description: Subnet ID.
  AMI:
    Type: String
    Default: AMIID
    Description: The Linux AMI to use.
  Key:
    Type: String
    Default: new-key
    Description: The key used to access the instance.
Resources:
  InstanceSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: "NEW-SG-WEB"
      GroupDescription: "SSH and web traffic in, all traffic out."
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: '80'
          ToPort: '80'
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: '22'
          ToPort: '22'
          CidrIp: 123.142.252.25/32
      SecurityGroupEgress:
        - IpProtocol: -1
          CidrIp: 0.0.0.0/0
  Linux:
    Type: 'AWS::EC2::Instance'
    Properties:
      SubnetId: !Ref Subnet
#      ImageId: !Ref AMI
      ImageId: !FindInMap [ RegionMap, !Ref "AWS::Region", !Ref AMI ]
      InstanceType:
        Ref: InstanceTypeParameter
      KeyName: !Ref Key
      SecurityGroupIds:
        - Ref: InstanceSecurityGroup
      BlockDeviceMappings:
        - DeviceName: /dev/xvda
          Ebs:
            VolumeSize: 8
        - DeviceName: /dev/xvdb
          Ebs:
            VolumeSize: 8
      Tags:
        - Key: Name
          Value: NEW-EC2

      UserData:
        Fn::Base64: |
          #cloud-boothook
          #!/bin/bash
          yum install -y httpd
          systemctl enable --now httpd
          echo "Hello World!" > /var/www/html/index.html
Outputs:  
  PublicIp:    
    Description: PublicIp Output    
    Value: {"Fn::GetAtt": ["Linux","PublicIp"]}

aws management console

  • CloudFormation > 스택 생성
  • 템플릿 준비 : 준비된 템플릿
  • 템플릿 소스 : 템플릿 파일 업로드 - new-ec2.yaml
  • 스택 이름 : new-yaml
  • subnet : 본인 subnet ID (subnet 2a)
  • VPC : 본인 VPC ID

aws management console (도쿄 리전)

  • 키페어 생성

  • 이름 : tokyo

  • 프라이빗 키 파일 형식 : .pem

  • CloudFormation > 스택 생성

  • 템플릿 준비 : 준비된 템플릿

  • 템플릿 소스 : 템플릿 파일 업로드 - new-ec2.yaml

  • 스택 이름 : tokyo

  • subnet : 본인 subnet ID (subnet 2a)

  • VPC : default VPC ID

구성관리 도구 : Ansible
서버템블릿 도구 : Docker
오케스트레이션 도구 : Kubernetes
프로비전 도구 : Terraform

Terraform 설치

[root@localhost ~]# wget https://releases.hashicorp.com/terraform/1.2.3/terraform_1.2.3_linux_amd64.zip
--2022-06-30 15:43:50--  https://releases.hashicorp.com/terraform/1.2.3/terraform_1.2.3_linux_amd64.zip
Resolving releases.hashicorp.com (releases.hashicorp.com)... 146.75.50.49
Connecting to releases.hashicorp.com (releases.hashicorp.com)|146.75.50.49|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 19891436 (19M) [application/zip]
Saving to: ‘terraform_1.2.3_linux_amd64.zip’

100%[===========================================>] 19,891,436  54.8MB/s   in 0.3s

2022-06-30 15:43:50 (54.8 MB/s) - ‘terraform_1.2.3_linux_amd64.zip’ saved [19891436/19891436]
[root@localhost ~]# unzip terraform_1.2.3_linux_amd64.zip
Archive:  terraform_1.2.3_linux_amd64.zip
  inflating: terraform
[root@localhost ~]# mv terraform /usr/local/bin/

AWS Terraform ec2 인스턴스 생성

[root@localhost ~]# mkdir aws && cd $_
[root@localhost aws]# vi main.tf
provider "aws" {
  region = "ap-northeast-2"
}

resource "aws_instance" "example" {
  ami           = "ami-0fd0765afb77bcca7"
  instance_type = "t2.micro"
}
[root@localhost aws]# terraform init

Initializing the backend...

Initializing provider plugins...
- Finding latest version of hashicorp/aws...
- Installing hashicorp/aws v4.20.1...
- Installed hashicorp/aws v4.20.1 (signed by HashiCorp)

Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
  • plan 검증
[root@localhost aws]# terraform plan

Terraform used the selected providers to generate the following execution plan.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_instance.example will be created
  + resource "aws_instance" "example" {
      + ami                                  = "ami-0fd0765afb77bcca7"
      + arn                                  = (known after apply)
      + associate_public_ip_address          = (known after apply)
      + availability_zone                    = (known after apply)
      + cpu_core_count                       = (known after apply)
      + cpu_threads_per_core                 = (known after apply)
      + disable_api_stop                     = (known after apply)
      + disable_api_termination              = (known after apply)
      + ebs_optimized                        = (known after apply)
      + get_password_data                    = false
      + host_id                              = (known after apply)
      + id                                   = (known after apply)
      + instance_initiated_shutdown_behavior = (known after apply)
      + instance_state                       = (known after apply)
      + instance_type                        = "t2.micro"
      + ipv6_address_count                   = (known after apply)
      + ipv6_addresses                       = (known after apply)
      + key_name                             = (known after apply)
      + monitoring                           = (known after apply)
      + outpost_arn                          = (known after apply)
      + password_data                        = (known after apply)
      + placement_group                      = (known after apply)
      + placement_partition_number           = (known after apply)
      + primary_network_interface_id         = (known after apply)
      + private_dns                          = (known after apply)
      + private_ip                           = (known after apply)
      + public_dns                           = (known after apply)
      + public_ip                            = (known after apply)
      + secondary_private_ips                = (known after apply)
      + security_groups                      = (known after apply)
      + source_dest_check                    = true
      + subnet_id                            = (known after apply)
      + tags_all                             = (known after apply)
      + tenancy                              = (known after apply)
      + user_data                            = (known after apply)
      + user_data_base64                     = (known after apply)
      + user_data_replace_on_change          = false
      + vpc_security_group_ids               = (known after apply)

      + capacity_reservation_specification {
          + capacity_reservation_preference = (known after apply)

          + capacity_reservation_target {
              + capacity_reservation_id                 = (known after apply)
              + capacity_reservation_resource_group_arn = (known after apply)
            }
        }

      + ebs_block_device {
          + delete_on_termination = (known after apply)
          + device_name           = (known after apply)
          + encrypted             = (known after apply)
          + iops                  = (known after apply)
          + kms_key_id            = (known after apply)
          + snapshot_id           = (known after apply)
          + tags                  = (known after apply)
          + throughput            = (known after apply)
          + volume_id             = (known after apply)
          + volume_size           = (known after apply)
          + volume_type           = (known after apply)
        }

      + enclave_options {
          + enabled = (known after apply)
        }

      + ephemeral_block_device {
          + device_name  = (known after apply)
          + no_device    = (known after apply)
          + virtual_name = (known after apply)
        }

      + maintenance_options {
          + auto_recovery = (known after apply)
        }

      + metadata_options {
          + http_endpoint               = (known after apply)
          + http_put_response_hop_limit = (known after apply)
          + http_tokens                 = (known after apply)
          + instance_metadata_tags      = (known after apply)
        }

      + network_interface {
          + delete_on_termination = (known after apply)
          + device_index          = (known after apply)
          + network_card_index    = (known after apply)
          + network_interface_id  = (known after apply)
        }

      + private_dns_name_options {
          + enable_resource_name_dns_a_record    = (known after apply)
          + enable_resource_name_dns_aaaa_record = (known after apply)
          + hostname_type                        = (known after apply)
        }

      + root_block_device {
          + delete_on_termination = (known after apply)
          + device_name           = (known after apply)
          + encrypted             = (known after apply)
          + iops                  = (known after apply)
          + kms_key_id            = (known after apply)
          + tags                  = (known after apply)
          + throughput            = (known after apply)
          + volume_id             = (known after apply)
          + volume_size           = (known after apply)
          + volume_type           = (known after apply)
        }
    }

Plan: 1 to add, 0 to change, 0 to destroy.

────────────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee
to take exactly these actions if you run "terraform apply" now.
  • destroy
[root@localhost aws]# terraform destroy
aws_instance.example: Refreshing state... [id=i-0d93c31f523cf6619]

Terraform used the selected providers to generate the following execution plan.
Resource actions are indicated with the following symbols:
  - destroy

Terraform will perform the following actions:

  # aws_instance.example will be destroyed
  - resource "aws_instance" "example" {
      - ami                                  = "ami-0fd0765afb77bcca7" -> null
      - arn                                  = "arn:aws:ec2:ap-northeast-2:050722723154:instance/i-0d93c31f523cf6619" -> null
      - associate_public_ip_address          = true -> null
      - availability_zone                    = "ap-northeast-2a" -> null
      - cpu_core_count                       = 1 -> null
      - cpu_threads_per_core                 = 1 -> null
      - disable_api_stop                     = false -> null
      - disable_api_termination              = false -> null
      - ebs_optimized                        = false -> null
      - get_password_data                    = false -> null
      - hibernation                          = false -> null
      - id                                   = "i-0d93c31f523cf6619" -> null
      - instance_initiated_shutdown_behavior = "stop" -> null
      - instance_state                       = "running" -> null
      - instance_type                        = "t2.micro" -> null
      - ipv6_address_count                   = 0 -> null
      - ipv6_addresses                       = [] -> null
      - monitoring                           = false -> null
      - primary_network_interface_id         = "eni-054ed38e749cffae5" -> null
      - private_dns                          = "ip-172-31-8-139.ap-northeast-2.compute.internal" -> null
      - private_ip                           = "172.31.8.139" -> null
      - public_dns                           = "ec2-3-38-151-163.ap-northeast-2.compute.amazonaws.com" -> null
      - public_ip                            = "3.38.151.163" -> null
      - secondary_private_ips                = [] -> null
      - security_groups                      = [
          - "default",
        ] -> null
      - source_dest_check                    = true -> null
      - subnet_id                            = "subnet-0014153bbc7e20894" -> null
      - tags                                 = {
          - "Name" = "terraform-example"
        } -> null
      - tags_all                             = {
          - "Name" = "terraform-example"
        } -> null
      - tenancy                              = "default" -> null
      - user_data_replace_on_change          = false -> null
      - vpc_security_group_ids               = [
          - "sg-0f378736735ead05a",
        ] -> null

      - capacity_reservation_specification {
          - capacity_reservation_preference = "open" -> null
        }

      - credit_specification {
          - cpu_credits = "standard" -> null
        }

      - enclave_options {
          - enabled = false -> null
        }

      - maintenance_options {
          - auto_recovery = "default" -> null
        }

      - metadata_options {
          - http_endpoint               = "enabled" -> null
          - http_put_response_hop_limit = 1 -> null
          - http_tokens                 = "optional" -> null
          - instance_metadata_tags      = "disabled" -> null
        }

      - private_dns_name_options {
          - enable_resource_name_dns_a_record    = false -> null
          - enable_resource_name_dns_aaaa_record = false -> null
          - hostname_type                        = "ip-name" -> null
        }

      - root_block_device {
          - delete_on_termination = true -> null
          - device_name           = "/dev/xvda" -> null
          - encrypted             = false -> null
          - iops                  = 100 -> null
          - tags                  = {} -> null
          - throughput            = 0 -> null
          - volume_id             = "vol-095c22371f494763f" -> null
          - volume_size           = 8 -> null
          - volume_type           = "gp2" -> null
        }
    }

Plan: 0 to add, 0 to change, 1 to destroy.
  • vi main.tf 수정
provider "aws" {
  region = "ap-northeast-2"
}

resource "aws_instance" "example" {
  ami                    = "ami-0fd0765afb77bcca7"
  instance_type          = "t2.micro"
  vpc_security_group_ids = [aws_security_group.instance.id]
  key_name  = "new-key"
  user_data = <<-EOF
              #! /bin/bash
              yum install -y httpd
              systemctl enable --now httpd
              echo "Hello, Terraform" > /var/www/html/index.html
              EOF

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

resource "aws_security_group" "instance" {

  name = var.security_group_name

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["123.142.252.25/32"]
  }
  ingress {
    from_port   = -1
    to_port     = -1
    protocol    = "icmp"
    cidr_blocks = ["0.0.0.0/0"]
  }
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
  tags = {
    Name = "terraform-sg"
  }
}

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"
}

output "public_dns" {
  value       = aws_instance.example.public_dns
  description = "The Public dns of the Instance"
}

output "private_ip" {
  value       = aws_instance.example.private_ip
  description = "The Private_ip of the Instance"
}
  • apply
Outputs:

private_ip = "172.31.0.34"
public_dns = "ec2-13-209-14-133.ap-northeast-2.compute.amazonaws.com"
public_ip = "13.209.14.133"

0개의 댓글

관련 채용 정보