GitLab CI/CD에서 AWS Secrets Manager 시크릿 사용
Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
GitLab CI/CD 파이프라인에서 AWS Secrets Manager에 저장된 시크릿을 사용할 수 있습니다. aws_secrets_manager 키워드로 정의하여 작업에서 AWS Secrets Manager에 저장된 시크릿을 사용할 수 있습니다.
히스토리
GitLab CI/CD 파이프라인에서 AWS Secrets Manager에 저장된 시크릿을 사용할 수 있습니다.
사전 요구 사항:
- AWS 계정에서 AWS Secrets Manager에 접근할 수 있어야 합니다.
- 다음 방법 중 하나를 사용하여 인증을 구성합니다:
- IAM 역할: GitLab Runner 인스턴스에 할당된 IAM 역할을 사용합니다.
- OpenID Connect: AWS에서 OpenID Connect 구성으로 임시 자격 증명을 검색합니다.
- AWS 구성에 대한 세부 정보를 제공하기 위해 프로젝트에 CI/CD 변수를 추가합니다:
AWS_REGION: 시크릿이 저장된 AWS 리전.AWS_ROLE_ARN: 가정할 AWS IAM 역할의 ARN (OpenID Connect 사용 시 필수).AWS_ROLE_SESSION_NAME: 선택 사항. 가정된 역할에 대한 커스텀 세션 이름.
CI/CD 작업에서 AWS Secrets Manager 시크릿 사용#
IAM 역할 인증 사용#
aws_secrets_manager 키워드로 정의하여 작업에서 AWS Secrets Manager에 저장된 시크릿을 사용할 수 있습니다.
이 방법은 GitLab Runner 인스턴스에 할당된 IAM 역할을 사용합니다. Kubernetes executor 또는 자동 확장을 사용할 때 IAM 역할이 러너 관리자에 적용되어 있는지 확인합니다.
사전 요구 사항:
- GitLab Runner 18.3 이상.
예를 들어:
variables:
AWS_REGION: us-east-1
database-migration:
secrets:
DATABASE_PASSWORD:
aws_secrets_manager:
secret_id: app-secrets/database
field: 'password'
file: false
stage: deploy
script:
- echo "Running database migration..."
- mysql -h $DB_HOST -u $DB_USER -p$DATABASE_PASSWORD < migration.sql
- echo "Migration completed successfully."
OpenID Connect 인증 사용#
강화된 보안을 위해 OpenID Connect를 사용하여 AWS를 인증하고 특정 IAM 역할을 가정할 수 있습니다.
기본적으로 러너는 AWS_ID_TOKEN이라는 ID 토큰을 찾습니다. 예를 들어:
variables:
AWS_REGION: us-east-1
AWS_ROLE_ARN: 'arn:aws:iam::123456789012:role/gitlab-secrets-role'
database-migration:
id_tokens:
AWS_ID_TOKEN:
aud: 'sts.amazonaws.com'
secrets:
DATABASE_PASSWORD:
aws_secrets_manager:
secret_id: app-secrets/database
field: 'password'
file: false
stage: deploy
script:
- echo "Connecting to production database..."
- psql postgresql://$DB_USER:$DATABASE_PASSWORD@$DB_HOST:5432/$DB_NAME -c "SELECT version();"
- echo "Database connection successful."
token 옵션을 사용하여 커스텀 토큰을 지정할 수도 있습니다. 예를 들어:
variables:
AWS_REGION: us-east-1
AWS_ROLE_ARN: 'arn:aws:iam::123456789012:role/gitlab-secrets-role'
database-migration:
id_tokens:
CUSTOM_AWS_TOKEN:
aud: 'sts.amazonaws.com'
secrets:
DATABASE_PASSWORD:
aws_secrets_manager:
secret_id: app-secrets/database
field: 'password'
token: $CUSTOM_AWS_TOKEN
file: false
stage: deploy
script:
- echo "Connecting to production database with custom token..."
- psql postgresql://$DB_USER:$DATABASE_PASSWORD@$DB_HOST:5432/$DB_NAME -c "SELECT version();"
- echo "Database connection successful."
단축 구문#
시크릿 ID를 문자열로 지정하여 단순화된 구문을 사용할 수 있습니다.
선택적으로 # 문자로 구분하여 필드를 지정할 수 있습니다.
예를 들어:
variables:
AWS_REGION: us-east-1
api-deployment:
secrets:
API_KEY:
aws_secrets_manager: 'app-secrets/api#api_key'
file: false
FULL_SECRET:
aws_secrets_manager: 'app-secrets/api'
file: false
stage: deploy
script:
- echo "Deploying API with specific field..."
- curl --header "Authorization: Bearer $API_KEY" https://api.example.com/deploy
- echo "Using full secret..."
- curl --header "Authorization: Bearer $(cat $FULL_SECRET | jq --raw-output '.api_key')" https://api.example.com/status
시크릿 버전 관리#
AWS Secrets Manager는 시크릿의 여러 버전을 지원합니다. version_id 또는 version_stage를 사용하여 특정 버전을 지정할 수 있습니다. 예를 들어:
variables:
AWS_REGION: us-east-1
production-deployment:
secrets:
DATABASE_PASSWORD:
aws_secrets_manager:
secret_id: prod-app-secrets/database
field: 'password'
version_stage: 'AWSCURRENT'
file: false
STAGING_DATABASE_PASSWORD:
aws_secrets_manager:
secret_id: prod-app-secrets/database
field: 'password'
version_id: '01234567-89ab-cdef-0123-456789abcdef'
file: false
stage: deploy
script:
- echo "Deploying to production with current secret version..."
- deploy-prod.sh --db-password $DATABASE_PASSWORD
- echo "Testing with specific secret version..."
- test-with-version.sh --db-password $STAGING_DATABASE_PASSWORD
크로스 계정 시크릿 접근#
다른 AWS 계정에서 시크릿을 검색하려면 전체 ARN을 사용해야 합니다. 예를 들어:
variables:
AWS_REGION: us-east-1
AWS_ROLE_ARN: 'arn:aws:iam::123456789012:role/cross-account-secrets-role'
cross-account-deployment:
id_tokens:
AWS_ID_TOKEN:
aud: 'sts.amazonaws.com'
secrets:
SHARED_API_KEY:
aws_secrets_manager:
secret_id: 'arn:aws:secretsmanager:us-east-1:987654321098:secret:shared-api-keys-AbCdEf'
field: 'production_key'
file: false
stage: deploy
script:
- echo "Accessing shared secret from another account..."
- curl --header "Authorization: Bearer $SHARED_API_KEY" https://shared-api.example.com/deploy
시크릿별 구성 재정의#
시크릿별로 글로벌 AWS 설정을 재정의할 수 있습니다. 예를 들어:
variables:
AWS_REGION: us-east-1
AWS_ROLE_ARN: 'arn:aws:iam::123456789012:role/default-role'
multi-region-deployment:
id_tokens:
AWS_ID_TOKEN:
aud: 'sts.amazonaws.com'
EU_AWS_TOKEN:
aud: 'sts.amazonaws.com'
secrets:
EU_DATABASE_PASSWORD:
aws_secrets_manager:
secret_id: eu-app-secrets/database
field: 'password'
region: 'eu-west-1'
role_arn: 'arn:aws:iam::123456789012:role/eu-deployment-role'
role_session_name: 'gitlab-eu-deployment'
token: $EU_AWS_TOKEN
file: false
US_DATABASE_PASSWORD:
aws_secrets_manager:
secret_id: us-app-secrets/database
field: 'password'
file: false
stage: deploy
script:
- echo "Deploying to EU region..."
- deploy-to-eu.sh --db-password $EU_DATABASE_PASSWORD
- echo "Deploying to US region..."
- deploy-to-us.sh --db-password $US_DATABASE_PASSWORD
이 예시에서:
aud: 오디언스로, 페더레이션 자격 증명을 생성할 때 사용한 오디언스와 일치해야 합니다.secret_id: AWS Secrets Manager에서 시크릿의 이름 또는 ARN. 다른 계정에서 시크릿을 검색하려면 ARN을 사용해야 합니다.field: 검색할 JSON 시크릿의 특정 키. 지정하지 않으면 전체 시크릿이 검색됩니다. 필드 접근은 플랫 JSON 시크릿(최상위 키만)에서만 지원되며 문자열, 숫자, 불리언 값을 지원합니다. 예를 들어:password:password필드에 접근합니다.api_key:api_key필드에 접근합니다.token: 인증에 사용할 ID 토큰을 지정합니다. 지정하지 않으면 러너는AWS_ID_TOKEN이라는 토큰을 찾습니다.
version_id: 시크릿의 특정 버전의 고유 식별자.version_id또는version_stage중 어느 것도 지정하지 않으면 AWS Secrets Manager는AWSCURRENT버전을 반환합니다.version_stage: 검색할 시크릿 버전의 스테이징 레이블(예:AWSCURRENT또는AWSPENDING). 동일한 시크릿에version_id와version_stage를 모두 지정할 수 없습니다.region: 이 특정 시크릿에 대해 글로벌AWS_REGION을 재정의합니다.role_arn: 이 특정 시크릿에 대해 글로벌AWS_ROLE_ARN을 재정의합니다.role_session_name: 이 특정 시크릿에 대해 글로벌AWS_ROLE_SESSION_NAME을 재정의합니다.- GitLab은 AWS Secrets Manager에서 시크릿을 가져와 임시 파일에 값을 저장합니다. 이 파일 경로는 파일 유형 CI/CD 변수와 유사하게 CI/CD 변수에 저장됩니다.
문제 해결#
AWS에서 OIDC 설정 시 일반적인 문제는 AWS용 OIDC 문제 해결을 참조하세요.
오류: no EC2 IMDS role found#
다음 두 조건이 모두 충족될 때 이 오류가 발생할 수 있습니다:
- CI/CD 작업이 IAM 역할 인증을 사용하도록 구성되어 있습니다.
- 작업이 AWS EKS에서 호스팅된 Kubernetes executor가 있는 러너에 의해 실행됩니다.
Resolving secrets
Resolving secret "MY_AWS_SECRET"...
Using "aws_secrets_manager" secret resolver...
ERROR: Job failed (system failure): resolving secrets: operation error Secrets Manager: GetSecretValue, get identity: get credentials: failed to refresh cached credentials, no EC2 IMDS role found, operation error ec2imds: GetMetadata, canceled, context deadline exceeded
Resolving secrets 단계는 러너 관리자가 처리합니다. 이 단계는 EC2 IMDS에 캐시된 IAM 자격 증명에 접근합니다.
IAM 역할이 러너 관리자에 적용되지 않은 경우 Resolving secrets 단계가 실패합니다.
이 오류를 해결하려면 러너 관리자에 올바른 IAM 역할을 적용합니다.
러너 관리자에 의해 생성 및 관리되는 러너 파드에 IAM 역할을 적용하는 것은 이 문제를 해결하지 못합니다.
