mirror of
https://gitea.com/mcereda/oam.git
synced 2026-02-08 21:34:25 +00:00
feat: step functions example
This commit is contained in:
@@ -636,6 +636,52 @@ Such roles need to allow being assumed by the `states.amazonaws.com` Principal.
|
|||||||
|
|
||||||
If wanting to send logs to CloudWatch, the execution role must be able to access the log group.
|
If wanting to send logs to CloudWatch, the execution role must be able to access the log group.
|
||||||
|
|
||||||
|
<details style='padding: 0 0 1rem 1rem'>
|
||||||
|
<summary>Example: get an RDS DB instance's information and pass it as a specific attribute
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"Comment": "Get an RDS DB instance's information and pass it as a specific attribute",
|
||||||
|
"StartAt": "Get RDS DB Instance information",
|
||||||
|
"States": {
|
||||||
|
"Get RDS DB Instance information": {
|
||||||
|
"Type": "Task",
|
||||||
|
"Arguments": {
|
||||||
|
"DbInstanceIdentifier": "some-rds-db-instance-identifier"
|
||||||
|
},
|
||||||
|
"Resource": "arn:aws:states:::aws-sdk:rds:describeDBInstances",
|
||||||
|
"End": true,
|
||||||
|
"Output": {
|
||||||
|
"RdsDbInstanceInformation": "{% $states.result.DbInstances[0] %}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"QueryLanguage": "JSONata"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
Unless one knows exactly what one is doing, prefer setting arguments from the service's Console to have _some_ level of
|
||||||
|
suggestions.
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>FIXME - using variables in DescribeDBSnapshots</summary>
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"DbInstanceIdentifier": "{% $states.input.ProdDBInstanceInfo.DbInstanceIdentifier %}"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"AvailableDBSnapshots": "{% $states.result.DbSnapshots[Status='available'] %}"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
## Resource constraints
|
## Resource constraints
|
||||||
|
|
||||||
| Data type | Component | Summary | Description | Type | Length | Pattern | Required |
|
| Data type | Component | Summary | Description | Type | Length | Pattern | Required |
|
||||||
|
|||||||
92
knowledge base/jsonata.md
Normal file
92
knowledge base/jsonata.md
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
# JSONata
|
||||||
|
|
||||||
|
> TODO
|
||||||
|
|
||||||
|
JSON query and transformation language.
|
||||||
|
|
||||||
|
<!-- Remove this line to uncomment if used
|
||||||
|
## Table of contents <!-- omit in toc -->
|
||||||
|
|
||||||
|
1. [TL;DR](#tldr)
|
||||||
|
1. [Further readings](#further-readings)
|
||||||
|
1. [Sources](#sources)
|
||||||
|
|
||||||
|
## TL;DR
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
# Concatenate strings
|
||||||
|
someAttribute & 'someSuffix'
|
||||||
|
'somePrefix' & someAttribute
|
||||||
|
'somePrefix' & someAttribute & 'someSuffix'
|
||||||
|
|
||||||
|
# Join strings
|
||||||
|
$join(['somePrefix', someAttribute, 'someSuffix'], '-')
|
||||||
|
|
||||||
|
# Filter array of objects by attribute's value
|
||||||
|
users[role = "admin"]
|
||||||
|
users[role = "admin" and name = "Alice"].name
|
||||||
|
|
||||||
|
# Filter events with timestamp value in the last week
|
||||||
|
events[$toMillis(timestamp) >= $toMillis($now()) - (60 * 60 * 7 * 24 * 1000)]
|
||||||
|
|
||||||
|
# Get a random value between 0 included and 1 excluded (0<=X<1)
|
||||||
|
$random()
|
||||||
|
|
||||||
|
# Get a random object from a list
|
||||||
|
# Lists are 0-indexed
|
||||||
|
users[$floor($random()*$count($users))]
|
||||||
|
```
|
||||||
|
|
||||||
|
<!-- Uncomment if used
|
||||||
|
<details>
|
||||||
|
<summary>Setup</summary>
|
||||||
|
|
||||||
|
```sh
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- Uncomment if used
|
||||||
|
<details>
|
||||||
|
<summary>Usage</summary>
|
||||||
|
|
||||||
|
```sh
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- Uncomment if used
|
||||||
|
<details>
|
||||||
|
<summary>Real world use cases</summary>
|
||||||
|
|
||||||
|
```sh
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
-->
|
||||||
|
|
||||||
|
## Further readings
|
||||||
|
|
||||||
|
- [Website]
|
||||||
|
- [Codebase]
|
||||||
|
|
||||||
|
### Sources
|
||||||
|
|
||||||
|
- [Documentation]
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Reference
|
||||||
|
═╬═Time══
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- In-article sections -->
|
||||||
|
<!-- Knowledge base -->
|
||||||
|
<!-- Files -->
|
||||||
|
<!-- Upstream -->
|
||||||
|
[Codebase]: https://github.com/jsonata-js/jsonata
|
||||||
|
[Documentation]: https://docs.jsonata.org/
|
||||||
|
[Website]: https://jsonata.org/
|
||||||
|
|
||||||
|
<!-- Others -->
|
||||||
@@ -0,0 +1,219 @@
|
|||||||
|
import * as pulumi from "@pulumi/pulumi";
|
||||||
|
import * as aws from "@pulumi/aws";
|
||||||
|
|
||||||
|
const iamRole: pulumi.Output<aws.iam.GetRoleResult> = aws.iam.getRoleOutput({
|
||||||
|
name: 'SomeServiceRole',
|
||||||
|
});
|
||||||
|
|
||||||
|
// -----------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base type for Step Function states.
|
||||||
|
*
|
||||||
|
* States are elements in a state machine.\
|
||||||
|
* A state is referred to by its name, which can be any string, but which must be unique within the scope of the entire
|
||||||
|
* state machine.
|
||||||
|
*
|
||||||
|
* States take input from their own invocation or a previous state.\
|
||||||
|
* States can filter their input and manipulate the output that is sent to the next state.
|
||||||
|
*
|
||||||
|
* Refer <https://docs.aws.amazon.com/step-functions/latest/dg/workflow-states.html>.
|
||||||
|
*/
|
||||||
|
type StateMachineBaseState = {
|
||||||
|
Type: string;
|
||||||
|
Comment?: string;
|
||||||
|
Next?: string;
|
||||||
|
End?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Choice state.\
|
||||||
|
* Enables conditional branching.
|
||||||
|
*/
|
||||||
|
interface StateMachineChoiceState extends StateMachineBaseState {
|
||||||
|
Type: "Choice";
|
||||||
|
Choices: Record<string, any>[];
|
||||||
|
Default: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Branch type for Parallel states.\
|
||||||
|
* Itself a smaller state machine.
|
||||||
|
*/
|
||||||
|
type StateMachineParallelBranch = {
|
||||||
|
StartAt: string;
|
||||||
|
States: Record<string, StateMachineStepState>;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Parallel state.\
|
||||||
|
* Runs other step states in parallel.
|
||||||
|
*/
|
||||||
|
interface StateMachineParallelState extends StateMachineBaseState {
|
||||||
|
Type: "Parallel";
|
||||||
|
Branches: StateMachineParallelBranch[];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Task state.\
|
||||||
|
* Runs a service integration or Lambda function.
|
||||||
|
*/
|
||||||
|
interface StateMachineTaskState extends StateMachineBaseState {
|
||||||
|
Type: "Task";
|
||||||
|
Resource: string;
|
||||||
|
Arguments?: Record<string, any>;
|
||||||
|
Output?: Record<string, any>;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wait state.\
|
||||||
|
* Pauses execution for a fixed duration or until a specified time or date.
|
||||||
|
*/
|
||||||
|
interface StateMachineWaitState extends StateMachineBaseState {
|
||||||
|
Type: "Wait";
|
||||||
|
Seconds?: number;
|
||||||
|
Timestamp?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Union type for Step Function states.
|
||||||
|
*/
|
||||||
|
type StateMachineStepState =
|
||||||
|
| StateMachineChoiceState
|
||||||
|
| StateMachineParallelState
|
||||||
|
| StateMachineTaskState
|
||||||
|
| StateMachineWaitState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic State Machine definition.
|
||||||
|
*/
|
||||||
|
interface StateMachineDefinition {
|
||||||
|
Comment?: string;
|
||||||
|
QueryLanguage?: string;
|
||||||
|
StartAt: string;
|
||||||
|
States: Record<string, StateMachineStepState>;
|
||||||
|
};
|
||||||
|
|
||||||
|
// -----------------
|
||||||
|
|
||||||
|
const changeClonedDbInstancePassword: StateMachineTaskState = {
|
||||||
|
Type: "Task",
|
||||||
|
Resource: "arn:aws:states:::aws-sdk:rds:modifyDBInstance",
|
||||||
|
Arguments: {
|
||||||
|
DbInstanceIdentifier: "{% $states.input.ClonedDBInstance.DbInstanceIdentifier %}",
|
||||||
|
MasterUserPassword: "some-Secur3-Password",
|
||||||
|
ApplyImmediately: true,
|
||||||
|
},
|
||||||
|
End: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
const checkClonedDbInstanceIsAvailable: StateMachineChoiceState = {
|
||||||
|
Type: "Choice",
|
||||||
|
Choices: [
|
||||||
|
{
|
||||||
|
Condition: "{% $states.input.ClonedDBInstance.DBInstanceStatus in ['available'] %}",
|
||||||
|
Next: "ChangeClonedDBInstancePassword",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
Default: "WaitForClonedDBInstanceNextCheck",
|
||||||
|
};
|
||||||
|
|
||||||
|
const createClonedDbInstance: StateMachineTaskState = {
|
||||||
|
Type: "Task",
|
||||||
|
Resource: "arn:aws:states:::aws-sdk:rds:restoreDBInstanceToPointInTime",
|
||||||
|
Arguments: {
|
||||||
|
SourceDBInstanceIdentifier: "{% $states.input.ExistingDBInstanceInfo.DbInstanceIdentifier %}",
|
||||||
|
UseLatestRestorableTime: true,
|
||||||
|
TargetDBInstanceIdentifier: "{% $join([$states.input.ExistingDBInstanceInfo.DbInstanceIdentifier, 'clone'], '-') %}",
|
||||||
|
Engine: "postgres",
|
||||||
|
MultiAZ: false,
|
||||||
|
AvailabilityZone: "eu-west-1a",
|
||||||
|
DbSubnetGroupName: "default",
|
||||||
|
PubliclyAccessible: false,
|
||||||
|
VpcSecurityGroupIds: [],
|
||||||
|
DbParameterGroupName: "{% $states.input.ExistingDBInstanceInfo.DbParameterGroups[0].DbParameterGroupName %}",
|
||||||
|
OptionGroupName: "{% $states.input.ExistingDBInstanceInfo.OptionGroupMemberships[0].OptionGroupName %}",
|
||||||
|
StorageType: "gp3",
|
||||||
|
DedicatedLogVolume: false,
|
||||||
|
DbInstanceClass: "db.t4g.medium",
|
||||||
|
DeletionProtection: false,
|
||||||
|
AutoMinorVersionUpgrade: false,
|
||||||
|
},
|
||||||
|
Output: {
|
||||||
|
ClonedDBInstance: "{% $states.result.DbInstance %}",
|
||||||
|
},
|
||||||
|
Next: "GetClonedDBInstanceState",
|
||||||
|
};
|
||||||
|
|
||||||
|
const getClonedDbInstanceState: StateMachineTaskState = {
|
||||||
|
Type: "Task",
|
||||||
|
Resource: "arn:aws:states:::aws-sdk:rds:describeDBInstances",
|
||||||
|
Arguments: {
|
||||||
|
DbInstanceIdentifier: "{% $states.input.ClonedDBInstance.DbInstanceIdentifier %}",
|
||||||
|
},
|
||||||
|
Output: {
|
||||||
|
ClonedDBInstance: "{% $states.result.DbInstances[0] %}",
|
||||||
|
},
|
||||||
|
Next: "CheckClonedDBInstanceIsAvailable",
|
||||||
|
};
|
||||||
|
|
||||||
|
const getExistingDbInstanceInfo: StateMachineTaskState = {
|
||||||
|
Type: "Task",
|
||||||
|
Resource: "arn:aws:states:::aws-sdk:rds:describeDBInstances",
|
||||||
|
Arguments: {
|
||||||
|
DbInstanceIdentifier: "some-existing-rds-instance",
|
||||||
|
},
|
||||||
|
Output: {
|
||||||
|
ExistingDBInstanceInfo: "{% $states.result.DbInstances[0] %}",
|
||||||
|
},
|
||||||
|
Next: "ParallelZone",
|
||||||
|
};
|
||||||
|
|
||||||
|
const waitForClonedDbInstanceNextCheck: StateMachineWaitState = {
|
||||||
|
Type: "Wait",
|
||||||
|
Seconds: 60,
|
||||||
|
Next: "GetClonedDBInstanceState",
|
||||||
|
};
|
||||||
|
|
||||||
|
const parallelZone: StateMachineParallelState = {
|
||||||
|
Type: "Parallel",
|
||||||
|
Branches: [
|
||||||
|
{
|
||||||
|
StartAt: "CreateClonedDBInstance",
|
||||||
|
States: {
|
||||||
|
CreateClonedDBInstance: createClonedDbInstance,
|
||||||
|
GetClonedDBInstanceState: getClonedDbInstanceState,
|
||||||
|
CheckClonedDBInstanceIsAvailable: checkClonedDbInstanceIsAvailable,
|
||||||
|
WaitForClonedDBInstanceNextCheck: waitForClonedDbInstanceNextCheck,
|
||||||
|
ChangeClonedDBInstancePassword: changeClonedDbInstancePassword,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// FIXME: another branch here
|
||||||
|
],
|
||||||
|
End: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
const stateMachineDefinition: StateMachineDefinition = {
|
||||||
|
QueryLanguage: "JSONata",
|
||||||
|
States: {
|
||||||
|
GetExistingDBInstanceInfo: getExistingDbInstanceInfo,
|
||||||
|
ParallelZone: parallelZone,
|
||||||
|
},
|
||||||
|
StartAt: "GetExistingDBInstanceInfo",
|
||||||
|
};
|
||||||
|
// pulumi.jsonStringify(stateMachineDefinition).apply(s => console.log(s))
|
||||||
|
|
||||||
|
const dbCloner_stateMachine: aws.sfn.StateMachine = new aws.sfn.StateMachine(
|
||||||
|
'dbCloner',
|
||||||
|
{
|
||||||
|
name: 'DBCloner',
|
||||||
|
roleArn: iamRole.arn,
|
||||||
|
loggingConfiguration: {
|
||||||
|
level: "OFF",
|
||||||
|
},
|
||||||
|
encryptionConfiguration: {
|
||||||
|
type: "AWS_OWNED_KEY",
|
||||||
|
},
|
||||||
|
publish: false,
|
||||||
|
definition: pulumi.jsonStringify(stateMachineDefinition),
|
||||||
|
},
|
||||||
|
);
|
||||||
Reference in New Issue
Block a user