Skip to content

youngwjung/eb-lab

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 

Repository files navigation

AWS Elastic Beanstalk

Elastic Beanstalk은 AWS에 어플리케이션을 배포하는 가장 간편하고 빠른 방법으로 Java, .NET, PHP, Node.js, Python, Ruby, Go, Docker를 사용하여 Apache, Nginx, IIS와 같은 서버에서 구동되는 웹서비스들을 지원합니다. 사용자를 대신해서 인프라를 프로비저닝해주고 업데이트 및 패치도 간단하게 적용할수 있습니다. 인프라 운영 오버헤드등을 줄여서 개발에 더 집중할수 있도록 도와주는 PaaS 입니다.

Lab Overview

  1. Open Source Python Django Application을 Elastic Beanstalk에 배포

  2. 구성파일(ebextensions)로 환경구성 Customization

  3. AWS CodePipeline 으로 배포 자동화 구성

  4. AWS KMS & Systems Manager로 Parameter 암호화

시작하기전에

  1. 본 Hands-on lab에서 사용할 Application 예제는 MDN (the Mozilla Developer Network) 에서 만든 튜토리얼의 예제입니다.
  2. 본 Hands-on lab은 AWS Seoul region 기준으로 작성되었습니다. Region을 Seoul (ap-northeast-2)로 변경 후 진행 부탁드립니다.
  3. AWS Credit 추가하기
  4. Lab 환경 구축

Elastic Beanstalk 환경 구성

  1. AWS Management Console에서 좌측 상단에 있는 [Services] 를 선택하고 검색창에서 Elastic Beanstalk을 검색하거나 [Compute] 밑에 있는 [Elastic Beanstalk] 를 선택

  2. [Create New Application]Application Name = local-library → [Create]

  3. Elastic Beanstalk Application Dashboard 에서 [Actions][Create environment]Web server environment 🔘 → [Select]

  4. Environment name = local-library-<YOUR_INITIAL>,
    Domain = local-library-<YOUR_INITIAL>,
    Platform = 🔘 Python - Amazon Linux 1,
    Application code = 🔘 Sample application,
    [Configure more options]

  5. Configuration presets = 🔘 High availability

  6. [Capacity][Modify]Instance type = m5.large, Metric = CPUUtilization, Unit = Percent, Upper threshold = 80, Lower threshold = 30 → [Save]

  7. [Security][Modify]EC2 key pair = EC2 인스턴스에 접속할 Key pair 지정, IAM instance profile = eb-lab-InstanceProfile-XXXXX → [Save]

  8. [Network][Modify]VPC = eb-vpc, Load balancer visibility = Public, Load balancer subnets = 모든 public subnet 선택, Instance subnets = 모든 private subnet 선택 → [Save]

  9. [Create environment]

Application 배포

  1. AWS Management Console에서 좌측 상단에 있는 [Services] 를 선택하고 검색창에서 Cloud9를 검색하거나 [Developer Tools] 밑에 있는 [Cloud9] 를 선택 → [Open IDE]

  2. 해당 링크를 참고해서 EB CLI 설치

  3. 해당 Git Repository를 Fork (GitHub 계정 필수)

  4. Forking한 Repository를 Cloud9으로 환경으로 Clone

    git clone http://<REPOSITORY_URL>
  5. 위에서 Clone한 로컬 Git Repository의 Root 디렉토리로 이동 후 EB CLI 설정

    eb init
    Select a default region: 10) ap-northeast-2 : Asia Pacific (Seoul)
    Select an application to use: 1) local-library
    Do you wish to continue with CodeCommit? (y/N): N
  6. EB CLI로 Application 배포

    eb deploy
  7. Elastic Beanstalk 도메인 주소로 접속해서 어플리케이션이 정상적으로 작동하는지 확인. 에러발생시 아래의 커맨드로 Log를 확인

    eb logs -a

Configuration & Customization

WSGI 설정

  1. EB Dashboard에서 [Configuration] → Category가 Software 인 탭에서 [Modify] 클릭 → WSGIPath = locallibrary/wsgi.py → [Apply]

ALLOWED_HOSTS 설정

  1. locallibrary/settings.py 파일을 열고 아래와 같이 수정

    ALLOWED_HOSTS = ['.elasticbeanstalk.com']
  2. EB CLI로 Application 배포 후 변경사항이 적용됬는지 확인

  3. 수정한 코드를 Commit & Push

    git add .
    git commit -m "fixed DisallowedHost error"
    git push
  4. EB CLI로 Application 배포 후 변경사항이 적용됬는지 확인

Custom script 실행

  1. ebextensions 폴더 생성

    mkdir .ebextensions
  2. configuration 파일 셍성

    touch .ebextensions/05_django.config
  3. .ebextensions/05_django.config 파일을 열고 아래의 코드블록 붙여넣기

    container_commands:
      01_collect_static:
        command: python manage.py collectstatic
      02_migrate:
        command: python manage.py migrate --noinput
        leader_only: true

Database 연결

  1. PostgreSQL client 설치

    sudo yum install postgresql -y
  2. RDS 인스턴스에 접속 (RDS Endpoint는 RDS Console에서 확인 가능)

    psql -h eb-postgres.xxxxxx.ap-northeast-2.rds.amazonaws.com -U master postgres
  3. 접속이 안될 경우 RDS 인스턴스에 붙어있는 Security Group에 Cloud9 인스턴스에서 PostgreSQL 포트로 접속 가능한 Inbound rule을 설정

  4. 아래와 같이 비밀번호 입력창이 나올경우, asdf1234를 입력

    Password for user master:
  5. Database 생성

    CREATE DATABASE local_library;
  6. Database User 생성

    CREATE USER local_library WITH PASSWORD 'asdf1234';
  7. Database User에 권한 부여

    GRANT ALL PRIVILEGES ON DATABASE local_library TO local_library;
  8. locallibrary/settings.py 파일을 열고 아래와 같이 수정

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.postgresql_psycopg2',
            'NAME': 'local_library',
            'USER': 'local_library',
            'PASSWORD': 'asdf1234',
            'HOST': '<RDS_ENDPOINT>',
            'PORT': '5432',
        }
    }
  9. locallibrary/settings.py 파일을 열고 아래와 같은 코드블록을 삭제

    # Heroku: Update database configuration from $DATABASE_URL.
    import dj_database_url
    db_from_env = dj_database_url.config(conn_max_age=500)
    DATABASES['default'].update(db_from_env)
  10. 수정한 코드를 Commit & Push하고 EB CLI를 통해서 Application 배포

CodePipeline 구축

  1. AWS Management Console에서 좌측 상단에 있는 [Services] 를 선택하고 검색창에서 CodePipeline를 검색하거나 [Developer Tools] 밑에 있는 [CodePipeline] 를 선택

  2. [Create pipeline]Pipeline name = eb, Service role = New service role → [Next]Source provider = GitHub → [Connect to GitHub]Repository = 랩 시작할때 Forking한 Repository, Branch = master → [Skip build stage]

  3. Deploy provider = AWS Elastic Beanstalk, Application nameEnvironment name에 위에서 생성한 리소스들을 넣고 [Next][Create pipeline]

Autoscaling 설정

ELB Health check 설정

  1. locallibrary/settings.py 파일을 열고 아래와 같은 코드블록을 붙여넣기

    # Get the private IP address of the instance to stop Sentry errors from
    # Load Balancer health checks.
    import requests
    
    PRIVATE_IP_URL = 'http://169.254.169.254/latest/meta-data/local-ipv4'
    PRIVATE_IP_REQUEST_DATA = requests.get(PRIVATE_IP_URL)
    if PRIVATE_IP_REQUEST_DATA:
        IP_ADDRESS = PRIVATE_IP_REQUEST_DATA.text
    
        ALLOWED_HOSTS.append(IP_ADDRESS)
  2. requirements.txt파일을 열고 아래의 라인을 추가

    requests==2.22.0
  3. 수정한 코드를 Commit & Push

  4. Load balancer 설정에서 Health check path/catalog/로 변경하고 적용

  5. Health Status가 ✅ OK 로 변했는지 확인

Autoscaling 테스트

  1. AWS Management Console 좌측 상단에 있는 [Services] 를 선택하고 검색창에서 ssm를 검색하고 [Systems Manager] 를 선택

  2. Systems Manager Dashboard 왼쪽 패널 Instances & Nodes 섹션 아래에 있는 [Session Manager] 선택

  3. [Start Session] → Instance Name: local-library-xxx 선택 → [Start Session] 클릭

  4. Root 환경으로 전환

    sudo -i
  5. Stress utility 설치

    yum install stress -y
  6. CPU load 생성

    stress --cpu 4 --timeout 600
  7. 신규 인스턴스가 생성되는지 확인

Auto-healing 테스트

  1. Session Manager를 통해서 EC2 인스턴스에 접속

  2. Apache HTTP Server 정지

    sudo service httpd stop
  3. 인스턴스가 자동으로 복구되는지 확인 후 Cloud9 IDE 실행

  4. configuration 파일 셍성

    touch .ebextensions/03_autoscaling.config
  5. .ebextensions/03_autoscaling.config 파일을 열고 아래의 코드블록 붙여넣기

    Resources:
      AWSEBAutoScalingGroup:
        Type: "AWS::AutoScaling::AutoScalingGroup"
        Properties:
          HealthCheckType: ELB
          HealthCheckGracePeriod: 300
  6. 수정한 코드를 Commit & Push

  7. 다시 EC2 인스턴스에 접속해서 Apache HTTP Server 정지하고 기존 인스턴스가 새로운 인스턴스로 교체되는지 확인

SSM Parameter Store 설정

KMS 암호화 키 생성

  1. AWS Management Console 좌측 상단에 있는 [Services] 를 선택하고 검색창에서 kms를 검색하고 [Key Management Service] 를 선택

  2. [Customer managed keys][Create key]Key type = Symmetric → [Next]Alias = eb → [Next]Key administrators = 해당 암호화키에 관리자 권한을 줄 IAM 유저 선택 → [Next]This account 탭에서 eb-lab-IAMRole-xxxx를 선택 → [Next][Finish]

SSM Parameter 생성

  1. AWS Management Console 좌측 상단에 있는 [Services] 를 선택하고 검색창에서 ssm를 검색하고 [Systems Manager] 를 선택

  2. Systems Manager Dashboard 왼쪽 패널 Application Management 섹션 아래에 있는 [Parameter Store] 선택

  3. [Create parameter]Name = /LOCAL_LIBRARY/DB_PASSWORD, Tier = Standard, Type = SecureString, KMS Key ID = alias/eb, Value = asdf1234 → [Create parameter]

IAM Role 권한 설정

  1. AWS Management Console에서 좌측 상단에 있는 [Services] 를 선택하고 검색창에서 IAM를 검색하거나 [Security, Identity, & Compliance] 바로 밑에 있는 [IAM] 를 선택

  2. [Roles]eb-lab-IAMRole-xxxx를 선택

  3. [Add inline policy] 선택 후, Service = Systems Manager, Actions = GetParameter, Resources = ✅ Specific → [Add ARN], Region = ap-northeast-2, Fully qualified parameter name = LOCAL_LIBRARY/DB_PASSWORD → [Add], [Review policy] 클릭, Name = ssm_get_param, [Create policy] 클릭

Application 설정 파일 수정

  1. locallibrary/settings.py 파일을 열고 DATABASES 블록 위에 아래의 코드블록을 붙여넣기

    # SSM
    import boto3
    ## Create the SSM Client
    ssm = boto3.client(
        'ssm',
        region_name='ap-northeast-2'
    )
    
    ## Get the requested parameter
    response = ssm.get_parameter(
        Name='/LOCAL_LIBRARY/DB_PASSWORD',
        WithDecryption=True
    )
    
    DB_PASSWORD = response['Parameter']['Value']
  2. locallibrary/settings.py 파일을 열고 DATABASES 블록을 아래와 같이 수정

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.postgresql_psycopg2',
            'NAME': 'local_library',
            'USER': 'local_library',
            'PASSWORD': DB_PASSWORD,
            'HOST': '<RDS_ENDPOINT>',
            'PORT': '5432',
        }
    }
  3. requirements.txt파일을 열고 아래의 라인을 추가

    boto3==1.11.9
  4. 수정한 코드를 Commit & Push

APM with X-Ray

  1. EB Dashboard에서 [Configuration] → Category가 Software 인 탭에서 [Modify] 클릭 → X-Ray Daemon ✅ Enabled → [Apply]

    Elastic Beanstalk 환경에 기본으로 X-Ray Daemon이 설치됩니다만 위의 옵션설정으로 실행시켜주어야 합니다

  2. requirements.txt파일을 열고 아래의 라인을 추가 (AWS X-Ray SDK for Python 설치)

    aws-xray-sdk==2.4.3
  3. locallibrary/settings.py 파일을 열고 INSTALLED_APPS 블록에 aws_xray_sdk.ext.django 추가

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        # Add our new application
        'catalog.apps.CatalogConfig', #This object was created for us in /catalog/apps.py,
        'aws_xray_sdk.ext.django',
    ]
  4. locallibrary/settings.py 에서 MIDDLEWARE 블록에 aws_xray_sdk.ext.django.middleware.XRayMiddleware 추가

    MIDDLEWARE = [
        'django.middleware.security.SecurityMiddleware',
        'whitenoise.middleware.WhiteNoiseMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
        'aws_xray_sdk.ext.django.middleware.XRayMiddleware',
    ]
  5. locallibrary/settings.py 에서 아래의 코드블록을 붙여넣기

    XRAY_RECORDER = {
        'AWS_XRAY_DAEMON_ADDRESS': '127.0.0.1:2000',
        'AUTO_INSTRUMENT': True,  # If turned on built-in database queries and template rendering will be recorded as subsegments
        'AWS_XRAY_CONTEXT_MISSING': 'LOG_ERROR',
        'PLUGINS': (),
        'SAMPLING': True,
        'SAMPLING_RULES': None,
        'AWS_XRAY_TRACING_NAME': 'locallibrary', # the segment name for segments generated from incoming requests
        'DYNAMIC_NAMING': None, # defines a pattern that host names should match
        'STREAMING_THRESHOLD': None, # defines when a segment starts to stream out its children subsegments
    }
  6. IAM Dashboard로 이동해서 eb-lab-IAMRole-xxxxAWSXRayWriteOnlyAccess 정책 연결

  7. 수정한 코드를 Commit & Push

  8. 웹 어플리케이션에 접속 후 Browising

  9. AWS Management Console에서 좌측 상단에 있는 [Services] 를 선택하고 검색창에서 X-Ray를 검색하거나 [Developer Tools] 밑에 있는 [X-Ray] 를 선택

  10. X-Ray Dashboard에서 [Traces] 선택

    • 각 URL별 응답속도 확인
    • Trace list 에서 Response Time 이 가장 긴 Trace를 선택 후 Raw data 에서 subsegments 확인