Deploy Laravel 6 app to AWS Elastic Beanstalk

Mac 에 PHP 7.3 설치

사용하는 Mac 의 PHP 버젼이 behind 7.3 였기에, 다음 링크를 참고하여, Homebrew 로 7.3 을 설치했다.

https://stitcher.io/blog/php-73-upgrade-mac

아래 PATH 를 .zshrc 에 추가하고, php -v 했을때 7.3.12 가 출력되는 것을 확인했다.

  echo 'export PATH="/usr/local/opt/[email protected]/bin:$PATH"' >> ~/.zshrc
  echo 'export PATH="/usr/local/opt/[email protected]/sbin:$PATH"' >> ~/.zshrc

Mac 에 Python 3.7 설치

내친김에 Python 도 업그레이드. 아래 PATH 를 .zshrc 에 추가하고, 버젼을 확인했다.

export PATH="/usr/local/opt/python/libexec/bin:$PATH"

Mac 에 EB-CLI 설치

EB CLI 가 없는 PC 였기에, 다음 링크를 참고하여, Homebrew 로 CLI 를 설치했다.

https://docs.aws.amazon.com/ko_kr/elasticbeanstalk/latest/dg/eb-cli3-install-osx.html

Mac 에 AWS-CLI 설치

brew install awscli 명령으로 설치했다. IAM 사용자 생성 후, configuration 해야만 된다.

RDB 생성

Poorman’s DB Client 인 Sequel Pro 를 사용하는 탓에 Free Tier 에 맞는 template 을 사용하여, RDB 를 생성시 MySQL 5.7 버젼을 선택했다. Public accessibility 은 YES 로 설정하여, Mac 에서 접속이 가능토록 했다. (지금까지의 설정으로 외부 접속이 가능한듯 싶었으나, 인바운드 3306 포트를 연 커스텀 VPC security group 을 추가하지 않으면 접속이 불가능 했다. default security group 의 인바운드/아웃바운드 규칙을 보면 wide-open 으로 되어있기 때문에, 접속이 불가능한 이유가 명쾌하게 이해되지 않지만, anyway 새로운 인프라마다 필요한 security group 을 추가해야 한다고 경험상 알고 있다. 가령 redis 는 redis_sg 를 추가하고 rdb 는 rdb_sg 를 추가한다.)

Elastic Beanstalk 앱 생성

Web Server 환경으로 콘솔의 요구사항을 입력하여, High availability 설정 preset 을 선택하면 Application Load Balancer 를 포함하는 PHP v7.3 앱 환경을 생성할 수 있는데, 이 설정은 production 이라는 이름으로 생성했다. 다른 모든 옵션은 default 로 설정했다. 로드 밸런서가 만들어지면, Route53 과 Aliased A 레코드를 넣어서 연결하면 된다. ACM (Amazon Certificate Manager) 으로 설정하면 https 에 필요한 certificate 에 필요한 CNAME 레코드 생성과 자동갱신등이 지원되므로 관리적인 측면에서 상당히 편리하다.

EB CLI 설치 및 IAM 메뉴에서 사용자 생성

eb init 을 이용하여, 최초 초기화를 하려 했을때, credentials 을 설정하지 않았다는 에러메시지가 나왔다. IAM 메뉴로 이동할 차례이다. Add user 메뉴에서 관리자 계정을 생성한다. 이를 통하여, Access key ID 와 Secret access key 를 받는다. 이는 eb CLI 의 aws-access-id 와 aws-secret-key 로 대응된다. (이런 이름의 불일치는 attention to detail competency 가 떨어져 보이지만, anyway.) 이제, 코드 베이스에 .elasticbeanstalk 폴더가 생성된 것이 보인다.

EB 가 생성한 EC2 는 S3 와 SQS 에 대한 access 권한이 있어야 하는데, 이는 IAM 메뉴의 Roles 항목에서 aws-elasticbeanstalk-ec2-role 에 추가했다.

AWS Console 에서 production 환경 변경

production > configuration 에 container option 을 보면, Document root 옵션이 있는데, 이를 /public 으로 수정했다.

ElastiCache Redis 설정

PHP 의 Redis 라이브러리인 predis/predis 가 버려진 프로젝트가 되었기에, EB 환경에 php-redis/php-redis 를 소스 설치를 위한 아래의 설정을 추가했다. Redis 설정은 간단하므로 생략한다. 다만, redis-sg 를 만들어서, 인바운드 port 를 열어두는 걸 잊지 말자. 아, 그리고 Laravel config/app.php 파일의 facade alias 인 Redis 를 클래스 충돌을 방지하기 위해 RedisManager 로 변경하라는 매뉴얼의 조언도 따랐다.

# these commands run before the application and web server are
# set up and the application version file is extracted.
commands:
    01_redis_install:
        # run this command from /tmp directory
        cwd: /tmp
        # don't run the command if phpredis is already installed (file /etc/php.d/redis.ini exists)
        test: '[ ! -f /etc/php.d/redis.ini ] && echo "phpredis extension not installed"'
        # executed only if test command succeeds
        command: |
            wget https://github.com/phpredis/phpredis/zipball/master -O phpredis.zip \
            && unzip -o phpredis.zip \
            && cd phpredis-* \
            && phpize \
            && ./configure \
            && make \
            && make install \
            && echo extension=redis.so > /etc/php.d/redis.ini

AWS s3

모두 default 옵션을 선택후, 버킷의 public access 설정을 아래의 링크를 참조하여 셋팅했다.

https://docs.aws.amazon.com/ko_kr/AmazonS3/latest/user-guide/block-public-access-bucket.html

버킷은 environment 변수 저장용 1개, 이미지 저장용 1개 통합 2개를 생성했다.

Laravel 프로덕션 환경용 .env 파일 s3 업로드

아래 명령으로 .env 파일을 s3 에 저장했다.

aws s3 cp .env.production s3://amuse-environment/.env

eb ssh 셋업

eb ssh --setup 을 입력하고 환경명을 지정하면, 다음과 같이 ssh 키를 생성후 업로드 할 수 있다.

eb ssh production 명령으로 해당 환경 EC2 인스턴스 ssh 접속이 가능해졌다.

.ebextensions 폴더 셋업

구체적인 셋업은 application specific 한 부분이므로, codebase 내에 있는 .config 파일들을 참고하기로 한다.

s3 bucket policy

웹앱에서 보여질 images 폴더에 버킷 정책을 아래와 같이 설정했다.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::amuse-images/*"
            ]
        }
    ]
}

To-dos left

지금까지의 작업으로, EB 를 이용하여 하나의 코드베이스로 작업되어 있는 API 및 back-office 앱을 배포했고, 최소한의 기능이 정상 동작하는 것을 확인했다. 하지만, 아래와 같은 작업들이 추가로 진행되어야만 하는데, 이를 위한 필요한 설정 등은 기회가 되면 다음번에 올려보기로 한다.

CloudFront 구성

Leave a Reply