워크플로 실행

워크플로를 실행하면 워크플로와 연결된 현재 워크플로 정의가 실행됩니다.

워크플로 실행 요청에서 런타임 인수를 전달하고 워크플로 변수를 사용하여 이러한 인수에 액세스할 수 있습니다. 자세한 내용은 실행 요청에서 런타임 인수 전달을 참조하세요.

워크플로 실행이 완료되면 기록 및 결과가 제한된 기간 동안 보관됩니다. 자세한 내용은 할당량 및 한도를 참조하세요.

시작하기 전에

조직에서 정의한 보안 제약조건으로 인해 다음 단계를 완료하지 못할 수 있습니다. 문제 해결 정보는 제한된 Google Cloud 환경에서 애플리케이션 개발을 참조하세요.

  1. Google Cloud 계정에 로그인합니다. Google Cloud를 처음 사용하는 경우 계정을 만들고 Google 제품의 실제 성능을 평가해 보세요. 신규 고객에게는 워크로드를 실행, 테스트, 배포하는 데 사용할 수 있는 $300의 무료 크레딧이 제공됩니다.
  2. Google Cloud Console의 프로젝트 선택기 페이지에서 Google Cloud 프로젝트를 선택하거나 만듭니다.

    프로젝트 선택기로 이동

  3. Google Cloud 프로젝트에 결제가 사용 설정되어 있는지 확인합니다.

  4. Google Cloud Console의 프로젝트 선택기 페이지에서 Google Cloud 프로젝트를 선택하거나 만듭니다.

    프로젝트 선택기로 이동

  5. Google Cloud 프로젝트에 결제가 사용 설정되어 있는지 확인합니다.

  6. 워크플로가 다른 Google Cloud 리소스에 액세스하는 경우 올바른 권한이 있는 서비스 계정과 연결되어 있는지 확인합니다. 기존 워크플로와 연결된 서비스 계정에 대해 알아보려면 워크플로의 연결된 서비스 계정 확인을 참조하세요.

    리소스를 만들고 서비스 계정을 연결하려면 리소스를 만들 수 있는 권한과 리소스에 연결할 서비스 계정을 가장할 수 있는 권한이 필요합니다. 자세한 내용은 서비스 계정 권한을 참조하세요.

  7. Google Cloud 콘솔 또는 Google Cloud CLI를 사용하여 워크플로를 배포합니다.

워크플로 실행

클라이언트 라이브러리를 사용하거나 Google Cloud 콘솔에서 gcloud CLI를 사용하거나 Workflows REST API로 요청을 전송하여 워크플로를 실행할 수 있습니다.

콘솔

  1. 워크플로를 실행하려면 Google Cloud 콘솔에서 Workflows 페이지로 이동합니다.

    Workflows로 이동

  2. Workflows 페이지에서 워크플로를 선택하여 세부정보 페이지로 이동합니다.

  3. 워크플로 세부정보 페이지에서 실행을 클릭합니다.

  4. 워크플로 실행 페이지의 입력 창에서 실행 전에 워크플로에 전달할 선택적 런타임 인수를 입력할 수 있습니다. 인수는 JSON 형식이어야 합니다(예: {"animal":"cat"}). 워크플로에 런타임 인수가 사용되지 않으면 비워 둡니다.

  5. 필요한 경우 워크플로 실행에 적용할 호출 로깅 수준을 지정하세요. 호출 로그 수준 목록에서 다음 중 하나를 선택합니다.

    • 미지정: 로깅 수준이 지정되지 않았습니다. 이 항목이 기본값입니다. 실행 로그 수준이 지정되지 않은(기본값) 한 실행 로그 수준이 워크플로 로그 수준보다 우선합니다. 이 경우 워크플로 로그 수준이 적용됩니다.
    • 오류만: 포착된 모든 예외 또는 예외로 인해 호출이 중지된 경우를 로깅합니다.
    • 모든 호출: 하위 워크플로 또는 라이브러리 함수에 대한 모든 호출과 결과를 로깅합니다.
    • 로그 없음: 호출 로깅이 없습니다.

  6. 실행을 클릭합니다.

  7. 실행 세부정보 페이지에서 모든 출력, 실행 ID 및 상태, 워크플로 실행의 현재 또는 최종 단계를 포함한 실행 결과를 볼 수 있습니다. 자세한 내용은 워크플로 실행 결과 액세스를 참조하세요.

gcloud

  1. 터미널을 엽니다.

  2. 실행하려는 워크플로의 이름을 찾습니다. 워크플로 이름을 모르면 다음 명령어를 입력하여 모든 워크플로를 나열할 수 있습니다.

    gcloud workflows list
    
  3. 워크플로는 다음 두 가지 방법으로 실행할 수 있습니다.

    • 워크플로를 실행하고 실행이 완료될 때까지 기다립니다.

      gcloud workflows run WORKFLOW_NAME \
      --call-log-level=CALL_LOGGING_LEVEL \
      --data=DATA
      
    • 실행 시도가 완료될 때까지 기다리지 않고 워크플로를 실행합니다.

      gcloud workflows execute WORKFLOW_NAME \
      --call-log-level=CALL_LOGGING_LEVEL \
      --data=DATA
      

      다음을 바꿉니다.

      • WORKFLOW_NAME: 워크플로의 이름입니다.
      • CALL_LOGGING_LEVEL(선택사항): 실행 중에 적용할 호출 로깅 수준입니다. 다음 중 하나일 수 있습니다.

        • none: 지정된 로깅 수준이 없습니다. 이 항목이 기본값입니다. 실행 로그 수준이 지정되지 않은(기본값) 한 실행 로그 수준이 워크플로 로그 수준보다 우선합니다. 이 경우 워크플로 로그 수준이 적용됩니다.
        • log-errors-only: 포착된 모든 예외 또는 예외로 인해 호출이 중지된 경우를 로깅합니다.
        • log-all-calls: 하위 워크플로 또는 라이브러리 함수와 해당 결과에 대한 모든 호출을 로깅합니다.
        • log-none: 호출 로깅이 없습니다.
      • DATA(선택사항): JSON 형식의 워크플로 런타임 인수입니다.

  4. gcloud workflows execute를 실행한 경우 워크플로 실행 시도의 고유 ID가 반환되며 출력은 다음과 비슷합니다.

     To view the workflow status, you can use following command:
     gcloud workflows executions describe b113b589-8eff-4968-b830-8d35696f0b33 --workflow workflow-2 --location us-central1

    실행 상태를 보려면 이전 단계에서 반환된 명령어를 입력합니다.

실행 시도가 성공하면 출력은 워크플로의 성공을 나타내는 state와 실행의 최종 워크플로 단계를 지정하는 status를 포함해 다음과 비슷합니다.

argument: '{"searchTerm":"Friday"}'
endTime: '2022-06-22T12:17:53.086073678Z'
name: projects/1051295516635/locations/us-central1/workflows/myFirstWorkflow/executions/c4dffd1f-13db-46a0-8a4a-ee39c144cb96
result: '["Friday","Friday the 13th (franchise)","Friday Night Lights (TV series)","Friday
    the 13th (1980 film)","Friday the 13th","Friday the 13th (2009 film)","Friday the
    13th Part III","Friday the 13th Part 2","Friday (Rebecca Black song)","Friday Night
    Lights (film)"]'
startTime: '2022-06-22T12:17:52.799387653Z'
state: SUCCEEDED
status:
    currentSteps:
    - routine: main
        step: returnOutput
workflowRevisionId: 000001-ac2

클라이언트 라이브러리

다음 샘플에서는 myFirstWorkflow 워크플로를 이미 배포했다고 가정합니다.

  1. 클라이언트 라이브러리를 설치하고 개발 환경을 설정합니다. 자세한 내용은 Workflows 클라이언트 라이브러리 개요를 참조하세요.

  2. 샘플 앱 저장소를 로컬 머신에 클론합니다.

    Java

    git clone https://github.com/GoogleCloudPlatform/java-docs-samples.git

    또는 zip 파일로 샘플을 다운로드하고 압축을 풀 수 있습니다.

    Node.js

    git clone https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git

    또는 zip 파일로 샘플을 다운로드하고 압축을 풀 수 있습니다.

    Python

    git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git

    또는 zip 파일로 샘플을 다운로드하고 압축을 풀 수 있습니다.

  3. Workflows 샘플 코드가 포함된 디렉터리로 변경합니다.

    Java

    cd java-docs-samples/workflows/cloud-client/

    Node.js

    cd nodejs-docs-samples/workflows/quickstart/

    Python

    cd python-docs-samples/workflows/cloud-client/

  4. 다음 샘플 코드를 살펴봅니다.

    Java

    // Imports the Google Cloud client library
    
    import com.google.cloud.workflows.executions.v1.CreateExecutionRequest;
    import com.google.cloud.workflows.executions.v1.Execution;
    import com.google.cloud.workflows.executions.v1.ExecutionsClient;
    import com.google.cloud.workflows.executions.v1.WorkflowName;
    import java.io.IOException;
    import java.util.concurrent.ExecutionException;
    
    public class WorkflowsQuickstart {
    
      private static final String PROJECT = System.getenv("GOOGLE_CLOUD_PROJECT");
      private static final String LOCATION = System.getenv().getOrDefault("LOCATION", "us-central1");
      private static final String WORKFLOW =
          System.getenv().getOrDefault("WORKFLOW", "myFirstWorkflow");
    
      public static void main(String... args)
          throws IOException, InterruptedException, ExecutionException {
        if (PROJECT == null) {
          throw new IllegalArgumentException(
              "Environment variable 'GOOGLE_CLOUD_PROJECT' is required to run this quickstart.");
        }
        workflowsQuickstart(PROJECT, LOCATION, WORKFLOW);
      }
    
      private static volatile boolean finished;
    
      public static void workflowsQuickstart(String projectId, String location, String workflow)
          throws IOException, InterruptedException, ExecutionException {
        // Initialize client that will be used to send requests. This client only needs
        // to be created once, and can be reused for multiple requests. After completing all of your
        // requests, call the "close" method on the client to safely clean up any remaining background
        // resources.
        try (ExecutionsClient executionsClient = ExecutionsClient.create()) {
          // Construct the fully qualified location path.
          WorkflowName parent = WorkflowName.of(projectId, location, workflow);
    
          // Creates the execution object.
          CreateExecutionRequest request =
              CreateExecutionRequest.newBuilder()
                  .setParent(parent.toString())
                  .setExecution(Execution.newBuilder().build())
                  .build();
          Execution response = executionsClient.createExecution(request);
    
          String executionName = response.getName();
          System.out.printf("Created execution: %s%n", executionName);
    
          long backoffTime = 0;
          long backoffDelay = 1_000; // Start wait with delay of 1,000 ms
          final long backoffTimeout = 10 * 60 * 1_000; // Time out at 10 minutes
          System.out.println("Poll for results...");
    
          // Wait for execution to finish, then print results.
          while (!finished && backoffTime < backoffTimeout) {
            Execution execution = executionsClient.getExecution(executionName);
            finished = execution.getState() != Execution.State.ACTIVE;
    
            // If we haven't seen the results yet, wait.
            if (!finished) {
              System.out.println("- Waiting for results");
              Thread.sleep(backoffDelay);
              backoffTime += backoffDelay;
              backoffDelay *= 2; // Double the delay to provide exponential backoff.
            } else {
              System.out.println("Execution finished with state: " + execution.getState().name());
              System.out.println("Execution results: " + execution.getResult());
            }
          }
        }
      }
    }

    Node.js(자바스크립트)

    const {ExecutionsClient} = require('@google-cloud/workflows');
    const client = new ExecutionsClient();
    /**
     * TODO(developer): Uncomment these variables before running the sample.
     */
    // const projectId = 'my-project';
    // const location = 'us-central1';
    // const workflow = 'myFirstWorkflow';
    // const searchTerm = '';
    
    /**
     * Executes a Workflow and waits for the results with exponential backoff.
     * @param {string} projectId The Google Cloud Project containing the workflow
     * @param {string} location The workflow location
     * @param {string} workflow The workflow name
     * @param {string} searchTerm Optional search term to pass to the Workflow as a runtime argument
     */
    async function executeWorkflow(projectId, location, workflow, searchTerm) {
      /**
       * Sleeps the process N number of milliseconds.
       * @param {Number} ms The number of milliseconds to sleep.
       */
      function sleep(ms) {
        return new Promise(resolve => {
          setTimeout(resolve, ms);
        });
      }
      const runtimeArgs = searchTerm ? {searchTerm: searchTerm} : {};
      // Execute workflow
      try {
        const createExecutionRes = await client.createExecution({
          parent: client.workflowPath(projectId, location, workflow),
          execution: {
            // Runtime arguments can be passed as a JSON string
            argument: JSON.stringify(runtimeArgs),
          },
        });
        const executionName = createExecutionRes[0].name;
        console.log(`Created execution: ${executionName}`);
    
        // Wait for execution to finish, then print results.
        let executionFinished = false;
        let backoffDelay = 1000; // Start wait with delay of 1,000 ms
        console.log('Poll every second for result...');
        while (!executionFinished) {
          const [execution] = await client.getExecution({
            name: executionName,
          });
          executionFinished = execution.state !== 'ACTIVE';
    
          // If we haven't seen the result yet, wait a second.
          if (!executionFinished) {
            console.log('- Waiting for results...');
            await sleep(backoffDelay);
            backoffDelay *= 2; // Double the delay to provide exponential backoff.
          } else {
            console.log(`Execution finished with state: ${execution.state}`);
            console.log(execution.result);
            return execution.result;
          }
        }
      } catch (e) {
        console.error(`Error executing workflow: ${e}`);
      }
    }
    
    executeWorkflow(projectId, location, workflowName, searchTerm).catch(err => {
      console.error(err.message);
      process.exitCode = 1;
    });
    

    Node.js(TypeScript)

    import {ExecutionsClient} from '@google-cloud/workflows';
    const client: ExecutionsClient = new ExecutionsClient();
    /**
     * TODO(developer): Uncomment these variables before running the sample.
     */
    // const projectId = 'my-project';
    // const location = 'us-central1';
    // const workflow = 'myFirstWorkflow';
    // const searchTerm = '';
    
    /**
     * Executes a Workflow and waits for the results with exponential backoff.
     * @param {string} projectId The Google Cloud Project containing the workflow
     * @param {string} location The workflow location
     * @param {string} workflow The workflow name
     * @param {string} searchTerm Optional search term to pass to the Workflow as a runtime argument
     */
    async function executeWorkflow(
      projectId: string,
      location: string,
      workflow: string,
      searchTerm: string
    ) {
      /**
       * Sleeps the process N number of milliseconds.
       * @param {Number} ms The number of milliseconds to sleep.
       */
      function sleep(ms: number): Promise<unknown> {
        return new Promise(resolve => {
          setTimeout(resolve, ms);
        });
      }
      const runtimeArgs = searchTerm ? {searchTerm: searchTerm} : {};
      // Execute workflow
      try {
        const createExecutionRes = await client.createExecution({
          parent: client.workflowPath(projectId, location, workflow),
          execution: {
            // Runtime arguments can be passed as a JSON string
            argument: JSON.stringify(runtimeArgs),
          },
        });
        const executionName = createExecutionRes[0].name;
        console.log(`Created execution: ${executionName}`);
    
        // Wait for execution to finish, then print results.
        let executionFinished = false;
        let backoffDelay = 1000; // Start wait with delay of 1,000 ms
        console.log('Poll every second for result...');
        while (!executionFinished) {
          const [execution] = await client.getExecution({
            name: executionName,
          });
          executionFinished = execution.state !== 'ACTIVE';
    
          // If we haven't seen the result yet, wait a second.
          if (!executionFinished) {
            console.log('- Waiting for results...');
            await sleep(backoffDelay);
            backoffDelay *= 2; // Double the delay to provide exponential backoff.
          } else {
            console.log(`Execution finished with state: ${execution.state}`);
            console.log(execution.result);
            return execution.result;
          }
        }
      } catch (e) {
        console.error(`Error executing workflow: ${e}`);
      }
    }
    
    executeWorkflow(projectId, location, workflowName, searchTerm).catch(
      (err: Error) => {
        console.error(err.message);
        process.exitCode = 1;
      }
    );

    Python

    import time
    
    from google.cloud import workflows_v1
    from google.cloud.workflows import executions_v1
    from google.cloud.workflows.executions_v1 import Execution
    from google.cloud.workflows.executions_v1.types import executions
    
    def execute_workflow(
        project: str, location: str = "us-central1", workflow: str = "myFirstWorkflow"
    ) -> Execution:
        """Execute a workflow and print the execution results.
    
        A workflow consists of a series of steps described using the Workflows syntax, and can be written in either YAML or JSON.
    
        Args:
            project: The Google Cloud project id which contains the workflow to execute.
            location: The location for the workflow
            workflow: The ID of the workflow to execute.
    
        Returns:
            The execution response.
        """
        # Set up API clients.
        execution_client = executions_v1.ExecutionsClient()
        workflows_client = workflows_v1.WorkflowsClient()
        # Construct the fully qualified location path.
        parent = workflows_client.workflow_path(project, location, workflow)
    
        # Execute the workflow.
        response = execution_client.create_execution(request={"parent": parent})
        print(f"Created execution: {response.name}")
    
        # Wait for execution to finish, then print results.
        execution_finished = False
        backoff_delay = 1  # Start wait with delay of 1 second
        print("Poll for result...")
        while not execution_finished:
            execution = execution_client.get_execution(request={"name": response.name})
            execution_finished = execution.state != executions.Execution.State.ACTIVE
    
            # If we haven't seen the result yet, wait a second.
            if not execution_finished:
                print("- Waiting for results...")
                time.sleep(backoff_delay)
                # Double the delay to provide exponential backoff.
                backoff_delay *= 2
            else:
                print(f"Execution finished with state: {execution.state.name}")
                print(f"Execution results: {execution.result}")
                return execution
    
    

    이 샘플은 다음을 수행합니다.

    1. Workflows용 클라우드 클라이언트 라이브러리를 설정합니다.
    2. 워크플로를 실행합니다.
    3. 실행이 종료될 때까지 워크플로 실행을 폴링합니다(지수 백오프 사용).
    4. 실행 결과를 출력합니다.
  5. 샘플을 실행하려면 먼저 종속 항목을 설치합니다.

    Java

    mvn compile

    Node.js(자바스크립트)

    npm install

    Node.js(TypeScript)

    npm install && npm run build

    Python

    pip3 install -r requirements.txt

  6. 스크립트를 실행합니다.

    Java

    GOOGLE_CLOUD_PROJECT=PROJECT_ID LOCATION=CLOUD_REGION WORKFLOW=WORKFLOW_NAME mvn compile exec:java -Dexec.mainClass=com.example.workflows.WorkflowsQuickstart

    Node.js(자바스크립트)

    npm start PROJECT_ID CLOUD_REGION WORKFLOW_NAME

    Node.js(TypeScript)

    npm start PROJECT_ID CLOUD_REGION WORKFLOW_NAME

    Python

    GOOGLE_CLOUD_PROJECT=PROJECT_ID LOCATION=CLOUD_REGION WORKFLOW=WORKFLOW_NAME python3 main.py

    다음을 바꿉니다.

    • PROJECT_ID(필수): Google Cloud 프로젝트의 프로젝트 ID
    • CLOUD_REGION: 워크플로의 위치(기본값: us-central1)
    • WORKFLOW_NAME: 워크플로의 ID(기본값: myFirstWorkflow)

    출력은 다음과 비슷합니다.

    Execution finished with state: SUCCEEDED
    ["Sunday","Sunday in the Park with George","Sunday shopping","Sunday Bloody Sunday","Sunday Times Golden Globe Race","Sunday All Stars","Sunday Night (South Korean TV series)","Sunday Silence","Sunday Without God","Sunday Independent (Ireland)"]
    

REST API

지정된 워크플로의 최신 버전을 사용하여 새 실행을 만들려면 projects.locations.workflows.executions.create 메서드를 사용합니다.

인증하려면 워크플로를 실행할 수 있는 충분한 권한이 포함된 서비스 계정이 필요합니다. 예를 들어 계정에 워크플로 실행을 트리거할 수 있는 권한이 있도록 서비스 계정에 Workflows 호출자 역할(roles/workflows.invoker)을 부여할 수 있습니다. 자세한 내용은 Workflows 호출을 참조하세요.

요청 데이터를 사용하기 전에 다음을 바꿉니다.

  • PROJECT_NUMBER: IAM 및 관리자 설정 페이지에 나열된 Google Cloud 프로젝트 번호입니다.
  • LOCATION: 워크플로가 배포되는 리전입니다(예: us-central1).
  • WORKFLOW_NAME: 워크플로의 사용자 정의 이름입니다(예: myFirstWorkflow).
  • PARAMETER: 선택사항. 실행 중인 워크플로에서 실행 요청의 일부로 전달하는 런타임 인수를 수신할 수 있는 경우 값이 하나 이상 있는 이스케이프 처리된 매개변수-값 쌍인 JSON 형식 문자열(예: "{\"searchTerm\":\"asia\"}")을 요청 본문에 추가할 수 있습니다.
  • VALUE: 선택사항. 워크플로에서 런타임 인수로 수신할 수 있는 매개변수-값 쌍의 값입니다.
  • CALL_LOGGING_LEVEL: 선택사항. 실행 중에 적용할 호출 로깅 수준입니다. 기본값은 로깅 수준이 지정되지 않고 대신 워크플로 로그 수준이 적용되는 것입니다. 자세한 내용은 Logging에 로그 전송을 참조하세요. 다음 필드 중 하나는 사용해야 합니다.
    • CALL_LOG_LEVEL_UNSPECIFIED: 로깅 수준이 지정되지 않고 대신 워크플로 로그 수준이 적용됩니다. 이 항목이 기본값입니다. 그렇지 않은 경우 실행 로그 수준이 적용되고 워크플로 로그 수준보다 우선 적용됩니다.
    • LOG_ERRORS_ONLY: 포착된 모든 예외 또는 예외로 인해 호출이 중지된 시기를 로깅합니다.
    • LOG_ALL_CALLS: 하위 워크플로 또는 라이브러리 함수와 해당 결과에 대한 모든 호출을 로깅합니다.
    • LOG_NONE: 호출 로깅이 없습니다.

JSON 요청 본문:

{
  "argument": "{\"PARAMETER\":\"VALUE\"}",
  "callLogLevel": "CALL_LOGGING_LEVEL"
}

요청을 보내려면 다음 옵션 중 하나를 펼칩니다.

성공한 경우 응답 본문에 새로 생성된 Execution 인스턴스가 포함됩니다.

{
  "name": "projects/PROJECT_NUMBER/locations/LOCATION/workflows/WORKFLOW_NAME/executions/EXECUTION_ID",
  "startTime": "2023-11-07T14:35:27.215337069Z",
  "state": "ACTIVE",
  "argument": "{\"PARAMETER\":\"VALUE\"}",
  "workflowRevisionId": "000001-2df",
  "callLogLevel": "CALL_LOGGING_LEVEL",
  "status": {}
}

실행 상태 확인

워크플로 실행 상태를 확인하는 데에는 유용한 몇 가지 명령어가 있습니다.

  • 워크플로의 실행 시도와 해당 ID의 목록을 검색하려면 다음 명령어를 입력합니다.

    gcloud workflows executions list WORKFLOW_NAME
    

    WORKFLOW_NAME을 워크플로 이름으로 바꿉니다.

    이 명령어는 다음과 비슷한 NAME 값을 반환합니다.

    projects/PROJECT_NUMBER/locations/REGION/workflows/WORKFLOW_NAME/executions/EXECUTION_ID

    다음 명령어에 사용할 실행 ID를 복사합니다.

  • 실행 시도 상태를 확인하고 시도가 완료될 때까지 기다리려면 다음 명령어를 입력합니다.

    gcloud workflows executions wait EXECUTION_ID
    

    EXECUTION_ID를 실행 시도의 ID로 바꿉니다.

    이 명령어는 실행 시도가 완료될 때까지 기다린 후 결과를 반환합니다.

  • 마지막 실행이 완료될 때까지 기다린 후 완료된 실행 결과를 반환하려면 다음 명령어를 입력합니다.

    gcloud workflows executions wait-last
    

    동일한 gcloud 세션에서 이전 실행 시도를 수행한 경우 이 명령어는 이전 실행 시도가 완료될 때까지 기다린 후 완료된 실행 결과를 반환합니다. 이전 시도가 없으면 gcloud가 다음 오류를 반환합니다.

    ERROR: (gcloud.workflows.executions.wait-last) [NOT FOUND] There are no cached executions available.
    
  • 마지막 실행 상태를 가져오려면 다음 명령어를 입력합니다.

    gcloud workflows executions describe-last
    

    동일한 gcloud 세션에서 이전 실행 시도를 수행한 경우에는 이 명령어가 실행 중인 상태일지라도 마지막 실행 결과를 반환합니다. 이전 시도가 없으면 gcloud가 다음 오류를 반환합니다.

    ERROR: (gcloud.beta.workflows.executions.describe-last) [NOT FOUND] There are no cached executions available.
    

다음 단계