{"id":26260272,"url":"https://github.com/mashiike/stefunny","last_synced_at":"2025-04-30T06:41:07.155Z","repository":{"id":37950930,"uuid":"424085720","full_name":"mashiike/stefunny","owner":"mashiike","description":null,"archived":false,"fork":false,"pushed_at":"2025-03-10T23:56:09.000Z","size":867,"stargazers_count":6,"open_issues_count":4,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-11T00:28:29.739Z","etag":null,"topics":["stepfunctions"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mashiike.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-11-03T03:58:07.000Z","updated_at":"2025-03-10T23:48:16.000Z","dependencies_parsed_at":"2024-02-13T04:28:08.406Z","dependency_job_id":"c508c0f0-13b5-4ec8-b924-257d6f1947ad","html_url":"https://github.com/mashiike/stefunny","commit_stats":{"total_commits":98,"total_committers":2,"mean_commits":49.0,"dds":"0.010204081632653073","last_synced_commit":"e6e223a6abdd11f392bf09f93cef7cf98d7824e5"},"previous_names":[],"tags_count":29,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mashiike%2Fstefunny","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mashiike%2Fstefunny/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mashiike%2Fstefunny/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mashiike%2Fstefunny/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mashiike","download_url":"https://codeload.github.com/mashiike/stefunny/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243495504,"owners_count":20299922,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["stepfunctions"],"created_at":"2025-03-13T23:08:47.683Z","updated_at":"2025-03-13T23:08:48.901Z","avatar_url":"https://github.com/mashiike.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# stefunny\n\n![Latest GitHub release](https://img.shields.io/github/release/mashiike/stefunny.svg)\n![Github Actions test](https://github.com/mashiike/stefunny/workflows/Test/badge.svg?branch=main)\n[![Go Report Card](https://goreportcard.com/badge/mashiike/stefunny)](https://goreportcard.com/report/mashiike/stefunny)\n[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/mashiike/stefunny/blob/master/LICENSE)\n\nstefunny is a deployment tool for [AWS StepFunctions](https://aws.amazon.com/step-functions/) state machine and the accompanying [AWS EventBridge](https://aws.amazon.com/eventbridge/) rule and scheudle.\n\nstefunny does,\n\n- Create a state machine.\n- Create a EventBridge rule and EventBridge Scheduler schedule.\n- Deploy state machine/ EventBridge rule / EventBridge Scheduler schedule/ StateMachine Alias.\n- Rollback to the previous version of the state machine.\n- Manage state machine versions.\n- Show status of the state machine.\n\nThat's all for now.\n\nstefunny does not,\n\n- Manage resources related to the StepFunctions state machine.\n    - e.g. IAM Role, Resources called by state machine, Trigger rule that is not a schedule, CloudWatch LogGroup, etc...\n- Manage StepFunctions Activities and Activity Worker.\n\nIf you hope to manage these resources **collectively**, we recommend other deployment tools ([AWS SAM](https://aws.amazon.com/serverless/sam/), [Serverless Framework](https://serverless.com/), etc.).\n\nIf you hope to manage these resources **partially individually**, we recommend the following tools:\n\n - [terraform](https://www.terraform.io/) for IAM Role, CloudWatch LogGroups, etc... \n - [lambroll](https://github.com/fujiwara/lambroll) for AWS Lambda function.\n - [ecspresso](https://github.com/kayac/ecspresso) for AWS ECS Task.\n\n## Install\n\n### Homebrew (macOS and Linux)\n\n```console\n$ brew install mashiike/tap/stefunny\n```\n\n### aqua\n\n[aqua](https://aquaproj.github.io/) is a declarative CLI Version Manager.\n\n```console\n$ aqua g -i mashiike/stefunny\n```\n\n### Binary packages\n\n[Releases](https://github.com/mashiike/stefunny/releases)\n\n### GitHub Actions\n\nAction mashiike/stefunny@v0 installs stefunny binary for Linux into /usr/local/bin. This action runs install only.\n\n```yml\njobs:\n  deploy:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n      - uses: mashiike/stefunny@v0\n        with:\n          version: v0.6.0 \n      - run: |\n          stefunny deploy\n```\n \n## QuickStart \nTry migrate your existing StepFunctions StateMachine to stefunny.\n\n```console\n$ mkdir hello\n$ cd hello\n$ stefunny init --state-machine Hello     \n2024/02/13 16:07:53 [notice] StateMachine/Hello save config to /home/user/hello/stefunny.yaml\n2024/02/13 16:07:53 [notice] StateMachine/Hello save state machine definition to /home/user/hello/definition.asl.json\n```\n\nEdit the definition.asl.json and stefunny.yaml.\n\nNow you can deploy state machine `Hello` using `stefunny deploy`.\n\n```console\n$ stefunny deploy\n2024/02/13 16:18:42 [info] Starting deploy \n2024/02/13 16:18:42 [info] update state machine `arn:aws:states:ap-northeast-1:123456789012:stateMachine:Hello:2`\n2024/02/13 16:18:42 [info] update current alias `arn:aws:states:ap-northeast-1:123456789012:stateMachine:Hello:current`\n2024/02/13 16:18:42 [info] deploy state machine `Hello`(at `2024-02-13 07:17:48.178 +0000 UTC`)\n2024/02/13 16:18:43 [info] finish deploy \n```\n\n## Usage\n\n```console\nUsage: stefunny \u003ccommand\u003e\n\nstefunny is a deployment tool for AWS StepFunctions state machine\n\nFlags:\n  -h, --help                      Show context-sensitive help.\n      --log-level=\"info\"          Set log level (debug, info, notice, warn, error) ($STEFUNNY_LOG_LEVEL)\n  -c, --config=\"stefunny.yaml\"    Path to config file ($STEFUNNY_CONFIG)\n      --tfstate=STRING            URL to terraform.tfstate referenced in config ($STEFUNNY_TFSTATE)\n      --ext-str=,...              external string values for Jsonnet\n      --ext-code=,...             external code values for Jsonnet\n      --region=\"\"                 AWS region ($AWS_REGION)\n      --alias=\"current\"           Alias name for state machine ($STEFUNNY_ALIAS)\n\nCommands:\n  version\n    Show version\n\n  init --state-machine=STRING\n    Initialize stefunny configuration\n\n  delete\n    Delete state machine and schedule rules\n\n  deploy\n    Deploy state machine and schedule rules\n\n  rollback\n    Rollback state machine\n\n  schedule --enabled --disabled\n    Enable or disable schedule rules (deprecated)\n\n  render \u003ctargets\u003e ...\n    Render state machine definition\n\n  execute\n    Execute state machine\n\n  versions\n    Manage state machine versions\n\n  diff\n    Show diff of state machine definition and trigers\n\n  pull\n    Pull state machine definition\n\n  studio\n    Show Step Functions workflow studio URL\n\n  status\n    Show status of state machine\n\nRun \"stefunny \u003ccommand\u003e --help\" for more information on a command.\n```\n\n### Init \n\n`stepfunny init` initialize stefunny.yaml and definition file by existing state machine.\n\n```console\nUsage: stefunny init --state-machine=STRING\n\nInitialize stefunny configuration\n\nFlags:\n  -h, --help                                Show context-sensitive help.\n      --log-level=\"info\"                    Set log level (debug, info, notice, warn, error) ($STEFUNNY_LOG_LEVEL)\n  -c, --config=\"stefunny.yaml\"              Path to config file ($STEFUNNY_CONFIG)\n      --tfstate=STRING                      URL to terraform.tfstate referenced in config ($STEFUNNY_TFSTATE)\n      --ext-str=,...                        external string values for Jsonnet\n      --ext-code=,...                       external code values for Jsonnet\n      --region=\"\"                           AWS region ($AWS_REGION)\n      --alias=\"current\"                     Alias name for state machine ($STEFUNNY_ALIAS)\n\n      --state-machine=STRING                AWS StepFunctions state machine name ($STATE_MACHINE_NAME)\n  -d, --definition=\"definition.asl.json\"    Path to state machine definition file ($DEFINITION_FILE_PATH)\n      --env=ENV,...                         templateize environment variables\n      --must-env=MUST-ENV,...               templateize must environment variables\n      --skip-trigger                        Skip trigger\n```\n\ncreated file foramt are checked file extension. `.json` saved as json, `.jsonnet` saved as jsonnet, `.yaml` or `.yml` saved as yaml.\n\nIf you manage the aws resources by terraform, you can use `--tfstate` flag with `stefunny init` command.\n\n```console\n$ export ENV=dev\n$ stefunny init --state-machine dev-Hello --tfstate s3://my-bucket/terraform.tfstate --must-env ENV\n```\nin this case, saved config and definition file are templatized by `text/template` \n\nfor example, the saved config file is like this.\n\n```yaml\naws_region: ap-northeast-1\nrequired_version: \"\u003e=v0.6.0\"\nstate_machine:\n  definition: definition.asl.json\n  logging_configuration:\n    destinations:\n    - cloudwatch_logs_log_group:\n        log_group_arn: \"{{ tfstate `aws_cloudwatch_log_group.state_machine.arn` }}:*\"\n    include_execution_data: true\n    level: ALL\n  name: \"{{ must_env `ENV` }}-Hello\"\n  role_arn: \"{{ tfstate `aws_iam_role.state_machine.arn` }}\"\n  tags:\n  - key: Name\n    value: \"{{ must_env `ENV` }}-Hello\"\n  tracing_configuration:\n    enabled: true\n  type: STANDARD\n```\n\n### Deploy\n\n```console\nUsage: stefunny deploy\n\nDeploy state machine and schedule rules\n\nFlags:\n  -h, --help                          Show context-sensitive help.\n      --log-level=\"info\"              Set log level (debug, info, notice, warn, error) ($STEFUNNY_LOG_LEVEL)\n  -c, --config=\"stefunny.yaml\"        Path to config file ($STEFUNNY_CONFIG)\n      --tfstate=STRING                URL to terraform.tfstate referenced in config ($STEFUNNY_TFSTATE)\n      --ext-str=,...                  external string values for Jsonnet\n      --ext-code=,...                 external code values for Jsonnet\n      --region=\"\"                     AWS region ($AWS_REGION)\n      --alias=\"current\"               Alias name for state machine ($STEFUNNY_ALIAS)\n\n      --dry-run                       Dry run\n      --skip-state-machine            Skip deploy state machine\n      --skip-trigger                  Skip deploy trigger\n      --version-description=STRING    Version description\n      --keep-versions=0               Number of latest versions to keep. Older versions will be deleted. (Optional value: default 0)\n      --trigger-enabled               Enable trigger\n      --trigger-disabled              Disable trigger\n      --[no-]unified                  when dry run, output unified diff\n```\nstefunny deploy works as below.\n\n- Create / Update State Machine from config file and definition file(yaml/json/jsonnet)\n  - Replace {{ env `FOO` `bar` }} syntax in the config file and definition file to environment variable \"FOO\".\n    If \"FOO\" is not defined, replaced by \"bar\"\n  - Replace {{ must_env `FOO` }} syntax in the config file and definition file to environment variable \"FOO\".\n    If \"FOO\" is not defined, abort immediately.\n  - If a terraform state is given in config, replace the {{tfstate `\u003ctf resource name\u003e`}} syntax in the config file and definition file with reference to the state content.\n- Publish new version of the state machine.\n- Update the alias to the new version.\n- Create/ Update EventBridge rule.\n- Create/ Update EventBridge Scheduler schedule.\n\n### Rollback \n\n```console\nUsage: stefunny rollback\n\nRollback state machine\n\nFlags:\n  -h, --help                      Show context-sensitive help.\n      --log-level=\"info\"          Set log level (debug, info, notice, warn, error) ($STEFUNNY_LOG_LEVEL)\n  -c, --config=\"stefunny.yaml\"    Path to config file ($STEFUNNY_CONFIG)\n      --tfstate=STRING            URL to terraform.tfstate referenced in config ($STEFUNNY_TFSTATE)\n      --ext-str=,...              external string values for Jsonnet\n      --ext-code=,...             external code values for Jsonnet\n      --region=\"\"                 AWS region ($AWS_REGION)\n      --alias=\"current\"           Alias name for state machine ($STEFUNNY_ALIAS)\n\n      --dry-run                   Dry run\n      --keep-version              Keep current version, no delete\n```\n\n`stefunny deploy` create/update alias `current` to the published state machine version on deploy.\n\n`stefunny rollback` works as below.\n\n1. Find previous one version of state machine.\n2. Update alias `current` to the previous version.\n3. default delete old version of state machine. (when `--keep-version` specified, not delete old version of state machine)\n\n### Studio and Pull \n\nIf you use AWS Step Functions Workflow Studio, you can open the studio URL with `stefunny studio` command.\n\n```console\nUsage: stefunny studio\n\nShow Step Functions workflow studio URL\n\nFlags:\n  -h, --help                      Show context-sensitive help.\n      --log-level=\"info\"          Set log level (debug, info, notice, warn, error) ($STEFUNNY_LOG_LEVEL)\n  -c, --config=\"stefunny.yaml\"    Path to config file ($STEFUNNY_CONFIG)\n      --tfstate=STRING            URL to terraform.tfstate referenced in config ($STEFUNNY_TFSTATE)\n      --ext-str=,...              external string values for Jsonnet\n      --ext-code=,...             external code values for Jsonnet\n      --region=\"\"                 AWS region ($AWS_REGION)\n      --alias=\"current\"           Alias name for state machine ($STEFUNNY_ALIAS)\n\n      --open                      open workflow studio\n```\n\n`stefunny studio` command shows the studio URL. If `--open` flag is specified, open the studio URL in the browser.\nEdit state machine on Workflow Studio, and pull the definition file with `stefunny pull` command.\n\n```console\nUsage: stefunny pull\n\nPull state machine definition\n\nFlags:\n  -h, --help                      Show context-sensitive help.\n      --log-level=\"info\"          Set log level (debug, info, notice, warn, error) ($STEFUNNY_LOG_LEVEL)\n  -c, --config=\"stefunny.yaml\"    Path to config file ($STEFUNNY_CONFIG)\n      --tfstate=STRING            URL to terraform.tfstate referenced in config ($STEFUNNY_TFSTATE)\n      --ext-str=,...              external string values for Jsonnet\n      --ext-code=,...             external code values for Jsonnet\n      --region=\"\"                 AWS region ($AWS_REGION)\n      --alias=\"current\"           Alias name for state machine ($STEFUNNY_ALIAS)\n\n      --[no-]templateize          templateize output\n      --qualifier=STRING          qualifier for the version\n```\n\n`stefunny pull` command pull the definition file from the state machine and save it to the file.\n\n### config file (yaml)\n\n```yaml\nrequired_version: \"\u003e=v0.6.0\"\naws_region: \"{{ env `AWS_REGION` `ap-northeast-1` }}\"\n\nstate_machine:\n  name: \"{{ must_env `ENV` }}-Hello\"\n  definition: definition.asl.json\n  logging_configuration:\n    destinations:\n      - cloudwatch_logs_log_group:\n          log_group_arn: \"{{ tfstate `aws_cloudwatch_log_group.state_machine.arn` }}:*\"\n    include_execution_data: true\n    level: ALL\n\n  role_arn: \"{{ tfstate `aws_iam_role.state_machine.arn` }}\"\n  tracing_configuration:\n    enabled: true\n  type: STANDARD\n\ntfstate:\n  - location: s3://my-tfstate-bucket/terraform.tfstate\n\ntrigger:\n  schedule:\n    - name: \"{{ must_env `ENV` }}-stefunny-test\"\n      group_name: default\n      action_after_completion: DELETE\n      flexible_time_window:\n        maximum_window_in_minutes: 240.0\n        mode: FLEXIBLE\n      schedule_expression: at(2024-02-29T00:01:00)\n      target:\n        retry_policy:\n          maximum_event_age_in_seconds: 86400.0\n          maximum_retry_attempts: 185.0\n        role_arn: \"{{ tfstate `aws_iam_role.event_bridge_scheduler.arn` }}\"\n\n  event:\n    - name: \"{{ must_env `ENV` }}-stefunny-test\"\n      event_bus_name: default\n      event_pattern: \"{{ file `event_pattern.json` | json_escape }}\"\n      role_arn: \"{{ tfstate `aws_iam_role.event_bridge.arn` }}\"\n\n```\n\nConfiguration files and definition files are read with `text/template`, stefunny has template functions env, must_env, file, json_escape and tfstate.\n\n\n### Template syntax\n\nstefunny uses the [text/template standard package in Go](https://pkg.go.dev/text/template) to render template files, and parses as YAML/JSON/Jsonnet. \n\n#### `env`\n\n```\n\"{{ env `NAME` `default value` }}\"\n```\n\nIf the environment variable `NAME` is set, it will replace with its value. If it's not set, it will replace with \"default value\".\n\n#### `must_env`\n\n```\n\"{{ must_env `NAME` }}\"\n```\n\nIt replaces with the value of the environment variable `NAME`. If the variable isn't set at the time of execution, stefunny will panic and stop forcefully.\n\nBy defining values that can cause issues when running without meaningful values with must_env, you can prevent unintended deployments.\n\n#### `json_escape`\n\n```\n\"{{ must_env `JSON_VALUE` | json_escape }}\"\n```\n\nIt escapes values as JSON strings. Use it when you want to escape values that need to be embedded as strings and require escaping, like quotes.\n\n#### `file`\n\n```\n\"{{ file `path/to/file` }}\"\n```\n\n#### `tfstate`\n\nIf written `tfstate` section in the configuration file, it will be use `tfstate` template function. as following.\n\nstefunny.yaml\n```yaml\nrequired_version: \"\u003ev0.0.0\"\n\nstate_machine:\n  name: send_sns\n  definition: send_sns.asl.jsonnet\n  role_arn: \"{{ tfstae `aws_iam_role.stepfunctions.arn` }}\"\n  logging_configuration:\n    level: OFF\n\ntfstate:\n  - path: \"./terraform.tfstate\"\n  - url: s3://my-bucket/terraform.tfstate\n    func_prefix: s3_\n```\n\nsend_sns.asl.jsonnet\n```jsonnet\n{\n  Comment: \"A simple AWS Step Functions state machine that sends a message to an SNS topic\", \n  StartAt: \"Send SNS Message\",\n  States: {\n    \"Send SNS Message\": {\n      Type: \"Task\",\n      Resource: \"arn:aws:states:::sns:publish\",\n      Parameters: {\n        \"TopicArn\": \"{{ s3_tfstate `aws_sns_topic.topic.arn` }}\",\n        \"Message.$\": \"$\"\n      },\n      End: true,\n    }\n  }\n}\n```\n\n`{{ tfstate \"resource_type.resource_name.attr\" }}` will expand to an attribute value of the resource in tfstate.\n\n`{{ tfstatef \"resource_type.resource_name['%s'].attr\" \"index\" }}` is similar to `{{ tfstatef \"resource_type.resource_name['index'].attr\" }}`. This function is useful to build a resource address with environment variables.\n\n```\n{{ tfstatef `aws_subnet.ecs['%s'].id` (must_env `SERVICE`) }}\n```\n\nThis function uses [tfstate-lookup](https://github.com/fujiwara/tfstate-lookup) to load tfstate.\n\n\n## Special Thanks\n\n@fujiwara has given me naming idea of stefunny.\n\n##  Inspire tools\n\n - [lambroll](https://github.com/fujiwara/lambroll)\n - [ecspresso](https://github.com/kayac/ecspresso)\n## LICENSE\n\nMIT License\n\nCopyright (c) 2021 IKEDA Masashi\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmashiike%2Fstefunny","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmashiike%2Fstefunny","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmashiike%2Fstefunny/lists"}