Analyzing cam.yaml
Example
metadata: description: This is an example application for FunctionGraph. author: Serverless team homePageUrl: https://www.huaweicloud.com/product/functiongraph.html version: 1.0.0 components: - name: helloworld type: Huawei::FunctionGraph::Function properties: region: cn-east-4 codeUri: https://test-wkx.obs.cn-north-4.myhuaweicloud.com/helloworld.zip projectID: 0531e14952000f742f3ec0088c4b25cf handler: index.handler runtime: Python3.9 memorySize: 256 timeout: 60 userData: key1: value1 key2: value2 encryptedUserData: '{"nonce": "ZEUOREFaiahRbMz+K9xQwA==", "header": "aGVhZGVy", "ciphertext": "SCxXsffvpU1BF2Ci8a2RedNQ", "tag": "a+EYRVPOsQ+YpQkMuFg1wA=="}' initializerTimeout: 30 initializerHandler: index.init_handler strategyConfig: concurrency: 80 concurrentNum: 20
Parameter Description
Function configuration is included in properties of the cam.yaml file. The following table details the function configuration.
Parameter |
Mandatory |
Can Be Updated |
Description |
---|---|---|---|
region |
Yes |
No |
Region where the function is located. |
codeUri |
Yes |
No |
Location of the function code. It is an OBS address where the function code package is stored. |
projectID |
Yes |
No |
Project ID. |
handler |
Yes |
Yes |
Function handler. |
runtime |
Yes |
No |
Execution environment. Options: Python 2.7 Python 3.6 PHP 7.3 Java 8 Node.js 6.10 Node.js 8.10 C# (.NET Core 2.0) C# (.NET Core 2.1) C# (.NET Core 3.1) Custom |
memorySize |
Yes |
Yes |
Memory size. Unit: MB. Enumerated values: 128, 256, 512, 768, 1024, 1280, 1536, 1792, 2048, 2560, 3072, 3584, 4096 |
timeout |
Yes |
Yes |
Timeout. Value range: 3s to 900s. |
userData |
No |
Yes |
Name/value information defined for the function. |
encryptedUserData |
No |
Yes |
Name/value information to be encrypted. |
initializerTimeout |
No |
Yes |
Initialization timeout. Value range: 1s to 300s. |
initializerHandler |
No |
Yes |
Function initializer. It must be in the format of "xx.xx". For example, if the function file name is myfunction.js and the initializer function is initializer, the initializer is myfunction.initializer. |
concurrentNum |
No |
Yes |
Maximum number of concurrent requests per instance. |
concurrency |
No |
Yes |
Maximum number of instances per function. Value 0 indicates that a function is disabled, and value –1 indicates that there is no instance limit. For example, the value 100 means that a function can have a maximum 100 instances, including common and reserved instances. |

- Currently, the cam.yaml file does not support the update of VPC, agency, file system, and dynamic memory settings. If a function uses a VPC, agency, file system, or dynamic memory settings, configure them on the function details page. These settings will be kept when executing the function update pipeline.
- To avoid displaying encryptedUserData in plaintext in the cam.yaml file, the CI/CD process encrypts its value using AES with Galois/Counter Mode (GCM). The ciphertext is the value of encryptedUserData in the cam.yaml file. This value is transferred in ciphertext in both the functions repository and the function update pipeline. It is decrypted and updated when the function is deployed. Therefore, the key for AES encryption must be provided when the function update pipeline is executed. Example:
Value of encryptedUserData in plaintext:
'{"password":"123"}'
After AES-GCM encryption:
{"nonce": "ZEUOREFaiahRbMz+K9xQwA==", "header": "aGVhZGVy", "ciphertext": "SCxXsffvpU1BF2Ci8a2RedNQ", "tag": "a+EYRVPOsQ+YpQkMuFg1wA=="} ciphertext is the encrypted value.
Keep the key for AES encryption properly.
Python AES-GCM example: https://pycryptodome.readthedocs.io/en/latest/src/cipher/modern.html?highlight=GCM#gcm-mode
The AES-GCM encryption script is as follows:
import json from base64 import b64encode from Crypto.Cipher import AES import sys if __name__ == '__main__': key = sys.argv[1].encode() data = sys.argv[2].encode() header = b"header" cipher = AES.new(key, AES.MODE_GCM) cipher.update(header) ciphertext, tag = cipher.encrypt_and_digest(data) json_k = ['nonce', 'header', 'ciphertext', 'tag'] json_v = [b64encode(x).decode('utf-8') for x in [cipher.nonce, header, ciphertext, tag]] result = json.dumps(dict(zip(json_k, json_v))) print(result)
To execute the script, run the following command on an ECS:
python3 aes_gcm_encrypt_tool.py "16-byte key" '{"password":"123"}'
Feedback
Was this page helpful?
Provide feedbackThank you very much for your feedback. We will continue working to improve the documentation.See the reply and handling status in My Cloud VOC.
For any further questions, feel free to contact us through the chatbot.
Chatbot