Start ECS using FunctionGraph and agency

This sample shows how to use functiongraph start to an ECS instance using following credentials retrieved by the agency:

  • $context->getSecurityAccessKey()

  • $context->getSecuritySecretKey()

  • $context->getSecurityToken()

and using the REST API Starting ECS in a Batch.

For complete source code, see samples-doc/functiongraph/ecs on GitHub.

Code

index.php
<?php
require_once __DIR__ . '/../vendor/autoload.php';

use OTC\Signer;
use OTC\Request;

function handler($event, $context)
{
  // get logger from context
  $logger = $context->getLogger();

  $project_id = getenv('RUNTIME_PROJECT_ID');
  $endpoint = $context->getUserData("ECS_ENDPOINT");
  $instance_id = $context->getUserData('ECS_INSTANCE_ID');

  $signer = new Signer();
  // use the temporary security credentials provided by the function context
  $signer->Key = $context->getSecurityAccessKey();
  $signer->Secret = $context->getSecuritySecretKey();
  $signer->SecurityToken = $context->getSecurityToken();

  $logger->info("Starting ECS instance: ". $instance_id);

  // see https://docs.otc.t-systems.com/elastic-cloud-server/api-ref/apis_recommended/batch_operations/starting_ecss_in_a_batch.html#en-us-topic-0020212207
  $url = 'https://' . $endpoint . '/v1/' . $project_id . '/cloudservers/action';

  $body = json_encode([
    'os-start' => [
      'servers' => [['id' => $instance_id]],
    ],
  ]);

  $headers = [
    'Content-Type' => 'application/json;charset=utf8',
  ];

  if ($project_id !== false && $project_id !== '') {
    // To access resources in a sub-project (e.g. eu_de/myproject)
    // by calling APIs, X-Project-Id of "eu_de/myproject" is needed
    $headers['X-Project-Id'] = $project_id;
  }

  $req = new Request('POST', $url, $headers, $body);

  // sign the request
  $curl = $signer->Sign($req);

  curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($curl, CURLOPT_HEADER, true);

  $response = curl_exec($curl);
  $status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
  $header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);

  $response_body = "";

  if ($status == 0) {

    $logger->error("Error: " . curl_error($curl));
    $response_body = curl_error($curl);
    $status = 500;
  } else {
    $response_headers = substr($response, 0, $header_size);
    $response_body = substr($response, $header_size);

    $logger->info("Status Code: " . $status);
    $logger->info("Response Headers: " . $response_headers);
    $logger->info("Response Body: " . $response_body);
    
  }
  curl_close($curl);

  $output = array(
    "statusCode" => $status,
    "headers" => array(
      "Content-Type" => "application/json",
    ),
    "isBase64Encoded" => false,
    "body" => $response_body,
  );
  return $output;
}
?>
composer.json
{
  "name": "opentelekomcloud-community/fg-ecs-start",
  "description": "Sample for a FunctionGraph function to start an ECS instance",
  "license": "Apache-2.0",
  "type": "project",

  "require": {
    "opentelekomcloud-community/otc-api-sign-sdk-php": "1.0.2"
  },
  "archive": {
    "exclude": [  
      "/Makefile"
    ]
  },
  "config": {
    "archive-format": "zip",
    "optimize-autoloader": true
  }
}

Deployment

Build deployment zip

Install dependencies using composer:

composer update

Following settings in composer.json are used to build a zip file for deployment to FunctionGraph (you may need to adjust the settings for your project):

zip settings
 {
   "archive": {
     "exclude": [
       "/Makefile"
     ]
   },
   "config": {
     "archive-format": "zip",
   }
 }

To build the deployment zip, execute following command in folder: samples-doc/functiongraph/ecs-start

composer archive --format=zip --file=code

This will create code.zip with code and dependencies included. (See composer.json how zip is built).

Create FunctionGraph function

Create function

Use OpentelekomCloud FunctionGraph console to create a function with following settings:

Create With: Create from scratch

Basic Information

  • Function Type: Event Function

  • Region: <YOUR REGION>, eg. eu-de

  • Function Name: <YOUR FUNCTION NAME>, eg. start-ecs

  • Agency: Specify an agency with policy to start ECS instance, e.g. ECS User

  • Runtime: PHP 8.3

Upload code

Use Upload -> Local ZIP and upload code.zip from previous step.

Configure function

In Configuration -> Basic Settings -> Handler: src/index.handler

In Configuration -> Environment Variables add following variables:

Environment variables

Environment variable name

Value

Default

ECS_INSTANCE_ID

<ID of ecs instance>

ECS_ENDPOINT

<ecs endpoint>

Default: ecs.eu-de.otc.t-systems.com

see: Regions and Endpoints

Create Test Event

In Code create a Test Event using “Blank Template” (Event is not used in function)

Test function

Click Test to test function.