본문 바로가기

DevOps

AWS를 통한 효과적인 데브옵스 구축 2/e 2장 중 AWS CLI 로 EC2 구성하기

728x90

aws 참고

AWS를 통한 효과적인 데브옵스 구축 2/e

 

 

계정 보안 MFA 및 IAM 사용해보자

aws 참고 - MFA

aws 참고 - IAM

블로그 참고

더보기

MFA(Multi-factor authentication)

보안 강화를 위해 멀티 팩터 인증(MFA)을 구성하여 AWS 리소스를 보호하는 것이 좋다.

 

MFA

  1. 로그인 후 - 보안자격증명 들어가기
  2. MFA 활성화
  3. 핸드폰에 GoogleAuthenticator(Google OTP) 설치
  4. QR 코드 스캔으로 연동하기
  5. 연속으로 나타나는 MFA 6자리 비밀번호 2개를 입력해서 마무리
  6. 이제 로그인마다 MFA 인증코드를 입력해야함

IAM(Identity and Access Management)

AWS 리소스에 대한 액세스를 안전하게 제어할 수 있는 웹 서비스로 IAM을 사용하여 리소스를 사용하도록 인증(로그인) 및 권한 부여(권한 있음)를 통해 제어하도록 한다. 즉, AWS 에서는 관리 작업의 경우에도 루트 사용자를 사용하지 마실 것을 강력히 권장하고 있으며 IAM 사용자를 만들어 사용할 것을 권장한다.

  1. IAM 메뉴로 이동
  2. 사용자 옵션을 선택
  3. 사용자 추가를 선택 후 프로그래밍 방식 액세스 옵션 선택
  4. 자격증명 다운로드(.csv다운로드)
  5. 권한 탭에서 권한 추가 후 Attach existing policies directly 선택 및 AWS 서비스 리소스의 전체 접근 권한을 제공하는 AdministratorAccess 추가
  6. 보안 자격증명 탭 클릭 후 콘솔 비밀번호 옵션 클릭
  7. MFA 디바이스 할당 클릭 후 MFA 디바이스와 연결
  8. 대시보드에서 IAM  메뉴 클릭
  9. IAM 사용자 로그인 링크로 접근(로그인 URL 로 콘솔에 로그인 시 이 링크를 사용)

 

 

 

AWS CLI 설치하자

aws 참고 - EC2

aws 참고 - AMI

 

더보기

터미널 창에서 'brew install awscli' 로 awscli 를 설치

1. 위에서 내려받은 csv 파일에서 엑세스키와 비밀 키를 가져오자 

$ more credentials.csv

 

2. AWS 계정을 구성하자

$ aws configure

AWS Access Key ID [****************676F]: AI***********************      

AWS Secret Access Key [****************vEwE]: UvxoLNe/EuCyjq****FSuUB**********************

Default region name [ap-northeast-2]: ap-northeast-2

Default output format [None]: 

 

3. 이제 CLI 를 사용할 수 있게 되었다. 사용자 계정 목록을 출력해보자

$ aws iam list-users

{

    "Users": [

        {

            "Path": "/",

            "UserName": "hooneats01",

            "UserId": "AI***********************",

            "Arn": "arn:aws:iam::394078117217:user/hooneats01",

            "CreateDate": "2022-07-20T00:45:09+00:00"

        }

    ]

}

 

4. EC2 를 사용하여 가상서버 구축하자

가상서버를 시작하려면 다음의 4가지 정보가 필요하다.

  • AMI ID
  • 인스턴스 유형
  • 보안 그룹
  • SSH 키 페어

4-1 AMI 찾기

$ aws ec2 describe-images --filters "Name=description,Values=Amazon Linux AMI * x86_64 HVM GP2" --query "Images[0].ImageId" --output text

 

4-2 인스턴스 유형

AWS 무료 티어에 적합한 t2.micro 

 

4-3 보안 그룹

보안 그룹은 방화벽과 유사하게 동작한다. 모든 EC2 인스턴스에는 지정된 보안 그룹 집합이 있다. 각 보안 그룹에는 인바운드(인그레스-ingress) 및 아웃바운드(이그레스-egress) 트래픽을 허용하는 규칙이 있다.

tcp/3000 포트에서 동작하는 소규모 웹을 만들어보자.

tcp/22 포트의 인바운드 접속을 허용해 SSH 로 인스턴스에 접혹해보자.

 

EC2 인스턴스를 보호하는 보안 그룹은 서브넷에 연결되어 있고, 서브넷은 VPC가 제공하는 네트워크에 연결되어 있다.

이를 위해, 자체적인 네트워크가 있는 가상 데이터 센터라고 볼 수 있는 가상 사설 클라우드(VPC, Virtual Private Cloud) ID 를 찾아야한다.

$ aws ec2 describe-vpcs

{

    "Vpcs": [

        {

            "CidrBlock": "172.31.0.0/16",

            "DhcpOptionsId": "dopt-56efa03d",

            "State": "available",

            "VpcId": "vpc-9c98*****",

            "OwnerId": "394078117217",

            "InstanceTenancy": "default",

            "CidrBlockAssociationSet": [

                {

                    "AssociationId": "vpc-cidr-assoc-ee4ab785",

                    "CidrBlock": "172.31.0.0/16",

                    "CidrBlockState": {

                        "State": "associated"

                    }

                }

            ],

            "IsDefault": true

        }

    ]

}

 

이제 VPC ID 로 새로운 보안 그룹을 생성할 수 있다.

$ aws ec2 create-security-group --group-name HelloWorld --description "Hello World Demo" --vpc-id vpc-9c98*****

{

    "GroupId": "sg-02aa7a15**********"

}

 

기본적으로 보안 그룹은 인스턴스로부터의 모든 아웃바운드 트래픽을 허용한다.

tcp/22(SSH) 와 tcp/3000을 인바운드 트래픽으로 열자

$ aws ec2 authorize-security-group-ingress --group-name HelloWorld --protocol tcp --port 22 --cidr 0.0.0.0/0

{

    "Return": true,

    "SecurityGroupRules": [

        {

            "SecurityGroupRuleId": "sgr-0ecb245c6f70d2c8e",

            "GroupId": "sg-02aa7a15a52a37229",

            "GroupOwnerId": "394078117217",

            "IsEgress": false,

            "IpProtocol": "tcp",

            "FromPort": 22,

            "ToPort": 22,

            "CidrIpv4": "0.0.0.0/0"

        }

    ]

}

$ aws ec2 authorize-security-group-ingress --group-name HelloWorld --protocol tcp --port 3000 --cidr 0.0.0.0/0

{

    "Return": true,

    "SecurityGroupRules": [

        {

            "SecurityGroupRuleId": "sgr-0793b694de9e1e4f7",

            "GroupId": "sg-02aa7a15a52a37229",

            "GroupOwnerId": "394078117217",

            "IsEgress": false,

            "IpProtocol": "tcp",

            "FromPort": 3000,

            "ToPort": 3000,

            "CidrIpv4": "0.0.0.0/0"

        }

    ]

}

 

확인해보자

$ aws ec2 describe-security-groups --group-name HelloWorld --output text

SECURITYGROUPS  Hello World Demo        sg-02aa7a15a52a37229    HelloWorld      394078117217    vpc-9c9802f7

IPPERMISSIONS   22      tcp     22

IPRANGES        0.0.0.0/0

IPPERMISSIONS   3000    tcp     3000

IPRANGES        0.0.0.0/0

IPPERMISSIONSEGRESS     -1

IPRANGES        0.0.0.0/0

 

 

4-4 SSH 키 생성하기

EC2 에서 키 페어를 생성하고 캐인 키를 내려받을 수 있다.

$ aws ec2 create-key-pair --key-name EffectiveDevOpsAWS --query "KeyMaterial" --output text > ~/.ssh/EffectiveDevOpsAWS.pem

 

$ aws ec2 describe-key-pairs --key-name EffectiveDevOpsAWS

{

    "KeyPairs": [

        {

            "KeyPairId": "key-0ac8813***********",

            "KeyFingerprint": "2b:95:5a:9c:bd:fa:1****************",

            "KeyName": "EffectiveDevOpsAWS",

            "KeyType": "rsa",

            "Tags": [],

            "CreateTime": "2022-07-20T04:15:55+00:00"

        }

    ]

}

 

$ cat ~/.ssh/EffectiveDevOpsAWS.pem

-----BEGIN RSA PRIVATE KEY-----

MIIEowIBAAKCAQEAowewCqDX7LhTw6NgSMGJxorxfg2UhgJvKgk4ZxWIwEjnUU9q

TbR1iX5j+Rn3iqVyf//u2YgKDAqYyny32fLwj7Lxh2LHLMz5+F6kV253l8jlxYIn

...

-----END RSA PRIVATE KEY-----

 

$ chmod 400 ~/.ssh/EffectiveDevOpsAWS.pem

 

 

 

 

EC2 인스턴스 띄우기

더보기

인스턴스 띄워보자

$ aws ec2 run-instances --instance-type t2.micro --key-name EffectiveDevOpsAWS --security-group-ids sg-02aa7a15********** --image-id ami-0a10b2721688ce9d2

{

    "Groups": [],

    "Instances": [

        {

            "AmiLaunchIndex": 0,

            "ImageId": "ami-0a10b2721688ce9d2",

            "InstanceId": "i-0abd8725************",

            "InstanceType": "t2.micro",

            "KeyName": "EffectiveDevOpsAWS",

            "LaunchTime": "2022-07-20T04:32:14+00:00",

            "Monitoring": {

                "State": "disabled"

            },

            "Placement": {

                "AvailabilityZone": "ap-northeast-2c",

                "GroupName": "",

                "Tenancy": "default"

            },

            "PrivateDnsName": "ip-172-31-46-45.ap-northeast-2.compute.internal",

            "PrivateIpAddress": "172.31.46.45",

            "ProductCodes": [],

            "PublicDnsName": "",

            "State": {

                "Code": 0,

                "Name": "pending"

            },

            "StateTransitionReason": "",

            "SubnetId": "subnet-471ee608",

            "VpcId": "vpc-9c9802f7",

            "Architecture": "x86_64",

            "BlockDeviceMappings": [],

 

확인해 보자

$ aws ec2 describe-instance-status --instance-ids i-0abd8725************

{

    "InstanceStatuses": [

        {

            "AvailabilityZone": "ap-northeast-2c",

            "InstanceId": "i-0abd8725************",

            "InstanceState": {

                "Code": 16,

                "Name": "running"

            },

            "InstanceStatus": {

                "Details": [

                    {

                        "Name": "reachability",

                        "Status": "passed"

                    }

                ],

                "Status": "ok"

            },

            "SystemStatus": {

                "Details": [

                    {

                        "Name": "reachability",

                        "Status": "passed"

                    }

                ],

                "Status": "ok"

            }

        }

    ]

}

$ aws ec2 describe-instance-status --instance-ids i-0abd8725949bc6a5f --output text | grep -i SystemStatus

SYSTEMSTATUS ok

 

 

SSH 를 이용해 EC2 인스턴스에 접속하자

더보기

 인스턴스에 SSH 로 접속하기 위해서는 실행 중인 인스턴스의 DNS 명을 찾아야한다.

$ aws ec2 describe-instances --instance-ids i-0abd8725949bc6a5f --query "Reservations[*].Instances[*].PublicDnsName"

[

    [

        "ec2-3-35-52-157.ap-northeast-2.compute.amazonaws.com"

    ]

]

 

AMI 가 아마존 리눅스이므로 기본 사용자 계정은 ec2-user이다.

$ ssh -i ~/.ssh/EffectiveDevOpsAWS.pem ec2-user@ec2-3-35-52-157.ap-northeast-2.compute.amazonaws.com

The authenticity of host 'ec2-3-35-52-157.ap-northeast-2.compute.amazonaws.com (3.35.52.157)' can't be established.

ED25519 key fingerprint is SHA256:gINBw6TUhirBHbTXwZmAuBk4K5iXBF69j3zsciPyzVE.

This key is not known by any other names

Are you sure you want to continue connecting (yes/no/[fingerprint])? yes

Warning: Permanently added 'ec2-3-35-52-157.ap-northeast-2.compute.amazonaws.com' (ED25519) to the list of known hosts.

 

       __|  __|_  )

       _|  (     /   Amazon Linux AMI

      ___|\___|___|

 

https://aws.amazon.com/amazon-linux-ami/2018.03-release-notes/

37 package(s) needed for security, out of 62 available

Run "sudo yum update" to apply all updates.

[ec2-user@ip-172-31-46-45 ~]$ 

 

 

Node.js 로 간단한 웹을 띄워보자

더보기

아마존 리눅스는 레드햇 엔터프라이즈 리눅스 기반이고, 패키지를 설치 및 관리하는 데 yum 이라는 도구를 사용한다. 이 운영체제에는 엔터프라이즈 리눅스를 위한 부가 패키지(EPEL-Extra Packages for Enterprise Linux)가 미리 구성되어 있고, Node.js 는 EPEL에 포함되어 있다.

[ec2-user@ip-172-31-46-45 ~]$ sudo yum install --enablerepo=epel -y nodejs

[ec2-user@ip-172-31-46-45 ~]$ node -v

 

/home/ec2-user/helloworld.js 파일을 만들자

pwd 하면 현재 경로가 /home/ec2-user 이다.

[ec2-user@ip-172-31-46-45 ~]$ vim helloworld.js

var http = require("http")

http.createServer(function (request, response) {

   // Send the HTTP header
   // HTTP Status: 200 : OK
   // Content Type: text/plain
   response.writeHead(200, {'Content-Type': 'text/plain'})

   // Send the response body as "Hello World"
   response.end('Hello World\n')
}).listen(3000)

// Console will print the message
console.log('Server running')

[ec2-user@ip-172-31-46-45 ~]$ node helloworld.js

ec2-3-35-52-157.ap-northeast-2.compute.amazonaws.com:3000 

띄워진 것을 확인했다면, Ctrl+C로 웹 을 중지시키고

upstart 를 사용해 간단한 코드를 서비스로 전환해보자

- 아마존 리눅스는 표준 레드햇 기반 배포판과 달리 upstart 라는 시스템 콜을 갖고 있다.

- upstart 구성을 추가하려면 EC2 인스턴스의 /etc/init에 파일을 생성하면 된다.

/etc/init/helloworld.conf 를 만들어보자

 

[ec2-user@ip-172-31-46-45 ~]$ sudo vim /etc/init/helloworld.conf

description "Hello world Deamon"

# Start when the system is ready to do networking.
# 시스템의 네트워크가 준비되면 시작(AWS 네트워크가 ENI[Elastic Network Interfaces] 기반이기에)
start on started elastic-network-interfaces

# Stop when the system is on its way down.
# 시스템이 다운되면 중지
stop on shutdown

respawn
script
    exec su --session-command="/usr/bin/node /home/ec2-user/helloworld.js" ec2-user
end script

 

 실행해 보자

[ec2-user@ip-172-31-46-45 ~]$ sudo start helloworld

helloworld start/running, process 13002

 

 

종료해 보자

Stop 명령어를 이용해 서비스를 완전히 종료하고 가상 서버에서 로그아웃한 후 인스턴스를 종료할 수 있다.

ec2-user@ip-172-31-46-45 ~]$ sudo stop helloworld

helloworld stop/waiting

[ec2-user@ip-172-31-46-45 ~]$ ec2-metadata -i

instance-id: i-0abd8725949bc6a5f

[ec2-user@ip-172-31-46-45 ~]$ exit

logout

$ aws ec2 terminate-instances --instance-ids i-0abd8725949bc6a5f

{

    "TerminatingInstances": [

        {

            "CurrentState": {

                "Code": 32,

                "Name": "shutting-down"

            },

            "InstanceId": "i-0abd8725949bc6a5f",

            "PreviousState": {

                "Code": 16,

                "Name": "running"

            }

        }

    ]

}

 

추가적으로 upstart 로 jar 파일은 다음과 같이 실행하면 되는 것 같다.

참고 URL1

참고 URL2

 

 

728x90