πŸ‘©β€πŸ’»0630[IaC,terraform]

망지·2022λ…„ 6μ›” 30일
1
post-custom-banner

πŸ“Œ 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λ₯Ό λ¦¬μ „λ³„λ‘œ μ§€μ •ν•˜λ €κ³  ν• λ•Œ μ‚¬μš©ν•©λ‹ˆλ‹€.

πŸ“™ Resources 파일 생성(VPC)

# vi new-vpc.yaml
AWSTemplateFormatVersion: 2010-09-09
Resources:
  VPC: ## 논리적 이름. λ‚΄κ°€ μ •ν•˜κΈ° λ‚˜λ¦„.
    Type: AWS::EC2::VPC
    Properties: 
      CidrBlock: 192.168.0.0/16
      EnableDnsSupport: true
      EnableDnsHostnames: true
      InstanceTenancy: default
      Tags:
        - Key: Name
          Value: NEW-VPC
  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
  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: NEW-IGW
  VPCGatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref InternetGateway
  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

βœ”οΈEnableDnsSupport;

πŸ“™ AWS - μ›Ή / cloudformationμ—μ„œ μŠ€νƒ 생성

βœ”οΈ 리전 - μ„œμšΈμ—μ„œ 진행

βœ”οΈ μŠ€νƒμ˜΅μ…˜κ΅¬μ„± μƒλž΅ - μŠ€νƒ 생성 λ²„νŠΌ 클릭

πŸ“™ parameter, mapping, resours ( μΈμŠ€ν„΄μŠ€ 생성 )

VPC ID, μ„œλΈŒλ„· ID μœ„μ—μ„œ μƒμ„±λœ κ²ƒμœΌλ‘œ μž…λ ₯ν•΄μ£ΌκΈ°

# vi 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"]}

βœ”οΈ 리전 - μ„œμšΈμ—μ„œ 진행

βœ”οΈ μŠ€νƒμ˜΅μ…˜κ΅¬μ„± μƒλž΅ - μŠ€νƒ 생성 λ²„νŠΌ 클릭

πŸ“™μ •λ¦¬ (μ‚­μ œν•˜κΈ°)

βœ”οΈ μ‚­μ œ μˆœμ„œ ; ec2 - vpc
βœ”οΈ μŠ€νƒμ„ μ‚­μ œν•˜λ©΄ λ‚΄λΆ€ λ¦¬μ†ŒμŠ€λ“€λ„ ν•œκΊΌλ²ˆμ— μ‚­μ œ 됨.
βœ”οΈ s3버킷은 λ”°λ‘œ μ‚­μ œν•΄μ£Όμ–΄μ•Ό 함.

πŸ“Œ 싀무 νŠΉν™” 이둠

싀무 νŠΉν™” pdf 파일 7.p~ 확인

βœ”οΈμ˜€μΌ€μŠ€νŠΈλ ˆμ΄μ…˜λ„κ΅¬
μΏ λ²„λ„€ν‹°μŠ€λŠ” 곧 ν΄λŸ¬μŠ€ν„°,
AZURE AKS, EKS, GCP GKE => μΏ λ²„λ„€ν‹°μŠ€

ꡬ성관리 ; ansible(on-prem)
μ„œλ²„ ν…œν”Œλ¦Ώ ; 도컀
μ˜€μΌ€μŠ€νŠΈλ ˆμ΄μ…˜ ; μΏ λ²„λ„€ν‹°μŠ€
ν”„λ‘œλΉ„μ „ ; ν…ŒλΌνΌ
->μ—”μ„œλΈ”κ³Ό ν…ŒλΌνΌμ€ 퍼블릭 ν΄λΌμš°λ“œ μ‹œλŒ€μ— μ ‘μ–΄λ“€λ©΄μ„œ κ·Έ 차이가 점점 쀄어듦. ν•˜μ§€λ§Œ ν…ŒλΌνΌμ΄ ec2μƒμ„±ν•˜κΈ°κ°€ 더 쉬움.

πŸ“Œ Terraform

πŸ“™ Terraform μž‘λ™ 방식

ν…ŒλΌνΌμ€ ν•΄μ‹œμ½”ν”„μ‚¬μ—μ„œ Goμ–Έμ–΄λ‘œ κ°œλ°œν•œ μ˜€ν”ˆμ†ŒμŠ€λ„κ΅¬μž…λ‹ˆλ‹€. μš΄μ˜μ²΄μ œλ§ˆλ‹€ λ°”μ΄λ„ˆλ¦¬ 파일이 μ‘΄μž¬ν•˜λŠ”λ° Go μ½”λ“œλŠ” ν•˜λ‚˜μ˜ λ°”μ΄λ„ˆλ¦¬ 파일둜 컴파일되며 Terraformμ΄λΌλŠ” λͺ…λ Ήμ–΄λ‘œ μ‹€ν–‰ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 이 Terraform λͺ…λ Ήμ–΄λ₯Ό μ‚¬μš©ν•˜μ—¬ λ…ΈνŠΈλΆ, λ°μŠ€ν¬νƒ‘, λΉŒλ“œ μ„œλ²„ λ˜λŠ” λ‹€λ₯Έ μ»΄ν“¨ν„°μ—μ„œλ“  인프라λ₯Ό 배포할 수 있으며 이λ₯Ό μœ„ν•΄ μΆ”κ°€ 인프라(λ§ˆμŠ€ν„°, μ—μ΄μ „νŠΈ)λ₯Ό 생성할 ν•„μš”κ°€ μ—†μŠ΅λ‹ˆλ‹€. 즉 Terraform λͺ…λ Ήμ–΄κ°€ AWS, Azure, GCP, Openstack λ“±μ˜ Providerλ₯Ό λŒ€μ‹ ν•΄ APIλ₯Ό ν˜ΈμΆœν•˜μ—¬ λ¦¬μ†ŒμŠ€λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€.
ν…ŒλΌνΌμ€ μƒμ„±ν•˜λ €λŠ” 인프라 정보가 담겨 μžˆλŠ” ν…μŠ€νŠΈλ‘œ 이루어진 ν…ŒλΌνΌ ꡬ성 νŒŒμΌμ„ μƒμ„±ν•˜μ—¬ APIλ₯Ό ν˜ΈμΆœν•©λ‹ˆλ‹€. μ΄λŸ¬ν•œ ꡬ성 값듀이 'μ½”λ“œν˜• 인프라'λ₯Ό λ§Œλ“œλŠ” λ°”λ‘œ κ·Έ 'μ½”λ“œ'μž…λ‹ˆλ‹€. νŒ€μ˜ λˆ„κ΅°κ°€κ°€ 인프라λ₯Ό μˆ˜μ •ν•˜κ³ μž ν•  λ•Œ, μ„œλ²„μ— 직접 μ ‘μ†ν•˜μ—¬ μž‘μ—…ν•˜κ±°λ‚˜ μˆ˜μž‘μ—…μœΌλ‘œ μˆ˜μ •ν•˜λŠ” λŒ€μ‹  ν…ŒλΌνΌμ„ μ‚¬μš©ν•˜μ—¬ ꡬ성 νŒŒμΌμ„ μˆ˜μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

# vi main.tf
provider "aws" { # awsλ₯Ό κ³΅κΈ‰μžλ‘œ μ‚¬μš©ν•˜μ—¬
  region = "ap-northeast-2" # μ„œμšΈ 리전에 인프라λ₯Ό λ°°ν¬ν•œλ‹€λŠ” 의미
}
resource "aws_instance" "example" {
  ami           = "ami-0fd0765afb77bcca7"
  instance_type = "t2.micro"
}

resource "_" "" { # PROVIDERλŠ” aws 같은 κ³΅κΈ‰μžμ˜ 이름이고 TYPE은 instance 같이 ν•΄λ‹Ή κ³΅κΈ‰μžμ—μ„œ 생성할 λ¦¬μ†ŒμŠ€ μœ ν˜•μž…λ‹ˆλ‹€. NAME은 ν…ŒλΌνΌ μ½”λ“œμ—μ„œ 이 λ¦¬μ†ŒμŠ€λ₯Ό μ°Έμ‘°ν•˜κΈ° μœ„ν•΄ μ‚¬μš©ν•  수 μžˆλŠ” exampleκ³Ό 같은 'μ‹λ³„μž'μž…λ‹ˆλ‹€. CONFIGλŠ” νŠΉμ • λ¦¬μ†ŒμŠ€μ— λŒ€ν•œ ν•˜λ‚˜ μ΄μƒμ˜ 인수(argument)둜 κ΅¬μ„±λ©λ‹ˆλ‹€.
[CONFIG ...]
}

πŸ“™ Terraform μ£Όμš” λͺ…λ Ήμ–΄

βœ”οΈ *.tf 슀크립트 μž‘μ„±
βœ”οΈ terraform init : terraform λͺ…λ Ήμ–΄μ—λŠ” ν…ŒλΌνΌμ˜ κΈ°λ³Έ κΈ°λŠ₯이 ν¬ν•¨λ˜μ–΄ μžˆμ§€λ§Œ λͺ¨λ“  κ³΅κΈ‰μž(AWS, Azure, GCP λ“±)에 λŒ€ν•œ μ½”λ“œκ°€ ν¬ν•¨λ˜μ–΄ μžˆμ§€ μ•ŠμŠ΅λ‹ˆλ‹€. κ·Έλ ‡κ²Œ λ•Œλ¬Έμ— terraform init λͺ…λ Ήμ–΄λ₯Ό μ‹€ν–‰ν•˜μ—¬ ν…ŒλΌνΌμ— μ½”λ“œλ₯Ό μŠ€μΊ”ν•˜λ„λ‘ μ§€μ‹œν•˜κ³  μ–΄λŠ κ³΅κΈ‰μžμΈμ§€ ν™•μΈν•˜κ³ , ν•„μš”ν•œ μ½”λ“œλ₯Ό λ‹€μš΄λ‘œλ“œν•˜λ„λ‘ ν•΄μ•Ό ν•©λ‹ˆλ‹€. 기본적으둜 κ³΅κΈ‰μž μ½”λ“œλŠ” ν…ŒλΌνΌμ˜ .terraform 폴더에 λ‹€μš΄λ‘œλ“œλ©λ‹ˆλ‹€.

βœ”οΈ terraform plan : ν…ŒλΌνΌμ΄ ꡬ성 νŒŒμΌμ„ μ‚¬μš©ν•˜μ—¬ μž‘μ—…μ„ μˆ˜ν–‰ν•˜κΈ° 전에 μ½”λ“œμ˜ μ˜¨μ „μ„±μ„ 검사할 수 μžˆμŠ΅λ‹ˆλ‹€. plan λͺ…λ Ήμ–΄λŠ” λ¦¬λˆ…μŠ€μ—μ„œ μ“°μ΄λŠ” diff λͺ…λ Ήμ˜ 결괏값과 μœ μ‚¬ν•©λ‹ˆλ‹€. + κ°€ μžˆλŠ” ν•­λͺ©μ€ μΆ”κ°€λ˜κ³ , - κ°€ μžˆλŠ” ν•­λͺ©μ€ μ‚­μ œλœλ‹€λŠ” λœ»μž…λ‹ˆλ‹€. ~ κ°€ μžˆλŠ” ν•­λͺ©μ€ μˆ˜μ •λ©λ‹ˆλ‹€.

βœ”οΈ terraform apply : ν…ŒλΌνΌμ˜ ꡬ성 νŒŒμΌμ„ μ‹€ν–‰ν•˜λ €λ©΄ terraform apply λͺ…λ Ήμ–΄λ₯Ό μ‹€ν–‰ν•©λ‹ˆλ‹€.

πŸ“™ Terraform μ„€μΉ˜

  # wget https://releases.hashicorp.com/terraform/1.2.3/terraform_1.2.3_linux_amd64.zip
# unzip terraform_1.2.3_linux_amd64.zip
# mv terraform /usr/local/bin/
# terraform -version

πŸ“™ AWS Terraform ec2 μΈμŠ€ν„΄μŠ€ 생성

# mkdir aws && cd $_
# vi main.tf
provider "aws" {
  region = "ap-northeast-2"
}

resource "aws_instance" "example" {
  ami           = "ami-0fd0765afb77bcca7"
  instance_type = "t2.micro"
}

# terraform init
# terraform plan
# terraform apply

πŸ“™ ec2 μΈμŠ€ν„΄μŠ€ 정보 μΆ”κ°€ 및 μ‚­μ œ (destroy)

# vi main.tf
provider "aws" {
  region = "ap-northeast-2"
}

resource "aws_instance" "example" {
  ami           = "ami-0fd0765afb77bcca7"
  instance_type = "t2.micro"
  tags = {
    Name = "terraform-example"
  }
}

# terraform init
# terraform plan
# terraform apply
# terraform destroy

πŸ“™ ec2 μΈμŠ€ν„΄μŠ€ μ›Ήμ„œλ²„ 배포

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

# terraform init
# terraform plan
# terraform apply
# terraform output public_ip
# terraform destroy

πŸ“™βœ”οΈβœοΈπŸ“’β­οΈπŸ“Œ

πŸ“Œ 기타

⭐️

profile
κΎΈμ€€νžˆ, μ°¨κ·Όμ°¨κ·Ό
post-custom-banner

0개의 λŒ“κΈ€