환경 구성

경우에 따라 함수에 서드 파티 API 키 또는 조정 가능한 설정과 같은 추가 구성이 필요할 수 있습니다. Cloud Functions용 Firebase SDK는 이러한 프로젝트 관련 데이터 유형을 간편하게 저장하고 검색할 수 있도록 두 가지 환경 구성 방식을 제공합니다.

  • 매개변수화된 구성. 이는 배포 시 검증되는 매개변수로 강력한 유형의 환경 구성을 제공하여 오류를 방지하고 디버깅을 간소화합니다.
  • 환경 변수. 이 방식에서는 환경 변수를 로드할 dotenv 파일을 수동으로 만듭니다.

대부분의 사용 사례에서는 매개변수화된 구성을 사용하는 것이 좋습니다. 이 방식을 사용하면 런타임 시와 배포 시 구성 값을 사용할 수 있으며 모든 매개변수에 유효한 값이 없으면 배포가 차단됩니다. 반대로 배포 시에는 환경 변수 구성을 사용할 수 없습니다.

매개변수화된 구성

Firebase용 Cloud Functions는 코드베이스 내에서 구성 매개변수를 선언적으로 정의하는 인터페이스를 제공합니다. 이러한 매개변수 값은 함수 배포 중에, 배포 및 런타임 옵션을 설정할 때, 실행 중에 모두 사용 가능합니다. 즉, 모든 매개변수에 유효한 값이 없으면 CLI에서 배포를 차단합니다.

코드에서 매개변수를 정의하려면 다음 모델을 따르세요.

const { onRequest } = require('firebase-functions/v2/https');
const { defineInt, defineString } = require('firebase-functions/params');

// Define some parameters
const minInstancesConfig = defineInt('HELLO_WORLD_MININSTANCES');
const welcomeMessage = defineString('WELCOME_MESSAGE');

// To use configured parameters inside the config for a function, provide them
// directly. To use them at runtime, call .value() on them.
export const helloworld = onRequest(
  { minInstances: minInstancesConfig },
 (req, res) => {
    res.send(`${welcomeMessage.value()}! I am a function.`);
  }
);

매개변수화된 구성 변수가 있는 함수를 배포할 때 Firebase CLI는 먼저 로컬 .env 파일에서 값을 로드하려고 시도합니다. 이러한 파일에 값이 없고 default가 설정되어 있지 않으면 CLI는 배포 중에 값을 묻는 메시지를 표시한 후 값을 functions/ 디렉터리의 .env.<project_ID>라는 .env 파일에 자동으로 저장합니다.

$ firebase deploy
i  functions: preparing codebase default for deployment
? Enter a string value for ENVIRONMENT: prod
i  functions: Writing new parameter values to disk: .env.projectId
…
$ firebase deploy
i  functions: Loaded environment variables from .env.projectId

개발 워크플로에 따라 생성된 .env.<project_ID> 파일을 버전 제어에 추가하는 것이 유용할 수 있습니다.

CLI 동작 구성

CLI에 값을 묻는 메시지가 표시되는 방식을 제어하는 Options 객체를 사용하여 매개변수를 구성할 수 있습니다. 다음 예시에서는 전화번호 형식의 유효성을 검사하고 간단한 선택 옵션을 제공하며 Firebase 프로젝트에서 자동으로 선택 옵션을 채우는 옵션을 설정합니다.

const { defineString } = require('firebase-functions/params');

const welcomeMessage = defineString('WELCOME_MESSAGE', {default: 'Hello World',
description: 'The greeting that is returned to the caller of this function'});

const onlyPhoneNumbers = defineString('PHONE_NUMBER', {input: {text:
{validationRegex: /\d{3}-\d{3}-\d{4}/, validationErrorMessage: "Please enter
a phone number in the format XXX-YYY-ZZZZ"}}});

const selectedOption = defineString('PARITY', {input: {select: {options:
[{value: "odd"}, {value: "even"}]}}})

const storageBucket = defineString('BUCKET', {input: {resource: {type:
"storage.googleapis.com/Bucket"}}, description: "This will automatically
populate the selector field with the deploying Cloud Project’s
storage buckets"})

매개변수 유형

매개변수화된 구성은 매개변수 값에 대한 강력한 입력을 제공하며 Cloud Secret Manager의 보안 비밀도 지원합니다. 지원되는 유형은 다음과 같습니다.

  • 보안 비밀
  • 문자열
  • 불리언
  • 정수
  • 부동 소수점

매개변수 값 및 표현식

Firebase는 배포 시와 함수가 실행되는 동안 매개변수를 평가합니다. 이러한 이중 환경으로 인해 매개변수 값을 비교할 때, 매개변수 값을 사용하여 함수의 런타임 옵션을 설정할 때 특별히 주의해야 합니다.

런타임 옵션으로 매개변수를 함수에 전달하려면 직접 전달합니다.

const { onRequest } = require('firebase-functions/v2/https');
const { defineInt } = require('firebase-functions/params');
const minInstancesConfig = defineInt('HELLO\_WORLD\_MININSTANCES');

export const helloworld = onRequest(
  { minInstances: minInstancesConfig },
  (req, res) => {
    //…

또한 어떤 옵션을 선택해야 할지 알아보기 위해 매개변수와 비교해야 하는 경우 값을 확인하는 대신 기본 제공 비교 연산자를 사용해야 합니다.

const { onRequest } = require('firebase-functions/v2/https');
const { defineBool } = require('firebase-functions/params');
const environment = params.defineString(‘ENVIRONMENT’, {default: ‘dev’});

// use built-in comparators
const minInstancesConfig = environment.equals('PRODUCTION').thenElse(10, 1);
export const helloworld = onRequest(
  { minInstances: minInstancesConfig },
  (req, res) => {
    //…

value 함수를 사용하여 런타임 시에만 사용되는 매개변수와 매개변수 표현식에 액세스할 수 있습니다.

const { onRequest } = require('firebase-functions/v2/https');
const { defineString } = require('firebase-functions/params');
const welcomeMessage = defineString('WELCOME_MESSAGE');

// To use configured parameters inside the config for a function, provide them
// directly. To use them at runtime, call .value() on them.
export const helloworld = onRequest(
 (req, res) => {
    res.send(`${welcomeMessage.value()}! I am a function.`);
  }
);

기본 제공 매개변수

Cloud Functions SDK는 firebase-functions/params 하위 패키지에서 사용할 수 있는 사전 정의된 매개변수 3개를 제공합니다.

  • projectId: 함수가 실행 중인 Cloud 프로젝트입니다.
  • databaseUrl: 함수와 연결된 실시간 데이터베이스 인스턴스의 URL입니다(Firebase 프로젝트에서 사용 설정된 경우).
  • storageBucket: 함수와 연결된 Cloud Storage 버킷입니다(Firebase 프로젝트에서 사용 설정된 경우).

이러한 기능은 모든 측면에서 사용자 정의 문자열 매개변수와 비슷하지만 항상 값이 Firebase CLI에 전달되므로 배포 시 이러한 값을 묻는 메시지가 표시되지 않거나 값이 .env 파일에 저장되지 않습니다.

보안 비밀 매개변수

defineSecret()을 사용하여 정의된 Secret 유형의 매개변수는 Cloud Secret Manager에 값이 저장된 문자열 매개변수를 나타냅니다. 보안 비밀 매개변수는 로컬 .env 파일을 확인하고 누락된 경우 파일에 새 값을 작성하는 대신 Cloud Secret Manager의 존재 여부를 확인하고 배포 중에 새 보안 비밀 값을 묻는 메시지를 대화형으로 표시합니다.

이 방법으로 정의된 보안 비밀 매개변수는 액세스 권한이 있어야 하는 개별 함수에 바인딩되어야 합니다.

const { onRequest } = require("functions/v2/https");
const { defineSecret } = require('firebase-functions/params');
const discordApiKey = defineSecret('DISCORD_API_KEY');

export const posttodiscord = onRequest(
  { secrets: [discordApiKey] },
  (req, res) => {
    const apiKey = discordApiKey.value();
    //…

보안 비밀 값은 함수가 실행될 때까지 표시되지 않으므로 함수를 구성하는 동안에는 이 값을 사용할 수 없습니다.

환경 변수

Firebase용 Cloud Functions는 .env 파일에 지정된 환경 변수를 애플리케이션 런타임에 로드하는 데 사용되는 dotenv 파일 형식을 지원합니다. 배포된 후에는 process.env 인터페이스를 통해 환경 변수를 읽을 수 있습니다.

이 방법으로 환경을 구성하려면 프로젝트에 .env 파일을 만들고 원하는 변수를 추가한 후에 배포합니다.

  1. functions/ 디렉터리에 .env 파일을 만듭니다.

    # Directory layout:
    #   my-project/
    #     firebase.json
    #     functions/
    #       .env
    #       package.json
    #       index.js
    
  2. 수정할 .env 파일을 열고 원하는 키를 추가합니다. 예를 들면 다음과 같습니다.

    PLANET=Earth
    AUDIENCE=Humans
    
  3. 함수를 배포하고 환경 변수가 로드되었는지 확인합니다.

    firebase deploy --only functions
    # ...
    # i functions: Loaded environment variables from .env.
    # ...
    

커스텀 환경 변수가 배포되고 나면 함수 코드에서 process.env 구문을 통해 해당 변수에 액세스할 수 있습니다.

// Responds with "Hello Earth and Humans"
exports.hello = onRequest((request, response) => {
  response.send(`Hello ${process.env.PLANET} and ${process.env.AUDIENCE}`);
});

여러 환경 변수 세트 배포

Firebase 프로젝트에 사용할 대체 환경 변수 집합(예: 스테이징과 프로덕션)이 필요한 경우 .env.<project or alias> 파일을 만들고 여기에 프로젝트별 환경 변수를 작성합니다. .env의 환경 변수와 프로젝트별 .env 파일(있는 경우)이 배포된 모든 함수에 포함됩니다.

예를 들어 프로젝트에는 개발 및 프로덕션 환경에서 약간 다른 값을 포함하는 다음 세 개의 파일이 포함될 수 있습니다.

.env .env.dev .env.prod
PLANET=Earth

AUDIENCE=Humans

AUDIENCE=Dev Humans AUDIENCE=Prod Humans

이러한 개별 파일의 값이 주어지면 함수를 통해 배포되는 환경 변수 집합이 대상 프로젝트에 따라 달라집니다.

$ firebase use dev
$ firebase deploy --only functions
i functions: Loaded environment variables from .env, .env.dev.
# Deploys functions with following user-defined environment variables:
#   PLANET=Earth
#   AUDIENCE=Dev Humans

$ firebase use prod
$ firebase deploy --only functions
i functions: Loaded environment variables from .env, .env.prod.
# Deploys functions with following user-defined environment variables:
#   PLANET=Earth
#   AUDIENCE=Prod Humans

예약된 환경 변수

일부 환경 변수 키는 내부에서 사용하도록 예약되어 있습니다. .env 파일에는 다음 키를 사용하지 마세요.

  • X_GOOGLE_로 시작하는 모든 키
  • EXT_로 시작하는 모든 키
  • FIREBASE_로 시작하는 모든 키
  • 다음 목록의 키:
  • CLOUD_RUNTIME_CONFIG
  • ENTRY_POINT
  • GCP_PROJECT
  • GCLOUD_PROJECT
  • GOOGLE_CLOUD_PROJECT
  • FUNCTION_TRIGGER_TYPE
  • FUNCTION_NAME
  • FUNCTION_MEMORY_MB
  • FUNCTION_TIMEOUT_SEC
  • FUNCTION_IDENTITY
  • FUNCTION_REGION
  • FUNCTION_TARGET
  • FUNCTION_SIGNATURE_TYPE
  • K_SERVICE
  • K_REVISION
  • PORT
  • K_CONFIGURATION

민감한 구성 정보 저장 및 액세스

.env 파일에 저장된 환경 변수는 함수 구성에 사용할 수 있지만 데이터베이스 사용자 인증 정보 또는 API 키와 같은 민감한 정보를 저장하는 안전한 방법으로 간주해서는 안 됩니다. 이는 소스 제어에서 .env 파일을 확인하는 경우에 특히 중요합니다.

민감한 구성 정보를 저장할 수 있도록 Firebase용 Cloud Functions는 Google Cloud Secret Manager와 통합됩니다. 이 암호화된 서비스를 사용하면 구성 값을 안전하게 저장하는 동시에 필요할 때 함수에서 쉽게 액세스할 수 있습니다.

보안 비밀 생성 및 사용

보안 비밀을 생성하려면 Firebase CLI를 사용합니다.

보안 비밀 생성 및 사용 방법:

  1. 로컬 프로젝트 디렉터리의 루트에서 다음 명령어를 실행합니다.

    firebase functions:secrets:set SECRET_NAME

  2. SECRET_NAME의 값을 입력합니다.

    CLI는 성공 메시지를 표시하고 변경사항을 적용하려면 함수를 배포해야 한다고 경고합니다.

  3. 배포하기 전에 함수 코드에서 함수에 runWith 매개변수를 사용하여 보안 비밀에 액세스할 수 있는지 확인하세요.

    const { onRequest } = require("functions/v2/https");
    
      exports.processpayment = onRequest(
        { secrets: ["SECRET_NAME"] },
        (data, context) => {
          const myBillingService = initializeBillingService(
            // reference the secret value
            process.env.SECRET_NAME
          );
          // Process the payment
        }
      );
  4. Cloud Functions 배포:

    firebase deploy --only functions

이제 다른 환경 변수처럼 보안 비밀에 액세스할 수 있게 됩니다. 반대로 runWith에 보안 비밀을 지정하지 않은 다른 함수가 보안 비밀에 액세스하려고 하면 정의되지 않은 값이 수신됩니다.

exports.anotherendpoint = onRequest((request, response) => {
  response.send(`The secret API key is ${process.env.SECRET_NAME}`);
  // responds with "The secret API key is undefined" because the `runWith` parameter is missing
});

함수가 배포되면 보안 비밀 값에 액세스할 수 있게 됩니다. runWith 매개변수에 보안 비밀을 명확하게 포함하는 함수만 이 보안 비밀을 환경 변수로 액세스할 수 있습니다. 이렇게 하면 필요한 경우에만 보안 비밀 값이 제공되도록 할 수 있으므로 보안 비밀이 실수로 유출될 위험을 줄일 수 있습니다.

보안 비밀 관리

Firebase CLI를 사용하여 보안 비밀을 관리합니다. 이러한 방식으로 보안 비밀을 관리할 때는 CLI가 변경될 경우 관련 함수를 수정하거나 다시 배포해야 한다는 점에 유의하세요. 구체적으로는 다음과 같습니다.

  • 보안 비밀에 새 값을 설정할 때마다 해당 보안 비밀을 참조하는 모든 함수가 최신 값을 선택하도록 다시 배포해야 합니다.
  • 보안 비밀을 삭제하는 경우 배포된 함수 중에 해당 보안 비밀을 참조하는 함수가 없는지 확인해야 합니다. 삭제된 보안 비밀 값을 사용하는 함수는 자동으로 실패합니다.

보안 비밀 관리를 위한 Firebase CLI 명령어 요약은 다음과 같습니다.

# Change the value of an existing secret
firebase functions:secrets:set SECRET_NAME

# View the value of a secret
functions:secrets:access SECRET_NAME

# Destroy a secret
functions:secrets:destroy SECRET_NAME

# View all secret versions and their state
functions:secrets:get SECRET_NAME

# Automatically clean up all secrets that aren't referenced by any of your functions
functions:secrets:prune

accessdestroy 명령어의 경우 특정 버전을 관리하는 선택적 버전 매개변수를 제공할 수 있습니다. 예를 들면 다음과 같습니다.

functions:secrets:access SECRET_NAME[@VERSION]

이러한 작업에 대한 자세한 내용을 보려면 명령어에 -h를 전달하여 CLI 도움말을 확인하세요.

보안 비밀 청구 방식

Secret Manager는 무료로 6개의 활성 보안 비밀 버전을 허용합니다. 따라서 Firebase 프로젝트에 매월 6개의 보안 비밀을 무료로 사용할 수 있습니다.

기본적으로 Firebase CLI는 필요한 경우(예: 새 보안 비밀 버전으로 함수를 배포하는 경우) 사용하지 않는 보안 비밀 버전을 자동으로 폐기합니다. 또한 functions:secrets:destroyfunctions:secrets:prune 명령어로 사용하지 않는 보안 비밀을 적극적으로 정리할 수 있습니다.

Secret Manager는 보안 비밀에 대해 월간 10,000회의 미청구 액세스 작업을 허용합니다. 함수 인스턴스는 콜드 스타트가 발생할 때마다 runWith 매개변수에 지정된 보안 비밀만 읽습니다. 상당수의 함수 인스턴스에서 많은 보안 비밀을 읽는 경우 프로젝트가 이 허용량을 초과할 수 있으며 이 경우 액세스 작업 10,000회당 $0.03가 청구됩니다.

자세한 내용은 Secret Manager 가격 책정을 참조하세요.

에뮬레이터 지원

dotenv를 사용하는 환경 구성은 로컬 Cloud Functions 에뮬레이터와 상호 운용되도록 설계되었습니다.

로컬 Cloud Functions 에뮬레이터를 사용하는 경우 .env.local 파일을 설정하여 프로젝트의 환경 변수를 재정의할 수 있습니다. .env.local의 콘텐츠는 .env 및 프로젝트별 .env 파일보다 우선 적용됩니다.

예를 들어 프로젝트에 개발 및 로컬 테스트용으로 약간 다른 값이 포함된 다음 세 개의 파일이 포함될 수 있습니다.

.env .env.dev .env.local
PLANET=Earth

AUDIENCE=Humans

AUDIENCE=Dev Humans AUDIENCE=Local Humans

로컬 컨텍스트에서 시작할 때 에뮬레이터는 다음에 표시된 환경 변수를 로드합니다.

  $ firebase emulators:start
  i  emulators: Starting emulators: functions
  # Starts emulator with following environment variables:
  #  PLANET=Earth
  #  AUDIENCE=Local Humans

Cloud Functions 에뮬레이터의 보안 비밀 및 사용자 인증 정보

Cloud Functions 에뮬레이터는 민감한 구성 정보를 저장하고 이러한 정보에 액세스하기 위해 보안 비밀을 사용하는 것을 지원합니다. 기본적으로 에뮬레이터는 애플리케이션 기본 사용자 인증 정보를 사용하여 프로덕션 보안 비밀에 액세스하려고 시도합니다. CI 환경과 같은 특정 상황에서는 권한 제한으로 인해 에뮬레이터가 보안 비밀 값에 액세스하지 못할 수 있습니다.

환경 변수에 대한 Cloud Functions 에뮬레이터 지원과 마찬가지로 .secret.local 파일을 설정하여 보안 비밀 값을 재정의할 수 있습니다. 이렇게 하면 특히 보안 비밀 값에 액세스할 수 없는 경우에도 로컬에서 함수를 쉽게 테스트할 수 있습니다.