dev

EC2에 GitHub Actions self-hosted runner 띄우기

Wonny (워니)
Wonny (워니)·2022년 09월 06일 06:00

GitHub Actions self-hosted runner가 필요했던 이유

이번에 새로 구축하게 된 파트너 계정 시스템 어플리케이션과 이 시스템에서 사용할 데이터베이스를 내부 private VPC에 배치했다. 파트너 계정 시스템 어플리케이션은 ASP.NET를 프레임워크로 사용하고, ORM으로 Entity Framework(이하 엔티티 프레임워크)를 사용하게 되었다.

이 상황에서 어플리케이션 내부 코드가 데이터베이스에 엑세스하는 경우에는 같은 네트워크에 있어서 권한 이슈가 발생하지 않는다. 그러나 엔티티 프레임워크를 이용하여 데이터베이스 마이그레이션을 하는 명령어의 경우 코드를 배치하는 GitHub Actions(이하 깃헙 액션) 워크플로우에서 실행되므로 같은 네트워크에 속하지 않아 권한 이슈가 발생한다. 다음과 같이 타임아웃 에러가 보인다.

dotnet ef database update --project Partners/Partners.DataAccess --startup-project Partners/Partners.Api --connection "$CONNECTION_STRING" info: Microsoft.EntityFrameworkCore.Infrastructure[10403] Entity Framework Core 6.0.8 initialized 'PartnersDbContext' using provider 'Npgsql.EntityFrameworkCore.PostgreSQL:6.0.6+6fa8f3c27a7c241a66e72a6c09e0b252509215d0' with options: None Npgsql.NpgsqlException (0x80004005): Failed to connect to 0.00.000.000:3306 ---> System.TimeoutException: Timeout during connection attempt at Npgsql.Internal.NpgsqlConnector.Connect(NpgsqlTimeout timeout) at Npgsql.Internal.NpgsqlConnector.Connect(NpgsqlTimeout timeout) at Npgsql.Internal.NpgsqlConnector.RawOpen(SslMode sslMode, NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken, Boolean isFirstAttempt) at Npgsql.Internal.NpgsqlConnector.<Open>g__OpenCore|191_1(NpgsqlConnector conn, SslMode sslMode, NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken, Boolean isFirstAttempt) at Npgsql.Internal.NpgsqlConnector.Open(NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken) at Npgsql.UnpooledConnectorSource.Get(NpgsqlConnection conn, NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken) at Npgsql.NpgsqlConnection.<Open>g__OpenAsync|45_0(Boolean async, CancellationToken cancellationToken) at Npgsql.NpgsqlConnection.Open() at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenDbConnection(Boolean errorsExpected) at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenInternal(Boolean errorsExpected) at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.Open(Boolean errorsExpected) at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlDatabaseCreator.Exists(Boolean async, CancellationToken cancellationToken) at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlDatabaseCreator.Exists(Boolean async, CancellationToken cancellationToken) at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlDatabaseCreator.Exists() at Microsoft.EntityFrameworkCore.Migrations.HistoryRepository.Exists() at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.Migrate(String targetMigration) at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.UpdateDatabase(String targetMigration, String connectionString, String contextType) at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabaseImpl(String targetMigration, String connectionString, String contextType) at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabase.<>c__DisplayClass0_0.<.ctor>b__0() at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action) Failed to connect to 0.00.000.000:3306

이를 해결하기 위해서는 ssh를 통해 데이터베이스에 접근해야 하는데, 화이트리스트에 등록되지 않은 외부 IP에서는 ssh 접근을 할 수 없었다. 깃헙 액션의 IP를 화이트리스트에 추가하는 방법이 있긴 하지만 너무 많은 IP가 존재하기도 하고, 느낌상 안정적이지 않았다. 그렇다고 이를 위해 모든 IP에서 접속할 수 있게 보안을 열 수는 없기에 ssh 접속을 할 수 있는 EC2를 생성하고, 이 EC2를 깃헙 액션 self-hosted runner로 사용하기로 했다.

EC2에 GitHub Actions self-hosted runner를 띄우는 방법

  1. 데이터베이스에 ssh 접근이 가능한 EC2 인스턴스를 생성한다. (이 부분은 인프라 담당하시는 분이 진행해주셨다.)
  2. Repository 혹은 Organization 페이지에서 Settings 페이지로 이동한다.
    • Repository의 설정 페이지에서 진행하는 경우 생성한 EC2를 해당 Repository에서만 사용할 수 있고, Organization의 설정 페이지에서 진행하는 경우 Orgranization에 포함된 모든 Repository에서 사용할 수 있다.
  3. Settings 페이지의 사이드바에 있는 Actions > Runners 메뉴로 이동한 후, [New runner] 버튼을 클릭하여 러너 생성 페이지로 이동한다. github actions self hosted runnder on ec2 1
  4. ssh 명령어를 사용하여 EC2 접속한 후 러너 생성 페이지에 나와있는 가이드대로 진행한다. 가이드가 잘되어 있어서 별다른 설명없이도 막힘없이 진행할 수 있었다. github actions self hosted runnder on ec2 2 github actions self hosted runnder on ec2 3
  5. 가이드 마지막에 ./run.sh 명령어를 사용하게 되어있는데 이 명령어를 사용하는 경우 세션이 종료되는 경우 프로그램 실행도 멈춘다. 그러므로 nohup ./run.sh 명령어를 사용하여 세션이 종료되어도 프로그램 실행이 유지되도록 한다.
  6. 설정을 잘 완료하였다면 러너 페이지에서 등록한 러너의 상태가 Offline이 아닌 Idle로 보여야 한다. github actions self hosted runnder on ec2 4
  7. 이후에는 해당 러너를 사용할 워크플로우의 runs-on 옵션에서 설정한 라벨을 사용하여 사용할 러너를 지정해주면 된다. - yaml runs-on: [self-hosted, Linux, X64]

그 외

여러 Organization에서 동일한 러너를 사용하고 싶은 니즈도 있었으나, 현재 GitHub 정책상으로는 엔터프라이즈 플랜을 사용해야지만 엔터프라이즈 레벨에서 여러 조직에서 사용할 수 있는 러너를 설정할 수 있었다.

Reference

Github actions self-hosted runner를 EC2에서 동작시키기 [[현구막]]

틀린 표현이 있을 수 있습니다. 발견하시면 알려주세요! 🤓


dev
github actions
© 2020 Wonny.