Octopus - Web App Reference Architecture

Octopus.TerraformApply exported 2023-11-12 by mcasperson belongs to ‘Octopus’ category.

This step populates an Octopus space with the environments, feeds, accounts, lifecycles, projects, and runbooks required to deploy a sample application to an Azure Web App. These resources combine to form a reference architecture teams can use to bootstrap an Octopus space with best practices and example projects. It is recommended that you run this step with the octopuslabs/terraform-workertools container image.

That this step assumes it is run on a cloud Octopus instance, or the default worker runs Linux, has Docker installed, and has PowerShell Core installed.

The step will not update existing projects, environments etc. If you wish to recreate these resource with the latest configuration, for example if this step is updated and you wish to see the latest settings, you must manually delete or rename the resources to be recreated.

Parameters

When steps based on the template are included in a project’s deployment process, the parameters below can be set.

Azure account application ID

ReferenceArchitecture.WebApp.Azure.ApplicationId =

This is the The Azure account application ID. Refer to the Azure documentation for details on creating a service principal.

Azure account subscription ID

ReferenceArchitecture.WebApp.Azure.SubscriptionId =

This is the The Azure account subscription ID. Refer to the Azure documentation for details on creating a service principal.

Azure account tenant ID

ReferenceArchitecture.WebApp.Azure.TenantId =

This is the The Azure account tenant ID. Refer to the Azure documentation for details on creating a service principal.

Azure account password

ReferenceArchitecture.WebApp.Azure.AccountPassword =

This is the The Azure account password. Refer to the Azure documentation for details on creating a service principal.

Docker Hub Username

ReferenceArchitecture.WebApp.Docker.Username =

The Docker Hub username. See the Docker docs for more information on creating a Docker Hub account.

Docker Hub Password

ReferenceArchitecture.WebApp.Docker.Password =

The Docker Hub password. See the Docker docs for more information on creating a Docker Hub account.

GitHub Access Token

ReferenceArchitecture.WebApp.GitHub.AccessToken =

The GitHub access token. Find more details in the GitHub documentation.

This value is used when populating GitHub repos with template projects. It can be left blank if you do not use the Create Template Github <platform> Project runbooks.

Octopus API Key

ReferenceArchitecture.WebApp.Octopus.ApiKey =

The Octopus API key. See the Octopus docs for more details on creating an API Key.

Octopus Space ID

ReferenceArchitecture.WebApp.Octopus.SpaceId = #{Octopus.Space.Id}

The Octopus space ID.

Octopus Server URL

ReferenceArchitecture.WebApp.Octopus.ServerUrl = #{Octopus.Web.ServerUri}

The Octopus server URL.

Optional Terraform Apply Args

ReferenceArchitecture.Terraform.ApplyArgs =

Optional arguments passed to the terraform apply command. See the documentation for details on any optional variables that can be defined here. Leave this field blank unless you have a specific reason to change it.

Optional Terraform Init Args

ReferenceArchitecture.Terraform.InitArgs =

Optional arguments passed to the terraform init command. See the documentation for details on any optional variables that can be defined here. Leave this field blank unless you have a specific reason to change it.

Script body

Steps based on this template will execute the following undefined script.

undefined

Provided under the Apache License version 2.0.

Report an issue

To use this template in Octopus Deploy, copy the JSON below and paste it into the Library → Step templates → Import dialog.

{
  "Id": "614ec627-22a1-442a-b6a1-d51ae7009999",
  "Name": "Octopus - Web App Reference Architecture",
  "Description": "This step populates an Octopus space with the environments, feeds, accounts, lifecycles, projects, and runbooks required to deploy a sample application to an Azure Web App. These resources combine to form a reference architecture teams can use to bootstrap an Octopus space with best practices and example projects. It is recommended that you run this step with the octopuslabs/terraform-workertools container image.\n\nThat this step assumes it is run on a cloud Octopus instance, or the default worker runs Linux, has Docker installed, and has PowerShell Core installed.\n\nThe step will not update existing projects, environments etc. If you wish to recreate these resource with the latest configuration, for example if this step is updated and you wish to see the latest settings, you must manually delete or rename the resources to be recreated.",
  "Version": 4,
  "ExportedAt": "2023-11-12T23:48:11.062Z",
  "ActionType": "Octopus.TerraformApply",
  "Author": "mcasperson",
  "Packages": [],
  "Parameters": [
    {
      "Id": "e8ed2805-bd27-470d-9580-c5486201e5e4",
      "Name": "ReferenceArchitecture.WebApp.Azure.ApplicationId",
      "Label": "Azure account application ID",
      "HelpText": "This is the The Azure account application ID. Refer to the [Azure documentation](https://learn.microsoft.com/en-us/purview/create-service-principal-azure) for details on creating a service principal.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "857dd051-4f27-4533-b3c1-4f60e2da208a",
      "Name": "ReferenceArchitecture.WebApp.Azure.SubscriptionId",
      "Label": "Azure account subscription ID",
      "HelpText": "This is the The Azure account subscription ID. Refer to the [Azure documentation](https://learn.microsoft.com/en-us/purview/create-service-principal-azure) for details on creating a service principal.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "99a7b543-4b0e-49d6-9e48-bc176e07e75e",
      "Name": "ReferenceArchitecture.WebApp.Azure.TenantId",
      "Label": "Azure account tenant ID",
      "HelpText": "This is the The Azure account tenant ID. Refer to the [Azure documentation](https://learn.microsoft.com/en-us/purview/create-service-principal-azure) for details on creating a service principal.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "6ea2138c-d67e-477b-975d-622a5f5e0f33",
      "Name": "ReferenceArchitecture.WebApp.Azure.AccountPassword",
      "Label": "Azure account password",
      "HelpText": "This is the The Azure account password. Refer to the [Azure documentation](https://learn.microsoft.com/en-us/purview/create-service-principal-azure) for details on creating a service principal.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "Sensitive"
      }
    },
    {
      "Id": "47a001cc-f17b-4905-bd73-91363d7b5f83",
      "Name": "ReferenceArchitecture.WebApp.Docker.Username",
      "Label": "Docker Hub Username",
      "HelpText": "The Docker Hub username. See the [Docker docs](https://docs.docker.com/docker-id/) for more information on creating a Docker Hub account.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "d83f2e90-532a-4db0-97e9-f07e8167c3e7",
      "Name": "ReferenceArchitecture.WebApp.Docker.Password",
      "Label": "Docker Hub Password",
      "HelpText": "The Docker Hub password. See the [Docker docs](https://docs.docker.com/docker-id/) for more information on creating a Docker Hub account.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "Sensitive"
      }
    },
    {
      "Id": "4d8e6395-e298-42f2-b2ca-cfdbcd65ae2b",
      "Name": "ReferenceArchitecture.WebApp.GitHub.AccessToken",
      "Label": "GitHub Access Token",
      "HelpText": "The GitHub access token. Find more details in the [GitHub documentation](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens).\n\n\nThis value is used when populating GitHub repos with template projects. It can be left blank if you do not use the `Create Template Github <platform> Project` runbooks.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "Sensitive"
      }
    },
    {
      "Id": "e088e550-e179-4998-be04-0b6653bd8371",
      "Name": "ReferenceArchitecture.WebApp.Octopus.ApiKey",
      "Label": "Octopus API Key",
      "HelpText": "The Octopus API key. See the [Octopus docs](https://octopus.com/docs/octopus-rest-api/how-to-create-an-api-key) for more details on creating an API Key.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "Sensitive"
      }
    },
    {
      "Id": "5c5c947b-2d3a-4f1f-a85c-1fa6a3b61bac",
      "Name": "ReferenceArchitecture.WebApp.Octopus.SpaceId",
      "Label": "Octopus Space ID",
      "HelpText": "The Octopus space ID.",
      "DefaultValue": "#{Octopus.Space.Id}",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "4b8f62d1-1c12-4027-bc60-44029c7df0cc",
      "Name": "ReferenceArchitecture.WebApp.Octopus.ServerUrl",
      "Label": "Octopus Server URL",
      "HelpText": "The Octopus server URL.",
      "DefaultValue": "#{Octopus.Web.ServerUri}",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Id": "ce1529b7-c366-4faa-a3bc-bade411237cc",
      "Name": "ReferenceArchitecture.Terraform.ApplyArgs",
      "Label": "Optional Terraform Apply Args",
      "HelpText": "Optional arguments passed to the `terraform apply` command. See the [documentation](https://oc.to/wRvMoP) for details on any optional variables that can be defined here. Leave this field blank unless you have a specific reason to change it.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "MultiLineText"
      }
    },
    {
      "Id": "14a42b42-2692-4850-943c-425d3036bf1c",
      "Name": "ReferenceArchitecture.Terraform.InitArgs",
      "Label": "Optional Terraform Init Args",
      "HelpText": "Optional arguments passed to the `terraform init` command. See the [documentation](https://oc.to/wRvMoP) for details on any optional variables that can be defined here. Leave this field blank unless you have a specific reason to change it.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "MultiLineText"
      }
    }
  ],
  "Properties": {
    "Octopus.Action.GoogleCloud.UseVMServiceAccount": "True",
    "Octopus.Action.GoogleCloud.ImpersonateServiceAccount": "False",
    "Octopus.Action.Terraform.GoogleCloudAccount": "False",
    "Octopus.Action.Terraform.AzureAccount": "False",
    "Octopus.Action.Terraform.ManagedAccount": "None",
    "Octopus.Action.Terraform.AllowPluginDownloads": "True",
    "Octopus.Action.Script.ScriptSource": "Inline",
    "Octopus.Action.Terraform.RunAutomaticFileSubstitution": "True",
    "Octopus.Action.Terraform.PlanJsonOutput": "False",
    "Octopus.Action.RunOnServer": "true",
    "Octopus.Action.Terraform.Template": "#region Provider\nterraform {\n  required_providers {\n    octopusdeploy = {\n      source = \"OctopusDeployLabs/octopusdeploy\"\n      version = \"0.21.1\"\n    }\n  }\n}\n\nvariable \"octopus_server\" {\n  type        = string\n  nullable    = false\n  sensitive   = false\n  description = \"The URL of the Octopus server e.g. https://myinstance.octopus.app.\"\n  default     = \"#{Octopus.Web.ServerUri}\"\n}\n\nvariable \"octopus_apikey\" {\n  type        = string\n  nullable    = false\n  sensitive   = true\n  description = \"The API key used to access the Octopus server. See https://octopus.com/docs/octopus-rest-api/how-to-create-an-api-key for details on creating an API key.\"\n}\n\nvariable \"octopus_space_id\" {\n  type        = string\n  nullable    = false\n  sensitive   = false\n  description = \"The ID of the Octopus space to populate.\"\n  default     = \"#{Octopus.Space.Id}\"\n}\n\nprovider \"octopusdeploy\" {\n  address  = var.octopus_server\n  api_key  = var.octopus_apikey\n  space_id = var.octopus_space_id\n}\n#endregion\n#region Locals\nlocals {\n  /*\n    You will need to edit:\n    * smoke_test_properties - depending on the step type, custom properties will need to be defined\n    * smoke_test_script - replace REPLACE THIS WITH CODE TO RETURN THE PUBLIC HOSTNAME with the appropriate logic\n    * cloud_account - this will need to be created in most cases\n    * security_scan_docker_script - the reference to the docker image deployed in earlier steps needs to be updated from #{Octopus.Action[Deploy Container].Package[web].PackageId}\n    * octopusdeploy_deployment_process - each of the sample application deployment processes (there are 3 defined in this template) needs to have the actual deployment step added\n  */\n\n  project_template_project_name             = \"Docker Project Templates\"\n  project_group_name                        = \"Azure Web App\"\n  infrastructure_project_name               = \"_ Azure Web App Infrastructure\"\n  infrastructure_project_description        = \"Runbooks to create and manage Azure Web Apps\"\n  infrastructure_runbook_name               = \"Create Web App\"\n  infrastructure_runbook_description        = \"Creates an Azure web app and the associated Octopus target\"\n  feedback_link                             = \"https://oc.to/CfiezA\"\n  octopub_frontend_project_name             = \"Azure WebApp Octopub Frontend\"\n  octopub_frontend_project_description      = \"Deploys the Octopub Frontend app to an Azure Web App target\"\n  octopub_products_project_name             = \"Azure WebApp Octopub Products\"\n  octopub_products_project_description      = \"Deploys the Octopub Products app to an Azure Web App target\"\n  octopub_audits_project_name               = \"Azure WebApp Octopub Audits\"\n  octopub_audits_project_description        = \"Deploys the Octopub Audits app to an Azure Web App target\"\n  octopub_orchestration_project_name        = \"_ Deploy Azure Web App Octopub Stack\"\n  octopub_orchestration_project_description = \"Deploys the full Octopub application stack\"\n  frontend_health_check                     = \"/index.html\"\n  products_health_check                     = \"/health/products\"\n  audits_health_check                       = \"/health/audits\"\n  target_role                               = \"Web App Reference Architecture\"\n  unique_prefix                             = \"#{Octopus.Web.ServerUri | Replace \\\"^https?://\\\" \\\"\\\" | Replace \\\"[^A-Za-z0-9]\\\" \\\"-\\\"}\"\n\n  // Use the example below for any accounts that might be included in this reference architecture\n  cloud_account = length(data.octopusdeploy_accounts.account.accounts) == 0 ? octopusdeploy_azure_service_principal.account[0].id : data.octopusdeploy_accounts.account.accounts[0].id\n\n  development_environment_id         = length(data.octopusdeploy_environments.environment_development.environments) == 0 ? octopusdeploy_environment.environment_development[0].id : data.octopusdeploy_environments.environment_development.environments[0].id\n  test_environment_id                = length(data.octopusdeploy_environments.environment_test.environments) == 0 ? octopusdeploy_environment.environment_test[0].id : data.octopusdeploy_environments.environment_test.environments[0].id\n  production_environment_id          = length(data.octopusdeploy_environments.environment_production.environments) == 0 ? octopusdeploy_environment.environment_production[0].id : data.octopusdeploy_environments.environment_production.environments[0].id\n  sync_environment_id                = length(data.octopusdeploy_environments.environment_sync.environments) == 0 ? octopusdeploy_environment.environment_sync[0].id : data.octopusdeploy_environments.environment_sync.environments[0].id\n  security_environment_id            = length(data.octopusdeploy_environments.environment_security.environments) == 0 ? octopusdeploy_environment.environment_security[0].id : data.octopusdeploy_environments.environment_security.environments[0].id\n  this_instance_library_variable_set = length(data.octopusdeploy_library_variable_sets.this_instance.library_variable_sets) == 0 ? octopusdeploy_library_variable_set.this_instance[0].id : data.octopusdeploy_library_variable_sets.this_instance.library_variable_sets[0].id\n  github_library_variable_set        = length(data.octopusdeploy_library_variable_sets.github.library_variable_sets) == 0 ? octopusdeploy_library_variable_set.github[0].id : data.octopusdeploy_library_variable_sets.github.library_variable_sets[0].id\n  docker_library_variable_set        = length(data.octopusdeploy_library_variable_sets.docker.library_variable_sets) == 0 ? octopusdeploy_library_variable_set.docker[0].id : data.octopusdeploy_library_variable_sets.docker.library_variable_sets[0].id\n  docker_hub_feed_id                 = length(data.octopusdeploy_feeds.dockerhub.feeds) == 0 ? octopusdeploy_docker_container_registry.docker_hub[0].id : data.octopusdeploy_feeds.dockerhub.feeds[0].id\n  github_feed_id                     = length(data.octopusdeploy_feeds.github_feed.feeds) == 0 ? octopusdeploy_github_repository_feed.github_feed[0].id : data.octopusdeploy_feeds.github_feed.feeds[0].id\n  worker_pool_id                     = length(data.octopusdeploy_worker_pools.workerpool_hosted_ubuntu.worker_pools) == 0 ? \"\" : data.octopusdeploy_worker_pools.workerpool_hosted_ubuntu.worker_pools[0].id\n  devops_lifecycle_id                = length(data.octopusdeploy_lifecycles.devsecops.lifecycles) == 0 ? octopusdeploy_lifecycle.lifecycle_devsecops[0].id : data.octopusdeploy_lifecycles.devsecops.lifecycles[0].id\n  project_group_id                   = length(data.octopusdeploy_project_groups.ra.project_groups) == 0 ? octopusdeploy_project_group.project_group_ra[0].id : data.octopusdeploy_project_groups.ra.project_groups[0].id\n  project_templates_project_group_id = length(data.octopusdeploy_project_groups.project_templates.project_groups) == 0 ? octopusdeploy_project_group.project_group_project_templates[0].id : data.octopusdeploy_project_groups.project_templates.project_groups[0].id\n  application_lifecycle_id           = length(data.octopusdeploy_lifecycles.application.lifecycles) == 0 ? octopusdeploy_lifecycle.lifecycle_application[0].id : data.octopusdeploy_lifecycles.application.lifecycles[0].id\n  smoke_test_container_image         = \"octopuslabs/azure-workertools\"\n  smoke_test_action_type             = \"Octopus.AzurePowerShell\"\n  smoke_test_properties              = {\n    \"Octopus.Action.RunOnServer\"         = \"true\"\n    \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n    \"Octopus.Action.Script.Syntax\"       = \"Bash\"\n    \"Octopus.Action.Script.ScriptBody\"   = local.smoke_test_script\n    \"OctopusUseBundledTooling\" : \"False\"\n    \"Octopus.Action.Azure.AccountId\" : local.cloud_account\n  }\n  link_highlight_container_image = \"octopuslabs/azure-workertools\"\n  link_highlight_action_type     = \"Octopus.AzurePowerShell\"\n  link_highlight_properties      = {\n    \"Octopus.Action.RunOnServer\"         = \"true\"\n    \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n    \"Octopus.Action.Script.Syntax\"       = \"Bash\"\n    \"Octopus.Action.Script.ScriptBody\"   = local.link_highlight_script\n    \"OctopusUseBundledTooling\" : \"False\"\n    \"Octopus.Action.Azure.AccountId\" : local.cloud_account\n  }\n\n  link_highlight_script = <<-EOT\n  write_highlight \"[https://#{Octopus.Action.Azure.WebAppName}.azurewebsites.net#{App.HealthCheck}](https://#{Octopus.Action.Azure.WebAppName}.azurewebsites.net#{App.HealthCheck})\"\n  EOT\n\n  feedback_script             = <<-EOT\n  Write-Highlight \"Please share your feedback on this step in our [GitHub discussion](${local.feedback_link}).\"\n  EOT\n  smoke_test_script           = <<-EOT\n  for i in {1..30}\n  do\n    HOSTNAME=#{Octopus.Action.Azure.WebAppName}.azurewebsites.net\n      if [[ -n \"$${HOSTNAME}\" ]]\n      then\n        break\n      fi\n      echo \"Waiting for ingress hostname\"\n      sleep 10\n  done\n\n\n  # Load balancers can take a minute or so before their DNS is propagated.\n  # A status code of 000 means curl could not resolve the DNS name, so we wait for a bit until DNS is updated.\n  echo \"Testing https://$${HOSTNAME}#{App.HealthCheck}\"\n  echo \"Waiting for DNS to propagate. This can take a while for a new load balancer.\"\n  for i in {1..30}\n  do\n    CODE=$(curl -o /dev/null -s -w \"%%{http_code}\\n\" https://$${HOSTNAME}#{App.HealthCheck})\n    if [[ \"$${CODE}\" == \"200\" ]]\n    then\n      break\n    fi\n    echo \"Waiting for DNS name to be resolvable and for service to respond\"\n    sleep 10\n  done\n\n  echo \"response code: $${CODE}\"\n  if [[ \"$${CODE}\" == \"200\" ]]\n  then\n      echo \"success\"\n      exit 0\n  else\n      echo \"error\"\n      exit 1\n  fi\n  EOT\n  security_scan_docker_script = <<-EOT\n  echo \"Pulling Trivy Docker Image\"\n  echo \"##octopus[stdout-verbose]\"\n  docker pull aquasec/trivy\n  echo \"##octopus[stdout-default]\"\n\n  echo \"Installing umoci\"\n  echo \"##octopus[stdout-verbose]\"\n  # Install umoci\n  if ! which umoci\n  then\n    curl -o umoci -L https://github.com/opencontainers/umoci/releases/latest/download/umoci.amd64 2>&1\n    chmod +x umoci\n  fi\n  echo \"##octopus[stdout-default]\"\n\n  DOCKERIMAGE=#{Octopus.Action[Deploy Container].Package.PackageId}\n  DOCKERTAG=#{Octopus.Action[Deploy Container].Package.PackageVersion}\n\n  echo \"Extracting Application Docker Image\"\n  echo \"##octopus[stdout-verbose]\"\n  # Download and extract the docker image\n  # https://manpages.ubuntu.com/manpages/jammy/man1/umoci-raw-unpack.1.html\n  docker pull quay.io/skopeo/stable:latest 2>&1\n  docker run -v $(pwd):/output quay.io/skopeo/stable:latest copy docker://$${DOCKERIMAGE}:$${DOCKERTAG} oci:/output/image:latest 2>&1\n  ./umoci unpack --image image --rootless bundle 2>&1\n  echo \"##octopus[stdout-default]\"\n\n  TIMESTAMP=$(date +%s%3N)\n  SUCCESS=0\n  for x in $(find . -name bom.json -type f -print); do\n      echo \"Scanning $${x}\"\n\n      # Delete any existing report file\n      if [[ -f \"$PWD/depscan-bom.json\" ]]; then\n        rm \"$PWD/depscan-bom.json\"\n      fi\n\n      # Generate the report, capturing the output, and ensuring $? is set to the exit code\n      OUTPUT=$(bash -c \"docker run --rm -v \\\"$PWD:/app\\\" aquasec/trivy sbom \\\"/app/$${x}\\\"; exit \\$?\" 2>&1)\n\n      # Success is set to 1 if the exit code is not zero\n      if [[ $? -ne 0 ]]; then\n          SUCCESS=1\n      fi\n\n      # Print the output stripped of ANSI colour codes\n      echo -e \"$${OUTPUT}\" | sed 's/\\x1b\\[[0-9;]*m//g'\n  done\n\n  set_octopusvariable \"VerificationResult\" $SUCCESS\n\n  if [[ $SUCCESS -ne 0 ]]; then\n    >&2 echo \"Critical vulnerabilities were detected\"\n  fi\n\n  exit 0\n  EOT\n}\n#endregion\n#region Environments\ndata \"octopusdeploy_environments\" \"environment_development\" {\n  ids          = null\n  partial_name = \"Development\"\n  skip         = 0\n  take         = 1\n}\n\nresource \"octopusdeploy_environment\" \"environment_development\" {\n  count                        = length(data.octopusdeploy_environments.environment_development.environments) == 0 ? 1 : 0\n  name                         = \"Development\"\n  description                  = \"\"\n  allow_dynamic_infrastructure = true\n  use_guided_failure           = true\n  sort_order                   = 10\n\n  jira_extension_settings {\n    environment_type = \"development\"\n  }\n\n  jira_service_management_extension_settings {\n    is_enabled = false\n  }\n\n  servicenow_extension_settings {\n    is_enabled = false\n  }\n}\n\ndata \"octopusdeploy_environments\" \"environment_test\" {\n  ids          = null\n  partial_name = \"Test\"\n  skip         = 0\n  take         = 1\n}\n\nresource \"octopusdeploy_environment\" \"environment_test\" {\n  count                        = length(data.octopusdeploy_environments.environment_test.environments) == 0 ? 1 : 0\n  name                         = \"Test\"\n  description                  = \"\"\n  allow_dynamic_infrastructure = true\n  use_guided_failure           = true\n  sort_order                   = 11\n\n  jira_extension_settings {\n    environment_type = \"testing\"\n  }\n\n  jira_service_management_extension_settings {\n    is_enabled = false\n  }\n\n  servicenow_extension_settings {\n    is_enabled = false\n  }\n}\n\ndata \"octopusdeploy_environments\" \"environment_production\" {\n  ids          = null\n  partial_name = \"Production\"\n  skip         = 0\n  take         = 1\n}\n\nresource \"octopusdeploy_environment\" \"environment_production\" {\n  count                        = length(data.octopusdeploy_environments.environment_production.environments) == 0 ? 1 : 0\n  name                         = \"Production\"\n  description                  = \"\"\n  allow_dynamic_infrastructure = true\n  use_guided_failure           = true\n  sort_order                   = 12\n\n  jira_extension_settings {\n    environment_type = \"production\"\n  }\n\n  jira_service_management_extension_settings {\n    is_enabled = false\n  }\n\n  servicenow_extension_settings {\n    is_enabled = false\n  }\n}\n\ndata \"octopusdeploy_environments\" \"environment_security\" {\n  ids          = null\n  partial_name = \"Security\"\n  skip         = 0\n  take         = 1\n}\n\nresource \"octopusdeploy_environment\" \"environment_security\" {\n  count                        = length(data.octopusdeploy_environments.environment_security.environments) == 0 ? 1 : 0\n  name                         = \"Security\"\n  description                  = \"\"\n  allow_dynamic_infrastructure = true\n  use_guided_failure           = false\n  sort_order                   = 14\n\n  jira_extension_settings {\n    environment_type = \"production\"\n  }\n\n  jira_service_management_extension_settings {\n    is_enabled = false\n  }\n\n  servicenow_extension_settings {\n    is_enabled = false\n  }\n}\n\ndata \"octopusdeploy_environments\" \"environment_sync\" {\n  ids          = null\n  partial_name = \"Sync\"\n  skip         = 0\n  take         = 1\n}\n\nresource \"octopusdeploy_environment\" \"environment_sync\" {\n  count                        = length(data.octopusdeploy_environments.environment_sync.environments) == 0 ? 1 : 0\n  name                         = \"Sync\"\n  description                  = \"\"\n  allow_dynamic_infrastructure = true\n  use_guided_failure           = false\n  sort_order                   = 15\n\n  jira_extension_settings {\n    environment_type = \"development\"\n  }\n\n  jira_service_management_extension_settings {\n    is_enabled = false\n  }\n\n  servicenow_extension_settings {\n    is_enabled = false\n  }\n}\n\ndata \"octopusdeploy_lifecycles\" \"devsecops\" {\n  ids          = []\n  partial_name = \"DevSecOps\"\n  skip         = 0\n  take         = 1\n}\n\ndata \"octopusdeploy_lifecycles\" \"application\" {\n  ids          = []\n  partial_name = \"Application\"\n  skip         = 0\n  take         = 1\n}\n\ndata \"octopusdeploy_lifecycles\" \"sync\" {\n  ids          = []\n  partial_name = \"Sync\"\n  skip         = 0\n  take         = 1\n}\n\nresource \"octopusdeploy_lifecycle\" \"sync\" {\n  count       = length(data.octopusdeploy_lifecycles.sync.lifecycles) == 0 ? 1 : 0\n  name        = \"Sync\"\n  description = \"\"\n\n  phase {\n    automatic_deployment_targets = []\n    optional_deployment_targets  = [\n      local.sync_environment_id\n    ]\n    name                                  = \"Sync\"\n    is_optional_phase                     = false\n    minimum_environments_before_promotion = 0\n  }\n\n  release_retention_policy {\n    quantity_to_keep    = 3\n    should_keep_forever = false\n    unit                = \"Days\"\n  }\n\n  tentacle_retention_policy {\n    quantity_to_keep    = 3\n    should_keep_forever = false\n    unit                = \"Days\"\n  }\n}\n\nresource \"octopusdeploy_lifecycle\" \"lifecycle_devsecops\" {\n  count       = length(data.octopusdeploy_lifecycles.devsecops.lifecycles) == 0 ? 1 : 0\n  name        = \"DevSecOps\"\n  description = \"\"\n\n  phase {\n    automatic_deployment_targets = []\n    optional_deployment_targets  = [\n      local.development_environment_id\n    ]\n    name                                  = \"Development\"\n    is_optional_phase                     = false\n    minimum_environments_before_promotion = 0\n  }\n  phase {\n    automatic_deployment_targets = []\n    optional_deployment_targets  = [\n      local.test_environment_id\n    ]\n    name                                  = \"Test\"\n    is_optional_phase                     = false\n    minimum_environments_before_promotion = 0\n  }\n  phase {\n    automatic_deployment_targets = []\n    optional_deployment_targets  = [\n      local.production_environment_id\n    ]\n    name                                  = \"Production\"\n    is_optional_phase                     = false\n    minimum_environments_before_promotion = 0\n  }\n  phase {\n    automatic_deployment_targets = [\n      local.security_environment_id\n    ]\n    optional_deployment_targets           = []\n    name                                  = \"Security\"\n    is_optional_phase                     = false\n    minimum_environments_before_promotion = 0\n  }\n\n  release_retention_policy {\n    quantity_to_keep    = 3\n    should_keep_forever = false\n    unit                = \"Days\"\n  }\n\n  tentacle_retention_policy {\n    quantity_to_keep    = 3\n    should_keep_forever = false\n    unit                = \"Days\"\n  }\n}\n\nresource \"octopusdeploy_lifecycle\" \"lifecycle_application\" {\n  count       = length(data.octopusdeploy_lifecycles.application.lifecycles) == 0 ? 1 : 0\n  name        = \"Application\"\n  description = \"\"\n\n  phase {\n    automatic_deployment_targets = []\n    optional_deployment_targets  = [\n      local.development_environment_id\n    ]\n    name                                  = \"Development\"\n    is_optional_phase                     = false\n    minimum_environments_before_promotion = 0\n  }\n  phase {\n    automatic_deployment_targets = []\n    optional_deployment_targets  = [\n      local.test_environment_id\n    ]\n    name                                  = \"Test\"\n    is_optional_phase                     = false\n    minimum_environments_before_promotion = 0\n  }\n  phase {\n    automatic_deployment_targets = []\n    optional_deployment_targets  = [\n      local.production_environment_id\n    ]\n    name                                  = \"Production\"\n    is_optional_phase                     = false\n    minimum_environments_before_promotion = 0\n  }\n\n  release_retention_policy {\n    quantity_to_keep    = 3\n    should_keep_forever = false\n    unit                = \"Days\"\n  }\n\n  tentacle_retention_policy {\n    quantity_to_keep    = 3\n    should_keep_forever = false\n    unit                = \"Days\"\n  }\n}\n#endregion\n#region Feeds\n\ndata \"octopusdeploy_feeds\" \"project\" {\n  feed_type = \"OctopusProject\"\n  ids       = []\n  skip      = 0\n  take      = 1\n}\n\ndata \"octopusdeploy_feeds\" \"bitnami\" {\n  feed_type    = \"Helm\"\n  ids          = []\n  partial_name = \"Bitnami\"\n  skip         = 0\n  take         = 1\n}\n\n\nresource \"octopusdeploy_helm_feed\" \"feed_helm\" {\n  count                                = length(data.octopusdeploy_feeds.bitnami.feeds) == 0 ? 1 : 0\n  name                                 = \"Bitnami\"\n  feed_uri                             = \"https://repo.vmware.com/bitnami-files/\"\n  package_acquisition_location_options = [\"ExecutionTarget\", \"NotAcquired\"]\n}\n\ndata \"octopusdeploy_feeds\" \"dockerhub\" {\n  feed_type    = \"Docker\"\n  ids          = []\n  partial_name = \"Docker Hub\"\n  skip         = 0\n  take         = 1\n}\n\nvariable \"feed_docker_hub_username\" {\n  type        = string\n  nullable    = false\n  sensitive   = true\n  description = \"The username used by the feed Docker Hub\"\n}\n\nvariable \"feed_docker_hub_password\" {\n  type        = string\n  nullable    = false\n  sensitive   = true\n  description = \"The password used by the feed Docker Hub\"\n}\n\nresource \"octopusdeploy_docker_container_registry\" \"docker_hub\" {\n  count                                = length(data.octopusdeploy_feeds.dockerhub.feeds) == 0 ? 1 : 0\n  name                                 = \"Docker Hub\"\n  password                             = var.feed_docker_hub_password\n  username                             = var.feed_docker_hub_username\n  api_version                          = \"v1\"\n  feed_uri                             = \"https://index.docker.io\"\n  package_acquisition_location_options = [\"ExecutionTarget\", \"NotAcquired\"]\n}\n\ndata \"octopusdeploy_feeds\" \"sales_maven_feed\" {\n  feed_type    = \"Maven\"\n  ids          = []\n  partial_name = \"Sales Maven Feed\"\n  skip         = 0\n  take         = 1\n}\n\nresource \"octopusdeploy_maven_feed\" \"feed_sales_maven_feed\" {\n  count                                = length(data.octopusdeploy_feeds.sales_maven_feed.feeds) == 0 ? 1 : 0\n  name                                 = \"Sales Maven Feed\"\n  feed_uri                             = \"https://octopus-sales-public-maven-repo.s3.ap-southeast-2.amazonaws.com/snapshot\"\n  package_acquisition_location_options = [\"Server\", \"ExecutionTarget\"]\n  download_attempts                    = 3\n  download_retry_backoff_seconds       = 20\n}\n\ndata \"octopusdeploy_feeds\" \"github_feed\" {\n  feed_type    = \"GitHub\"\n  ids          = []\n  partial_name = \"Github Releases\"\n  skip         = 0\n  take         = 1\n}\n\nresource \"octopusdeploy_github_repository_feed\" \"github_feed\" {\n  count                          = length(data.octopusdeploy_feeds.github_feed.feeds) == 0 ? 1 : 0\n  download_attempts              = 1\n  download_retry_backoff_seconds = 30\n  feed_uri                       = \"https://api.github.com\"\n  name                           = \"Github Releases\"\n}\n#endregion\n#region Library Variable Sets\ndata \"octopusdeploy_library_variable_sets\" \"this_instance\" {\n  partial_name = \"This Instance\"\n  skip         = 0\n  take         = 1\n}\n\nresource \"octopusdeploy_library_variable_set\" \"this_instance\" {\n  count       = length(data.octopusdeploy_library_variable_sets.this_instance.library_variable_sets) == 0 ? 1 : 0\n  name        = \"This Instance\"\n  description = \"Credentials used to interact with this Octopus instance\"\n}\n\nresource \"octopusdeploy_variable\" \"octopus_admin_api_key\" {\n  count           = length(data.octopusdeploy_library_variable_sets.this_instance.library_variable_sets) == 0 ? 1 : 0\n  name            = \"Octopus.ApiKey\"\n  type            = \"Sensitive\"\n  description     = \"Octopus API Key\"\n  is_sensitive    = true\n  is_editable     = true\n  owner_id        = octopusdeploy_library_variable_set.this_instance[0].id\n  sensitive_value = var.octopus_apikey\n}\n\ndata \"octopusdeploy_library_variable_sets\" \"github\" {\n  partial_name = \"GitHub\"\n  skip         = 0\n  take         = 1\n}\n\nresource \"octopusdeploy_library_variable_set\" \"github\" {\n  count       = length(data.octopusdeploy_library_variable_sets.github.library_variable_sets) == 0 ? 1 : 0\n  name        = \"GitHub\"\n  description = \"Credentials used to interact with GitHub\"\n}\n\nvariable \"github_access_token\" {\n  type        = string\n  nullable    = false\n  sensitive   = true\n  description = \"The GitHub access token\"\n}\n\nresource \"octopusdeploy_variable\" \"github_access_token\" {\n  count           = length(data.octopusdeploy_library_variable_sets.github.library_variable_sets) == 0 ? 1 : 0\n  name            = \"Git.Credentials.Password\"\n  type            = \"Sensitive\"\n  description     = \"The GitHub access token\"\n  is_sensitive    = true\n  is_editable     = true\n  owner_id        = octopusdeploy_library_variable_set.github[0].id\n  sensitive_value = var.github_access_token\n}\n\ndata \"octopusdeploy_library_variable_sets\" \"docker\" {\n  partial_name = \"Docker\"\n  skip         = 0\n  take         = 1\n}\n\nresource \"octopusdeploy_library_variable_set\" \"docker\" {\n  count       = length(data.octopusdeploy_library_variable_sets.docker.library_variable_sets) == 0 ? 1 : 0\n  name        = \"Docker\"\n  description = \"Credentials used to interact with Docker\"\n}\n\nresource \"octopusdeploy_variable\" \"docker_username\" {\n  count        = length(data.octopusdeploy_library_variable_sets.docker.library_variable_sets) == 0 ? 1 : 0\n  name         = \"Docker.Credentials.Username\"\n  type         = \"String\"\n  description  = \"The docker username\"\n  is_sensitive = false\n  is_editable  = true\n  owner_id     = octopusdeploy_library_variable_set.docker[0].id\n  value        = var.feed_docker_hub_username\n}\n\nresource \"octopusdeploy_variable\" \"docker_password\" {\n  count           = length(data.octopusdeploy_library_variable_sets.docker.library_variable_sets) == 0 ? 1 : 0\n  name            = \"Docker.Credentials.Password\"\n  type            = \"Sensitive\"\n  description     = \"The docker password\"\n  is_sensitive    = true\n  is_editable     = true\n  owner_id        = octopusdeploy_library_variable_set.docker[0].id\n  sensitive_value = var.feed_docker_hub_password\n}\n#endregion\n#region Accounts\n\ndata \"octopusdeploy_accounts\" \"account\" {\n  account_type = \"AzureServicePrincipal\"\n  partial_name = \"Azure\"\n  skip         = 0\n  take         = 1\n}\n\nvariable \"azure_account_application_id\" {\n  type        = string\n  nullable    = false\n  sensitive   = false\n  description = \"The Azure account application ID\"\n}\n\nvariable \"azure_account_subscription_id\" {\n  type        = string\n  nullable    = false\n  sensitive   = false\n  description = \"The Azure account subscription ID\"\n}\n\nvariable \"azure_account_tenant_id\" {\n  type        = string\n  nullable    = false\n  sensitive   = false\n  description = \"The Azure account tenant ID\"\n}\n\nvariable \"azure_account_password\" {\n  type        = string\n  nullable    = false\n  sensitive   = true\n  description = \"The Azure account password\"\n}\n\nresource \"octopusdeploy_azure_service_principal\" \"account\" {\n  count                             = length(data.octopusdeploy_accounts.account.accounts) == 0 ? 1 : 0\n  description                       = \"Azure Account\"\n  name                              = \"Azure\"\n  environments                      = []\n  tenants                           = []\n  tenanted_deployment_participation = \"Untenanted\"\n  application_id                    = var.azure_account_application_id\n  password                          = var.azure_account_password\n  subscription_id                   = var.azure_account_subscription_id\n  tenant_id                         = var.azure_account_tenant_id\n}\n\n#endregion\n#region Worker Pools\n\ndata \"octopusdeploy_worker_pools\" \"workerpool_hosted_ubuntu\" {\n  partial_name = \"Hosted Ubuntu\"\n  ids          = null\n  skip         = 0\n  take         = 1\n}\n#endregion\n#region Project Groups\ndata \"octopusdeploy_project_groups\" \"ra\" {\n  ids          = []\n  partial_name = local.project_group_name\n  skip         = 0\n  take         = 1\n}\n\nresource \"octopusdeploy_project_group\" \"project_group_ra\" {\n  count       = length(data.octopusdeploy_project_groups.ra.project_groups) == 0 ? 1 : 0\n  name        = local.project_group_name\n  description = \"${local.project_group_name} projects.\"\n}\n\ndata \"octopusdeploy_project_groups\" \"project_templates\" {\n  ids          = []\n  partial_name = \"Project Templates\"\n  skip         = 0\n  take         = 1\n}\n\nresource \"octopusdeploy_project_group\" \"project_group_project_templates\" {\n  count       = length(data.octopusdeploy_project_groups.project_templates.project_groups) == 0 ? 1 : 0\n  name        = \"Project Templates\"\n  description = \"Sample code project generators\"\n}\n#endregion\n\n#region Projects\n\n#region Infrastructure Project\nvariable \"infrastructure_project_name\" {\n  type    = string\n  default = \"\"\n}\n\n\ndata \"octopusdeploy_projects\" \"infrastructure\" {\n  partial_name = var.infrastructure_project_name == \"\" ? local.infrastructure_project_name : var.infrastructure_project_name\n  skip         = 0\n  take         = 1\n}\n\nresource \"octopusdeploy_variable\" \"azure_account\" {\n  count       = length(data.octopusdeploy_projects.infrastructure.projects) == 0 ? 1 : 0\n  name        = \"Azure.Account\"\n  type        = \"AzureAccount\"\n  description = \"The Azure account used to create the web app infrastructure\"\n  value       = local.cloud_account\n  owner_id    = octopusdeploy_project.infrastructure[0].id\n}\n\nresource \"octopusdeploy_project\" \"infrastructure\" {\n  count                                = length(data.octopusdeploy_projects.infrastructure.projects) == 0 ? 1 : 0\n  name                                 = var.infrastructure_project_name == \"\" ? local.infrastructure_project_name : var.infrastructure_project_name\n  auto_create_release                  = false\n  default_guided_failure_mode          = \"EnvironmentDefault\"\n  default_to_skip_if_already_installed = false\n  discrete_channel_release             = false\n  is_disabled                          = false\n  is_version_controlled                = true\n  lifecycle_id                         = local.devops_lifecycle_id\n  project_group_id                     = local.project_group_id\n  included_library_variable_sets       = []\n  tenanted_deployment_participation    = \"Untenanted\"\n\n  connectivity_policy {\n    allow_deployments_to_no_targets = true\n    exclude_unhealthy_targets       = false\n    skip_machine_behavior           = \"None\"\n  }\n\n  versioning_strategy {\n    template = \"#{Octopus.Version.LastMajor}.#{Octopus.Version.LastMinor}.#{Octopus.Version.NextPatch}\"\n  }\n\n  lifecycle {\n    ignore_changes = [connectivity_policy]\n  }\n  description = local.infrastructure_project_description\n}\n\nresource \"octopusdeploy_runbook\" \"runbook_create_infrastructure\" {\n  count             = length(data.octopusdeploy_projects.infrastructure.projects) == 0 ? 1 : 0\n  name              = local.infrastructure_runbook_name\n  project_id        = octopusdeploy_project.infrastructure[0].id\n  environment_scope = \"Specified\"\n  environments      = [\n    local.development_environment_id,\n    local.test_environment_id,\n    local.production_environment_id,\n  ]\n  force_package_download      = false\n  default_guided_failure_mode = \"EnvironmentDefault\"\n  description                 = local.infrastructure_runbook_description\n  multi_tenancy_mode          = \"Untenanted\"\n\n  retention_policy {\n    quantity_to_keep    = 100\n    should_keep_forever = false\n  }\n\n  connectivity_policy {\n    allow_deployments_to_no_targets = true\n    exclude_unhealthy_targets       = false\n    skip_machine_behavior           = \"None\"\n  }\n}\n\nresource \"octopusdeploy_runbook_process\" \"runbook_process_runbook_create_infrastructure\" {\n  count      = length(data.octopusdeploy_projects.infrastructure.projects) == 0 ? 1 : 0\n  runbook_id = octopusdeploy_runbook.runbook_create_infrastructure[0].id\n\n  step {\n    condition           = \"Success\"\n    name                = \"Generate Variables\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Generate Variables\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = \"${data.octopusdeploy_worker_pools.workerpool_hosted_ubuntu.worker_pools[0].id}\"\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = \"Set-OctopusVariable -name \\\"OctopusEnvironmentName\\\" -value $OctopusParameters[\\\"Octopus.Environment.Name\\\"]\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n\n  step {\n    condition           = \"Success\"\n    name                = \"Create Resource Group If Not Exists (AZ Module)\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.AzurePowerShell\"\n      name                               = \"Create Resource Group If Not Exists (AZ Module)\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = true\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.Script.ScriptSource\"              = \"Inline\"\n        \"CreateResourceGroup.ResourceGroup.Location.Abbr\" = \"australiasoutheast\"\n        \"Octopus.Action.Script.ScriptBody\"                = \"$resourceGroupName = $OctopusParameters[\\\"CreateResourceGroup.ResourceGroup.Name\\\"]\\n$resourceGroupLocationAbbr = $OctopusParameters[\\\"CreateResourceGroup.ResourceGroup.Location.Abbr\\\"]\\n\\n$existingResourceGroups = (az group list --query \\\"[?location=='$resourceGroupLocationAbbr']\\\") | ConvertFrom-JSON\\n\\n$createResourceGroup = $true\\nforeach ($resourceGroupFound in $existingResourceGroups)\\n{\\t\\n\\tWrite-Host \\\"Checking if current resource group $($resourceGroupFound.name) matches $resourceGroupName\\\"\\n    if ($resourceGroupFound.name -eq $resourceGroupName)\\n    {\\n    \\t$createResourceGroup = $false\\n    \\tWrite-Highlight \\\"Resource group already exists, skipping creation\\\"\\n    \\tbreak\\n    }\\n}\\n\\nif ($createResourceGroup)\\n{\\n\\tWrite-Host \\\"Creating the $resourceGroupName because it was not found in $resourceGroupLocationAbbr\\\"\\n\\taz group create -l $resourceGroupLocationAbbr -n $resourceGroupName\\n}\"\n        \"Octopus.Action.RunOnServer\"                      = \"true\"\n        \"Octopus.Action.Script.Syntax\"                    = \"PowerShell\"\n        \"Octopus.Action.Azure.AccountId\"                  = \"#{CreateResourceGroup.Azure.Account}\"\n        \"CreateResourceGroup.Azure.Account\"               = \"Azure.Account\"\n        \"CreateResourceGroup.ResourceGroup.Name\"          = \"octopub-#{Octopus.Action[Generate Variables].Output.OctopusEnvironmentName | ToLower}\"\n        \"OctopusUseBundledTooling\"                        = \"False\"\n      }\n\n      container {\n        feed_id = local.docker_hub_feed_id\n        image   = \"octopuslabs/azure-workertools\"\n      }\n\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n  step {\n    condition           = \"Success\"\n    name                = \"Create App Service Plan\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.AzureResourceGroup\"\n      name                               = \"Create App Service Plan\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.Azure.ResourceGroupDeploymentMode\"     = \"Incremental\"\n        \"Octopus.Action.Azure.TemplateSource\"                  = \"Inline\"\n        \"Octopus.Action.Azure.ResourceGroupTemplateParameters\" = jsonencode({\n          \"environment\" = {\n            \"value\" = \"#{Octopus.Action[Generate Variables].Output.OctopusEnvironmentName | ToLower}\"\n          }\n          \"projectName\" = {\n            \"value\" = \"octopub\"\n          }\n          \"appServiceSku\" = {\n            \"value\" = \"B2\"\n          }\n        })\n        \"Octopus.Action.Azure.ResourceGroupTemplate\" = jsonencode({\n          \"parameters\" = {\n            \"environment\" = {\n              \"type\" = \"string\"\n            }\n            \"projectName\" = {\n              \"type\" = \"string\"\n            }\n            \"appServiceSku\" = {\n              \"type\"         = \"string\"\n              \"defaultValue\" = \"B2\"\n              \"metadata\"     = {\n                \"description\" = \"The SKU of App Service Plan\"\n              }\n            }\n          }\n          \"variables\" = {\n            \"appServicePlanName\" = \"[concat(parameters('projectName'), '-', parameters('environment'),'-hosting')]\"\n          }\n          \"resources\" = [\n            {\n              \"kind\"       = \"linux\"\n              \"location\"   = \"[resourceGroup().location]\"\n              \"properties\" = {\n                \"reserved\" = \"true\"\n              }\n              \"dependsOn\" = []\n              \"sku\"       = {\n                \"name\" = \"[parameters('appServiceSku')]\"\n              }\n              \"apiVersion\" = \"2017-08-01\"\n              \"type\"       = \"Microsoft.Web/serverfarms\"\n              \"name\"       = \"[variables('appServicePlanName')]\"\n              \"comments\"   = \"This app service plan is used for the web app and slots.\"\n            },\n          ]\n          \"outputs\" = {\n            \"appServicePlan\" = {\n              \"type\"  = \"string\"\n              \"value\" = \"[resourceId('Microsoft.Web/serverfarms', variables('appServicePlanName'))]\"\n            }\n          }\n          \"$schema\"        = \"https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#\"\n          \"contentVersion\" = \"1.0.0.0\"\n        })\n        \"Octopus.Action.Azure.AccountId\"         = local.cloud_account\n        \"Octopus.Action.Azure.ResourceGroupName\" = \"octopub-#{Octopus.Action[Generate Variables].Output.OctopusEnvironmentName | ToLower}\"\n        \"Octopus.Action.RunOnServer\"             = \"true\"\n        \"OctopusUseBundledTooling\"               = \"False\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n  step {\n    condition           = \"Success\"\n    name                = \"Create Frontend Web App Service\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.AzureResourceGroup\"\n      name                               = \"Create Frontend Web App Service\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.Azure.ResourceGroupTemplateParameters\" = jsonencode({\n          \"environment\" = {\n            \"value\" = \"#{Octopus.Action[Generate Variables].Output.OctopusEnvironmentName | ToLower}\"\n          }\n          \"projectName\" = {\n            \"value\" = \"octopubfrontend\"\n          }\n          \"uniquePrefix\" = {\n            \"value\" = local.unique_prefix\n          }\n          \"appServicePlanId\" = {\n            \"value\" = \"#{Octopus.Action[Create App Service Plan].Output.AzureRmOutputs[appServicePlan]}\"\n          }\n          \"dockerImageName\" = {\n            \"value\" = \"nginx:latest\"\n          }\n          \"resourceTags\" = {\n            \"value\" = {\n              \"octopus-environment\" = \"#{Octopus.Action[Generate Variables].Output.OctopusEnvironmentName}\"\n              \"octopus-role\"        = \"${local.target_role} Frontend\"\n              \"octopus-space\"       = \"#{Octopus.Space.Name}\"\n              \"octopus-project\"     = \"Azure WebApp Octopub Frontend\"\n            }\n          }\n        })\n        \"Octopus.Action.Azure.ResourceGroupTemplate\" = jsonencode({\n          \"resources\" = [\n            {\n              \"apiVersion\" = \"2016-08-01\"\n              \"name\"       = \"[variables('webAppPortalName')]\"\n              \"kind\"       = \"app,linux,container\"\n              \"location\"   = \"[resourceGroup().location]\"\n              \"tags\"       = \"[parameters('resourceTags')]\"\n              \"dependsOn\"  = []\n              \"properties\" = {\n                \"name\"       = \"[variables('webAppPortalName')]\"\n                \"siteConfig\" = {\n                  \"linuxFxVersion\" = \"[concat('DOCKER|', parameters('dockerImageName'))]\"\n                  \"alwaysOn\"       = \"true\"\n                }\n                \"serverFarmId\" = \"[parameters('appServicePlanId')]\"\n              }\n              \"type\" = \"Microsoft.Web/sites\"\n            },\n          ]\n          \"$schema\"        = \"https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#\"\n          \"contentVersion\" = \"1.0.0.0\"\n          \"parameters\"     = {\n            \"environment\" = {\n              \"type\" = \"string\"\n            }\n            \"projectName\" = {\n              \"type\" = \"string\"\n            }\n            \"uniquePrefix\" = {\n              \"defaultValue\" = local.unique_prefix\n              \"type\"         = \"string\"\n            }\n            \"appServicePlanId\" = {\n              \"type\"         = \"string\"\n              \"defaultValue\" = \"#{Octopus.Action[Create App Service Plan].Output.AzureRmOutputs[appServicePlan]}\"\n            }\n            \"dockerImageName\" = {\n              \"type\"         = \"string\"\n              \"defaultValue\" = \"nginx:latest\"\n            }\n            \"resourceTags\" = {\n              \"type\"         = \"object\"\n              \"defaultValue\" = {\n                \"octopus-environment\" = \"#{Octopus.Action[Generate Variables].Output.OctopusEnvironmentName}\"\n                \"octopus-role\"        = \"${local.target_role} Frontend\"\n                \"octopus-space\"       = \"#{Octopus.Space.Name}\"\n                \"octopus-project\"     = \"\"\n              }\n            }\n          }\n          \"variables\" = {\n            \"webAppPortalName\" = \"[concat(parameters('uniquePrefix'), '-', parameters('projectName'), '-', parameters('environment'), '-webapp')]\"\n          }\n        })\n        \"Octopus.Action.Azure.AccountId\"                   = local.cloud_account\n        \"Octopus.Action.Azure.ResourceGroupName\"           = \"octopub-#{Octopus.Action[Generate Variables].Output.OctopusEnvironmentName | ToLower}\"\n        \"Octopus.Action.RunOnServer\"                       = \"true\"\n        \"OctopusUseBundledTooling\"                         = \"False\"\n        \"Octopus.Action.Azure.ResourceGroupDeploymentMode\" = \"Incremental\"\n        \"Octopus.Action.Azure.TemplateSource\"              = \"Inline\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n\n  step {\n    condition           = \"Success\"\n    name                = \"Create Products Microservice App Service\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.AzureResourceGroup\"\n      name                               = \"Create Products Microservice App Service\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.Azure.ResourceGroupTemplateParameters\" = jsonencode({\n          \"environment\" = {\n            \"value\" = \"#{Octopus.Action[Generate Variables].Output.OctopusEnvironmentName | ToLower}\"\n          }\n          \"projectName\" = {\n            \"value\" = \"octopubproducts\"\n          }\n          \"uniquePrefix\" = {\n            \"value\" = local.unique_prefix\n          }\n          \"appServicePlanId\" = {\n            \"value\" = \"#{Octopus.Action[Create App Service Plan].Output.AzureRmOutputs[appServicePlan]}\"\n          }\n          \"dockerImageName\" = {\n            \"value\" = \"nginx:latest\"\n          }\n          \"resourceTags\" = {\n            \"value\" = {\n              \"octopus-environment\" = \"#{Octopus.Action[Generate Variables].Output.OctopusEnvironmentName}\"\n              \"octopus-role\"        = \"${local.target_role} Products\"\n              \"octopus-space\"       = \"#{Octopus.Space.Name}\"\n              \"octopus-project\"     = \"Azure WebApp Octopub Products\"\n            }\n          }\n        })\n        \"Octopus.Action.Azure.ResourceGroupTemplate\" = jsonencode({\n          \"resources\" = [\n            {\n              \"apiVersion\" = \"2016-08-01\"\n              \"name\"       = \"[variables('webAppPortalName')]\"\n              \"kind\"       = \"app,linux,container\"\n              \"location\"   = \"[resourceGroup().location]\"\n              \"tags\"       = \"[parameters('resourceTags')]\"\n              \"dependsOn\"  = []\n              \"properties\" = {\n                \"name\"       = \"[variables('webAppPortalName')]\"\n                \"siteConfig\" = {\n                  \"linuxFxVersion\" = \"[concat('DOCKER|', parameters('dockerImageName'))]\"\n                  \"alwaysOn\"       = \"true\"\n                }\n                \"serverFarmId\" = \"[parameters('appServicePlanId')]\"\n              }\n              \"type\" = \"Microsoft.Web/sites\"\n            },\n          ]\n          \"$schema\"        = \"https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#\"\n          \"contentVersion\" = \"1.0.0.0\"\n          \"parameters\"     = {\n            \"environment\" = {\n              \"type\" = \"string\"\n            }\n            \"projectName\" = {\n              \"type\" = \"string\"\n            }\n            \"uniquePrefix\" = {\n              \"defaultValue\" = local.unique_prefix\n              \"type\"         = \"string\"\n            }\n            \"appServicePlanId\" = {\n              \"type\"         = \"string\"\n              \"defaultValue\" = \"#{Octopus.Action[Create App Service Plan].Output.AzureRmOutputs[appServicePlan]}\"\n            }\n            \"dockerImageName\" = {\n              \"type\"         = \"string\"\n              \"defaultValue\" = \"nginx:latest\"\n            }\n            \"resourceTags\" = {\n              \"type\"         = \"object\"\n              \"defaultValue\" = {\n                \"octopus-environment\" = \"#{Octopus.Action[Generate Variables].Output.OctopusEnvironmentName}\"\n                \"octopus-role\"        = \"${local.target_role} Products\"\n                \"octopus-space\"       = \"#{Octopus.Space.Name}\"\n                \"octopus-project\"     = \"\"\n              }\n            }\n          }\n          \"variables\" = {\n            \"webAppPortalName\" = \"[concat(parameters('uniquePrefix'), '-', parameters('projectName'), '-', parameters('environment'), '-webapp')]\"\n          }\n        })\n        \"Octopus.Action.Azure.AccountId\"                   = local.cloud_account\n        \"Octopus.Action.Azure.ResourceGroupName\"           = \"octopub-#{Octopus.Action[Generate Variables].Output.OctopusEnvironmentName | ToLower}\"\n        \"Octopus.Action.RunOnServer\"                       = \"true\"\n        \"OctopusUseBundledTooling\"                         = \"False\"\n        \"Octopus.Action.Azure.ResourceGroupDeploymentMode\" = \"Incremental\"\n        \"Octopus.Action.Azure.TemplateSource\"              = \"Inline\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n\n  step {\n    condition           = \"Success\"\n    name                = \"Create Audits Microservice App Service\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.AzureResourceGroup\"\n      name                               = \"Create Audits Microservice App Service\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.Azure.ResourceGroupTemplateParameters\" = jsonencode({\n          \"environment\" = {\n            \"value\" = \"#{Octopus.Action[Generate Variables].Output.OctopusEnvironmentName | ToLower}\"\n          }\n          \"projectName\" = {\n            \"value\" = \"octopubaudits\"\n          }\n          \"uniquePrefix\" = {\n            \"value\" = local.unique_prefix\n          }\n          \"appServicePlanId\" = {\n            \"value\" = \"#{Octopus.Action[Create App Service Plan].Output.AzureRmOutputs[appServicePlan]}\"\n          }\n          \"dockerImageName\" = {\n            \"value\" = \"nginx:latest\"\n          }\n          \"resourceTags\" = {\n            \"value\" = {\n              \"octopus-environment\" = \"#{Octopus.Action[Generate Variables].Output.OctopusEnvironmentName}\"\n              \"octopus-role\"        = \"${local.target_role} Audits\"\n              \"octopus-space\"       = \"#{Octopus.Space.Name}\"\n              \"octopus-project\"     = \"Azure WebApp Octopub Audits\"\n            }\n          }\n        })\n        \"Octopus.Action.Azure.ResourceGroupTemplate\" = jsonencode({\n          \"resources\" = [\n            {\n              \"apiVersion\" = \"2016-08-01\"\n              \"name\"       = \"[variables('webAppPortalName')]\"\n              \"kind\"       = \"app,linux,container\"\n              \"location\"   = \"[resourceGroup().location]\"\n              \"tags\"       = \"[parameters('resourceTags')]\"\n              \"dependsOn\"  = []\n              \"properties\" = {\n                \"name\"       = \"[variables('webAppPortalName')]\"\n                \"siteConfig\" = {\n                  \"linuxFxVersion\" = \"[concat('DOCKER|', parameters('dockerImageName'))]\"\n                  \"alwaysOn\"       = \"true\"\n                }\n                \"serverFarmId\" = \"[parameters('appServicePlanId')]\"\n              }\n              \"type\" = \"Microsoft.Web/sites\"\n            },\n          ]\n          \"$schema\"        = \"https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#\"\n          \"contentVersion\" = \"1.0.0.0\"\n          \"parameters\"     = {\n            \"environment\" = {\n              \"type\" = \"string\"\n            }\n            \"projectName\" = {\n              \"type\" = \"string\"\n            }\n            \"uniquePrefix\" = {\n              \"defaultValue\" = local.unique_prefix\n              \"type\"         = \"string\"\n            }\n            \"appServicePlanId\" = {\n              \"type\"         = \"string\"\n              \"defaultValue\" = \"#{Octopus.Action[Create App Service Plan].Output.AzureRmOutputs[appServicePlan]}\"\n            }\n            \"dockerImageName\" = {\n              \"type\"         = \"string\"\n              \"defaultValue\" = \"nginx:latest\"\n            }\n            \"resourceTags\" = {\n              \"type\"         = \"object\"\n              \"defaultValue\" = {\n                \"octopus-environment\" = \"#{Octopus.Action[Generate Variables].Output.OctopusEnvironmentName}\"\n                \"octopus-role\"        = \"${local.target_role} Audits\"\n                \"octopus-space\"       = \"#{Octopus.Space.Name}\"\n                \"octopus-project\"     = \"\"\n              }\n            }\n          }\n          \"variables\" = {\n            \"webAppPortalName\" = \"[concat(parameters('uniquePrefix'), '-', parameters('projectName'), '-', parameters('environment'), '-webapp')]\"\n          }\n        })\n        \"Octopus.Action.Azure.AccountId\"                   = local.cloud_account\n        \"Octopus.Action.Azure.ResourceGroupName\"           = \"octopub-#{Octopus.Action[Generate Variables].Output.OctopusEnvironmentName | ToLower}\"\n        \"Octopus.Action.RunOnServer\"                       = \"true\"\n        \"OctopusUseBundledTooling\"                         = \"False\"\n        \"Octopus.Action.Azure.ResourceGroupDeploymentMode\" = \"Incremental\"\n        \"Octopus.Action.Azure.TemplateSource\"              = \"Inline\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n\n  step {\n    condition           = \"Always\"\n    name                = \"Feedback\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Feedback\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = local.feedback_script\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n}\n#endregion\n\n#region Octopub Frontend Project\nvariable \"frontend_project_name\" {\n  type    = string\n  default = \"\"\n}\n\ndata \"octopusdeploy_projects\" \"frontend\" {\n  partial_name = var.frontend_project_name == \"\" ? local.octopub_frontend_project_name : var.frontend_project_name\n  skip         = 0\n  take         = 1\n}\n\nresource \"octopusdeploy_variable\" \"frontend_health_check\" {\n  count        = length(data.octopusdeploy_projects.frontend.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.frontend[0].id\n  value        = local.frontend_health_check\n  name         = \"App.HealthCheck\"\n  type         = \"String\"\n  description  = \"The path to perform a health check on.\"\n  is_sensitive = false\n  depends_on   = []\n}\n\nresource \"octopusdeploy_variable\" \"azure_webapp_octopub_frontend_octopus_azure_account\" {\n  count        = length(data.octopusdeploy_projects.frontend.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.frontend[0].id\n  value        = local.cloud_account\n  name         = \"Octopus.Azure.Account\"\n  type         = \"AzureAccount\"\n  description  = \"\"\n  is_sensitive = false\n}\n\nresource \"octopusdeploy_project\" \"frontend\" {\n  count                                = length(data.octopusdeploy_projects.frontend.projects) == 0 ? 1 : 0\n  name                                 = var.frontend_project_name == \"\" ? local.octopub_frontend_project_name : var.frontend_project_name\n  auto_create_release                  = false\n  default_guided_failure_mode          = \"EnvironmentDefault\"\n  default_to_skip_if_already_installed = false\n  discrete_channel_release             = false\n  is_disabled                          = false\n  is_version_controlled                = true\n  lifecycle_id                         = local.devops_lifecycle_id\n  project_group_id                     = local.project_group_id\n  included_library_variable_sets       = []\n  tenanted_deployment_participation    = \"Untenanted\"\n\n  connectivity_policy {\n    allow_deployments_to_no_targets = true\n    exclude_unhealthy_targets       = false\n    skip_machine_behavior           = \"None\"\n  }\n\n  versioning_strategy {\n    template = \"#{Octopus.Version.LastMajor}.#{Octopus.Version.LastMinor}.#{Octopus.Version.NextPatch}\"\n  }\n\n  lifecycle {\n    ignore_changes = [connectivity_policy]\n  }\n  description = local.octopub_frontend_project_description\n}\n\nresource \"octopusdeploy_deployment_process\" \"frontend\" {\n  count      = length(data.octopusdeploy_projects.frontend.projects) == 0 ? 1 : 0\n  project_id = octopusdeploy_project.frontend[0].id\n\n  step {\n    condition           = \"Success\"\n    name                = \"Generate Variables\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Generate Variables\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = \"${data.octopusdeploy_worker_pools.workerpool_hosted_ubuntu.worker_pools[0].id}\"\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = \"Set-OctopusVariable -name \\\"OctopusEnvironmentName\\\" -value $OctopusParameters[\\\"Octopus.Environment.Name\\\"]\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n\n  // The deployment step goes here.\n  // Call the step \"Deploy Container\"\n\n  step {\n    condition           = \"Success\"\n    name                = \"Deploy Container\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.AzureAppService\"\n      name                               = \"Deploy Container\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = true\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"                = \"true\"\n        \"OctopusUseBundledTooling\"                  = \"False\"\n        \"Octopus.Action.Azure.DeploymentType\"       = \"Container\"\n        \"Octopus.Action.Package.DownloadOnTentacle\" = \"False\"\n        \"Octopus.Action.Azure.AppSettings\"          = jsonencode([\n          {\n            \"name\"        = \"UDL_SETVALUE_1\"\n            \"value\"       = \"[/usr/share/nginx/html/config.json][productEndpoint]https://${local.unique_prefix}-octopubproducts-#{Octopus.Action[Generate Variables].Output.OctopusEnvironmentName | ToLower}-webapp.azurewebsites.net/api/products\"\n            \"slotSetting\" = \"false\"\n          },\n          {\n            \"name\"        = \"UDL_SETVALUE_2\"\n            \"value\"       = \"[/usr/share/nginx/html/config.json][productHealthEndpoint]https://${local.unique_prefix}-octopubproducts-#{Octopus.Action[Generate Variables].Output.OctopusEnvironmentName | ToLower}-webapp.azurewebsites.net/health/products\"\n            \"slotSetting\" = \"false\"\n          },\n          {\n            \"name\"        = \"UDL_SETVALUE_3\"\n            \"value\"       = \"[/usr/share/nginx/html/config.json][auditEndpoint]https://${local.unique_prefix}-octopubaudits-#{Octopus.Action[Generate Variables].Output.OctopusEnvironmentName | ToLower}-webapp.azurewebsites.net/api/audits\"\n            \"slotSetting\" = \"false\"\n          },\n          {\n            \"name\"        = \"UDL_SETVALUE_4\"\n            \"value\"       = \"[/usr/share/nginx/html/config.json][auditHealthEndpoint]https://${local.unique_prefix}-octopubaudits-#{Octopus.Action[Generate Variables].Output.OctopusEnvironmentName | ToLower}-webapp.azurewebsites.net/health/audits\"\n            \"slotSetting\" = \"false\"\n          }\n        ])\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n\n      primary_package {\n        package_id           = \"octopussamples/octopub-frontend\"\n        acquisition_location = \"NotAcquired\"\n        feed_id              = local.docker_hub_feed_id\n        properties           = { SelectionMode = \"immediate\" }\n      }\n\n      features = []\n    }\n\n    properties   = {}\n    target_roles = [\"${local.target_role} Frontend\"]\n  }\n\n  step {\n    condition           = \"Success\"\n    name                = \"Service Link\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type = local.link_highlight_action_type\n      properties  = local.link_highlight_properties\n      container {\n        feed_id = local.docker_hub_feed_id\n        image   = local.link_highlight_container_image\n      }\n      name                               = \"Service Link\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      environments                       = []\n      excluded_environments              = []\n      channels                           = []\n      tenant_tags                        = []\n      features                           = []\n    }\n\n    properties   = {}\n    target_roles = [\"${local.target_role} Frontend\"]\n  }\n\n  step {\n    condition           = \"Success\"\n    name                = \"Smoke Test\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = local.smoke_test_action_type\n      name                               = \"Smoke Test\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = local.smoke_test_properties\n      container {\n        feed_id = local.docker_hub_feed_id\n        image   = local.smoke_test_container_image\n      }\n      environments = [\n        local.development_environment_id,\n        local.test_environment_id,\n        local.production_environment_id,\n      ]\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = [\"${local.target_role} Frontend\"]\n  }\n\n  step {\n    condition           = \"Success\"\n    name                = \"Security Scan\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Security Scan\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = true\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"Bash\"\n        \"Octopus.Action.Script.ScriptBody\"   = local.security_scan_docker_script\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n\n  step {\n    condition           = \"Always\"\n    name                = \"Feedback\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Feedback\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = local.feedback_script\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n}\n\n#endregion\n\n#region Octopub Products Project\nvariable \"products_project_name\" {\n  type    = string\n  default = \"\"\n}\n\n\ndata \"octopusdeploy_projects\" \"products\" {\n  partial_name = var.products_project_name == \"\" ? local.octopub_products_project_name : var.products_project_name\n  skip         = 0\n  take         = 1\n}\n\nresource \"octopusdeploy_variable\" \"azure_webapp_octopub_products_octopus_azure_account\" {\n  count        = length(data.octopusdeploy_projects.products.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.products[0].id\n  value        = local.cloud_account\n  name         = \"Octopus.Azure.Account\"\n  type         = \"AzureAccount\"\n  description  = \"\"\n  is_sensitive = false\n}\n\nresource \"octopusdeploy_variable\" \"products_health_check\" {\n  count        = length(data.octopusdeploy_projects.products.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.products[0].id\n  value        = local.products_health_check\n  name         = \"App.HealthCheck\"\n  type         = \"String\"\n  description  = \"The path to perform a health check on.\"\n  is_sensitive = false\n  depends_on   = []\n}\n\nresource \"octopusdeploy_project\" \"products\" {\n  count                                = length(data.octopusdeploy_projects.products.projects) == 0 ? 1 : 0\n  name                                 = var.products_project_name == \"\" ? local.octopub_products_project_name : var.products_project_name\n  auto_create_release                  = false\n  default_guided_failure_mode          = \"EnvironmentDefault\"\n  default_to_skip_if_already_installed = false\n  discrete_channel_release             = false\n  is_disabled                          = false\n  is_version_controlled                = true\n  lifecycle_id                         = local.devops_lifecycle_id\n  project_group_id                     = local.project_group_id\n  included_library_variable_sets       = []\n  tenanted_deployment_participation    = \"Untenanted\"\n\n  connectivity_policy {\n    allow_deployments_to_no_targets = true\n    exclude_unhealthy_targets       = false\n    skip_machine_behavior           = \"None\"\n  }\n\n  versioning_strategy {\n    template = \"#{Octopus.Version.LastMajor}.#{Octopus.Version.LastMinor}.#{Octopus.Version.NextPatch}\"\n  }\n\n  lifecycle {\n    ignore_changes = [connectivity_policy]\n  }\n  description = local.octopub_products_project_description\n}\n\nresource \"octopusdeploy_deployment_process\" \"products\" {\n  count      = length(data.octopusdeploy_projects.products.projects) == 0 ? 1 : 0\n  project_id = octopusdeploy_project.products[0].id\n\n  step {\n    condition           = \"Success\"\n    name                = \"Generate Variables\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Generate Variables\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = \"${data.octopusdeploy_worker_pools.workerpool_hosted_ubuntu.worker_pools[0].id}\"\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = \"Set-OctopusVariable -name \\\"OctopusEnvironmentName\\\" -value $OctopusParameters[\\\"Octopus.Environment.Name\\\"]\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n\n  // The deployment step goes here.\n  // Call the step \"Deploy Container\"\n\n  step {\n    condition           = \"Success\"\n    name                = \"Deploy Container\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.AzureAppService\"\n      name                               = \"Deploy Container\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = true\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"                = \"true\"\n        \"OctopusUseBundledTooling\"                  = \"False\"\n        \"Octopus.Action.Azure.DeploymentType\"       = \"Container\"\n        \"Octopus.Action.Package.DownloadOnTentacle\" = \"False\"\n        \"Octopus.Action.Azure.AppSettings\"          = jsonencode([\n          {\n            \"name\"        = \"WEBSITES_PORT\"\n            \"value\"       = \"8083\"\n            \"slotSetting\" = \"false\"\n          }\n        ])\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n\n      primary_package {\n        package_id           = \"octopussamples/octopub-products-microservice\"\n        acquisition_location = \"NotAcquired\"\n        feed_id              = local.docker_hub_feed_id\n        properties           = { SelectionMode = \"immediate\" }\n      }\n\n      features = []\n    }\n\n    properties   = {}\n    target_roles = [\"${local.target_role} Products\"]\n  }\n\n  step {\n    condition           = \"Success\"\n    name                = \"Service Link\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type = local.link_highlight_action_type\n      properties  = local.link_highlight_properties\n      container {\n        feed_id = local.docker_hub_feed_id\n        image   = local.link_highlight_container_image\n      }\n      name                               = \"Service Link\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      environments                       = []\n      excluded_environments              = []\n      channels                           = []\n      tenant_tags                        = []\n      features                           = []\n    }\n\n    properties   = {}\n    target_roles = [\"${local.target_role} Products\"]\n  }\n\n  step {\n    condition           = \"Success\"\n    name                = \"Smoke Test\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = local.smoke_test_action_type\n      name                               = \"Smoke Test\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = local.smoke_test_properties\n      container {\n        feed_id = local.docker_hub_feed_id\n        image   = local.smoke_test_container_image\n      }\n      environments = [\n        local.development_environment_id,\n        local.test_environment_id,\n        local.production_environment_id,\n      ]\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = [\"${local.target_role} Products\"]\n  }\n\n  step {\n    condition           = \"Success\"\n    name                = \"Security Scan\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Security Scan\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = true\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"Bash\"\n        \"Octopus.Action.Script.ScriptBody\"   = local.security_scan_docker_script\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n\n  step {\n    condition           = \"Always\"\n    name                = \"Feedback\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Feedback\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = local.feedback_script\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n}\n#endregion\n\n#region Octopub Audits Project\nvariable \"audits_project_name\" {\n  type    = string\n  default = \"\"\n}\n\ndata \"octopusdeploy_projects\" \"audits\" {\n  partial_name = var.audits_project_name == \"\" ? local.octopub_audits_project_name : var.audits_project_name\n  skip         = 0\n  take         = 1\n}\n\nresource \"octopusdeploy_variable\" \"azure_webapp_octopub_audits_octopus_azure_account\" {\n  count        = length(data.octopusdeploy_projects.audits.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.audits[0].id\n  value        = local.cloud_account\n  name         = \"Octopus.Azure.Account\"\n  type         = \"AzureAccount\"\n  description  = \"\"\n  is_sensitive = false\n}\n\nresource \"octopusdeploy_variable\" \"audits_healthcheck\" {\n  count        = length(data.octopusdeploy_projects.audits.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.audits[0].id\n  value        = local.audits_health_check\n  name         = \"App.HealthCheck\"\n  type         = \"String\"\n  description  = \"The path to perform a health check on.\"\n  is_sensitive = false\n  depends_on   = []\n}\n\nresource \"octopusdeploy_project\" \"audits\" {\n  count                                = length(data.octopusdeploy_projects.audits.projects) == 0 ? 1 : 0\n  name                                 = var.audits_project_name == \"\" ? local.octopub_audits_project_name : var.audits_project_name\n  auto_create_release                  = false\n  default_guided_failure_mode          = \"EnvironmentDefault\"\n  default_to_skip_if_already_installed = false\n  discrete_channel_release             = false\n  is_disabled                          = false\n  is_version_controlled                = true\n  lifecycle_id                         = local.devops_lifecycle_id\n  project_group_id                     = local.project_group_id\n  included_library_variable_sets       = []\n  tenanted_deployment_participation    = \"Untenanted\"\n\n  connectivity_policy {\n    allow_deployments_to_no_targets = true\n    exclude_unhealthy_targets       = false\n    skip_machine_behavior           = \"None\"\n  }\n\n  versioning_strategy {\n    template = \"#{Octopus.Version.LastMajor}.#{Octopus.Version.LastMinor}.#{Octopus.Version.NextPatch}\"\n  }\n\n  lifecycle {\n    ignore_changes = [connectivity_policy]\n  }\n  description = local.octopub_audits_project_description\n}\n\nresource \"octopusdeploy_deployment_process\" \"audits\" {\n  count      = length(data.octopusdeploy_projects.audits.projects) == 0 ? 1 : 0\n  project_id = octopusdeploy_project.audits[0].id\n\n\n  step {\n    condition           = \"Success\"\n    name                = \"Generate Variables\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Generate Variables\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = \"${data.octopusdeploy_worker_pools.workerpool_hosted_ubuntu.worker_pools[0].id}\"\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = \"Set-OctopusVariable -name \\\"OctopusEnvironmentName\\\" -value $OctopusParameters[\\\"Octopus.Environment.Name\\\"]\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n\n  // The deployment step goes here.\n  // Call the step \"Deploy Container\"\n\n  step {\n    condition           = \"Success\"\n    name                = \"Deploy Container\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.AzureAppService\"\n      name                               = \"Deploy Container\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = true\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"                = \"true\"\n        \"OctopusUseBundledTooling\"                  = \"False\"\n        \"Octopus.Action.Azure.DeploymentType\"       = \"Container\"\n        \"Octopus.Action.Package.DownloadOnTentacle\" = \"False\"\n        \"Octopus.Action.Azure.AppSettings\"          = jsonencode([\n          {\n            \"name\"        = \"WEBSITES_PORT\"\n            \"value\"       = \"10000\"\n            \"slotSetting\" = \"false\"\n          },\n          {\n            \"name\"        = \"MIGRATE_AT_START\"\n            \"value\"       = \"true\"\n            \"slotSetting\" = \"false\"\n          },\n        ])\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n\n      primary_package {\n        package_id           = \"octopussamples/octopub-audit-microservice\"\n        acquisition_location = \"NotAcquired\"\n        feed_id              = local.docker_hub_feed_id\n        properties           = { SelectionMode = \"immediate\" }\n      }\n\n      features = []\n    }\n\n    properties   = {}\n    target_roles = [\"${local.target_role} Audits\"]\n  }\n\n  step {\n    condition           = \"Success\"\n    name                = \"Service Link\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type = local.link_highlight_action_type\n      properties  = local.link_highlight_properties\n      container {\n        feed_id = local.docker_hub_feed_id\n        image   = local.link_highlight_container_image\n      }\n      name                               = \"Service Link\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      environments                       = []\n      excluded_environments              = []\n      channels                           = []\n      tenant_tags                        = []\n      features                           = []\n    }\n\n    properties   = {}\n    target_roles = [\"${local.target_role} Audits\"]\n  }\n\n  step {\n    condition           = \"Success\"\n    name                = \"Smoke Test\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = local.smoke_test_action_type\n      properties                         = local.smoke_test_properties\n      name                               = \"Smoke Test\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      container {\n        feed_id = local.docker_hub_feed_id\n        image   = local.smoke_test_container_image\n      }\n      environments = [\n        local.development_environment_id,\n        local.test_environment_id,\n        local.production_environment_id,\n      ]\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = [\"${local.target_role} Audits\"]\n  }\n\n  step {\n    condition           = \"Success\"\n    name                = \"Security Scan\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Security Scan\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = true\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"Bash\"\n        \"Octopus.Action.Script.ScriptBody\"   = local.security_scan_docker_script\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n\n  step {\n    condition           = \"Always\"\n    name                = \"Feedback\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Feedback\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.Script.ScriptBody\"   = local.feedback_script\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n}\n#endregion\n\n#region Octopub Orchestration Project\ndata \"octopusdeploy_projects\" \"orchestration\" {\n  partial_name = local.octopub_orchestration_project_name\n  skip         = 0\n  take         = 1\n}\n\nresource \"octopusdeploy_project\" \"orchestration\" {\n  count                                = length(data.octopusdeploy_projects.orchestration.projects) == 0 ? 1 : 0\n  name                                 = local.octopub_orchestration_project_name\n  auto_create_release                  = false\n  default_guided_failure_mode          = \"EnvironmentDefault\"\n  default_to_skip_if_already_installed = false\n  discrete_channel_release             = false\n  is_disabled                          = false\n  is_version_controlled                = false\n  lifecycle_id                         = local.devops_lifecycle_id\n  project_group_id                     = local.project_group_id\n  included_library_variable_sets       = []\n  tenanted_deployment_participation    = \"Untenanted\"\n\n  connectivity_policy {\n    allow_deployments_to_no_targets = true\n    exclude_unhealthy_targets       = false\n    skip_machine_behavior           = \"None\"\n  }\n\n  versioning_strategy {\n    template = \"#{Octopus.Version.LastMajor}.#{Octopus.Version.LastMinor}.#{Octopus.Version.NextPatch}\"\n  }\n\n  lifecycle {\n    ignore_changes = []\n  }\n  description = local.octopub_products_project_description\n}\n\nresource \"octopusdeploy_deployment_process\" \"orchestration\" {\n  project_id = octopusdeploy_project.orchestration[0].id\n  count      = length(data.octopusdeploy_projects.orchestration.projects) == 0 ? 1 : 0\n\n  step {\n    condition           = \"Success\"\n    name                = \"Deploy Frontend\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.DeployRelease\"\n      name                               = \"Deploy Frontend\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = true\n      is_required                        = false\n      worker_pool_id                     = \"\"\n      properties                         = {\n        \"Octopus.Action.Package.DownloadOnTentacle\"        = \"NotAcquired\"\n        \"Octopus.Action.RunOnServer\"                       = \"True\"\n        \"Octopus.Action.DeployRelease.DeploymentCondition\" = \"Always\"\n        \"Octopus.Action.DeployRelease.ProjectId\"           = length(data.octopusdeploy_projects.frontend.projects) == 0 ? octopusdeploy_project.frontend[0].id : data.octopusdeploy_projects.frontend.projects[0].id\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n\n      primary_package {\n        package_id           = length(data.octopusdeploy_projects.frontend.projects) == 0 ? octopusdeploy_project.frontend[0].id : data.octopusdeploy_projects.frontend.projects[0].id\n        acquisition_location = \"NotAcquired\"\n        feed_id              = data.octopusdeploy_feeds.project.feeds[0].id\n        properties           = {}\n      }\n\n      features = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n  step {\n    condition           = \"Success\"\n    name                = \"Deploy Products\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.DeployRelease\"\n      name                               = \"Deploy Products\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = true\n      is_required                        = false\n      worker_pool_id                     = \"\"\n      properties                         = {\n        \"Octopus.Action.DeployRelease.ProjectId\"           = length(data.octopusdeploy_projects.products.projects) == 0 ? octopusdeploy_project.products[0].id : data.octopusdeploy_projects.products.projects[0].id\n        \"Octopus.Action.Package.DownloadOnTentacle\"        = \"NotAcquired\"\n        \"Octopus.Action.RunOnServer\"                       = \"True\"\n        \"Octopus.Action.DeployRelease.DeploymentCondition\" = \"Always\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n\n      primary_package {\n        package_id           = length(data.octopusdeploy_projects.products.projects) == 0 ? octopusdeploy_project.products[0].id : data.octopusdeploy_projects.products.projects[0].id\n        acquisition_location = \"NotAcquired\"\n        feed_id              = data.octopusdeploy_feeds.project.feeds[0].id\n        properties           = {}\n      }\n\n      features = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n  step {\n    condition           = \"Success\"\n    name                = \"Deploy Audits\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.DeployRelease\"\n      name                               = \"Deploy Audits\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = true\n      is_required                        = false\n      worker_pool_id                     = \"\"\n      properties                         = {\n        \"Octopus.Action.RunOnServer\"                       = \"True\"\n        \"Octopus.Action.DeployRelease.DeploymentCondition\" = \"Always\"\n        \"Octopus.Action.DeployRelease.ProjectId\"           = length(data.octopusdeploy_projects.audits.projects) == 0 ? octopusdeploy_project.audits[0].id : data.octopusdeploy_projects.audits.projects[0].id\n        \"Octopus.Action.Package.DownloadOnTentacle\"        = \"NotAcquired\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n\n      primary_package {\n        package_id           = length(data.octopusdeploy_projects.audits.projects) == 0 ? octopusdeploy_project.audits[0].id : data.octopusdeploy_projects.audits.projects[0].id\n        acquisition_location = \"NotAcquired\"\n        feed_id              = data.octopusdeploy_feeds.project.feeds[0].id\n        properties           = {}\n      }\n\n      features = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n  step {\n    condition           = \"Always\"\n    name                = \"Feedback\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Feedback\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.Script.ScriptBody\"   = local.feedback_script\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n}\n#endregion\n\n#region Project Templates\nvariable \"project_template_project_name\" {\n  type    = string\n  default = \"\"\n}\n\ndata \"octopusdeploy_projects\" \"docker_project_template\" {\n  partial_name = var.project_template_project_name == \"\" ? local.project_template_project_name : var.project_template_project_name\n  skip         = 0\n  take         = 1\n}\n\nresource \"octopusdeploy_variable\" \"docker_project_template_git_organization\" {\n  count        = length(data.octopusdeploy_projects.docker_project_template.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.docker_project_template[0].id\n  value        = \"\"\n  name         = \"Git.Url.Organization\"\n  type         = \"String\"\n  description  = \"The GitHub organization to create the repo in.\"\n  is_sensitive = false\n\n  prompt {\n    description = \"The Github organization where the repo will be created. This is the `owner` part of the URL `https://github.com/owner/myrepo`.\"\n    label       = \"Github Organization\"\n    is_required = true\n    display_settings {\n      control_type = \"SingleLineText\"\n    }\n  }\n\n  scope {\n    actions      = []\n    channels     = []\n    environments = [local.sync_environment_id]\n    machines     = []\n    roles        = null\n    tenant_tags  = null\n  }\n}\n\nresource \"octopusdeploy_variable\" \"docker_project_template_git_repo\" {\n  count        = length(data.octopusdeploy_projects.docker_project_template.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.docker_project_template[0].id\n  value        = \"\"\n  name         = \"Git.Url.Repo\"\n  type         = \"String\"\n  description  = \"The GitHub repo to create.\"\n  is_sensitive = false\n\n  prompt {\n    description = \"The Github repo to be created. This is the `myrepo` part of the URL `https://github.com/owner/myrepo`.\"\n    label       = \"Github Repo\"\n    is_required = true\n    display_settings {\n      control_type = \"SingleLineText\"\n    }\n  }\n\n  scope {\n    actions      = []\n    channels     = []\n    environments = [local.sync_environment_id]\n    machines     = []\n    roles        = null\n    tenant_tags  = null\n  }\n}\n\nresource \"octopusdeploy_variable\" \"docker_project_template_image_name\" {\n  count        = length(data.octopusdeploy_projects.docker_project_template.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.docker_project_template[0].id\n  value        = \"\"\n  name         = \"Application.Docker.Image\"\n  type         = \"String\"\n  description  = \"The Docker image to create containing the new application.\"\n  is_sensitive = false\n\n  prompt {\n    description = \"The Docker image to create containing the new application.\"\n    label       = \"Docker Image\"\n    is_required = true\n    display_settings {\n      control_type = \"SingleLineText\"\n    }\n  }\n\n  scope {\n    actions      = []\n    channels     = []\n    environments = [local.sync_environment_id]\n    machines     = []\n    roles        = null\n    tenant_tags  = null\n  }\n}\n\nresource \"octopusdeploy_variable\" \"docker_project_template_octopus_project\" {\n  count        = length(data.octopusdeploy_projects.docker_project_template.projects) == 0 ? 1 : 0\n  owner_id     = octopusdeploy_project.docker_project_template[0].id\n  value        = \"\"\n  name         = \"Application.Octopus.Project\"\n  type         = \"String\"\n  description  = \"The Octopus project to associate with the new application.\"\n  is_sensitive = false\n\n  prompt {\n    description = \"The Octopus project to associate with the new application. A release is created in this project when the image is successfully built.\"\n    label       = \"Octopus Project\"\n    is_required = true\n    display_settings {\n      control_type = \"SingleLineText\"\n    }\n  }\n\n  scope {\n    actions      = []\n    channels     = []\n    environments = [local.sync_environment_id]\n    machines     = []\n    roles        = null\n    tenant_tags  = null\n  }\n}\n\nresource \"octopusdeploy_project\" \"docker_project_template\" {\n  count                                = length(data.octopusdeploy_projects.docker_project_template.projects) == 0 ? 1 : 0\n  name                                 = var.project_template_project_name == \"\" ? local.project_template_project_name : var.project_template_project_name\n  auto_create_release                  = false\n  default_guided_failure_mode          = \"Off\"\n  default_to_skip_if_already_installed = false\n  discrete_channel_release             = false\n  is_disabled                          = false\n  is_version_controlled                = false\n  lifecycle_id                         = local.application_lifecycle_id\n  project_group_id                     = local.project_templates_project_group_id\n  included_library_variable_sets       = [\n    local.this_instance_library_variable_set, local.github_library_variable_set, local.docker_library_variable_set\n  ]\n  tenanted_deployment_participation = \"Untenanted\"\n\n  connectivity_policy {\n    allow_deployments_to_no_targets = true\n    exclude_unhealthy_targets       = false\n    skip_machine_behavior           = \"None\"\n  }\n\n  versioning_strategy {\n    template = \"#{Octopus.Version.LastMajor}.#{Octopus.Version.LastMinor}.#{Octopus.Version.NextPatch}\"\n  }\n\n  lifecycle {\n    ignore_changes = []\n  }\n  description = <<EOT\nCreates Project Templates.\nEOT\n}\n\nresource \"octopusdeploy_runbook\" \"docker_project_template_create_nodejs_template\" {\n  count                       = length(data.octopusdeploy_projects.docker_project_template.projects) == 0 ? 1 : 0\n  name                        = \"📗 Create Template Github Node.js Project\"\n  project_id                  = octopusdeploy_project.docker_project_template[0].id\n  environment_scope           = \"Specified\"\n  environments                = [local.sync_environment_id]\n  force_package_download      = false\n  default_guided_failure_mode = \"EnvironmentDefault\"\n  description                 = \"This runbook populates a GitHub repo with a sample Node.js project and GitHub Actions Workflow that builds a Docker image, pushes it to DockerHub, and triggers the deployment of the associated Octopus project in the Development environment. \\n\\n**Action**: Creates a new GitHub repo (if it doesn't exist) and populates it with the output of a Yeoman generator.\\n\\n\\n**Affects**: This will overwrite files in the target Git repo. Changes can be reverted with git.\"\n  multi_tenancy_mode          = \"Untenanted\"\n\n  retention_policy {\n    quantity_to_keep    = 100\n    should_keep_forever = false\n  }\n\n  connectivity_policy {\n    allow_deployments_to_no_targets = true\n    exclude_unhealthy_targets       = false\n    skip_machine_behavior           = \"None\"\n  }\n}\n\nresource \"octopusdeploy_runbook_process\" \"docker_project_template_create_nodejs_template\" {\n  runbook_id = octopusdeploy_runbook.docker_project_template_create_nodejs_template[0].id\n  count      = length(data.octopusdeploy_projects.docker_project_template.projects) == 0 ? 1 : 0\n\n  step {\n    condition           = \"Success\"\n    name                = \"Get Variables\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Get Variables\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.Script.ScriptBody\"   = \"# This is a workaround to the issue where octostache templates in the Terraform\\n# project are replaced during deployment, when we actually want some variables\\n# at run time.\\n\\nSet-OctopusVariable -name \\\"Project.Name\\\" -value $OctopusParameters[\\\"Octopus.Project.Name\\\"]\\nSet-OctopusVariable -name \\\"Web.ServerUri\\\" -value $OctopusParameters[\\\"Octopus.Web.ServerUri\\\"]\\nSet-OctopusVariable -name \\\"Space.Id\\\" -value $OctopusParameters[\\\"Octopus.Space.Id\\\"]\\nSet-OctopusVariable -name \\\"Space.Name\\\" -value $OctopusParameters[\\\"Octopus.Space.Name\\\"]\"\n        \"Octopus.Action.RunOnServer\"         = \"true\"\n        \"Octopus.Action.Script.ScriptSource\" = \"Inline\"\n        \"Octopus.Action.Script.Syntax\"       = \"PowerShell\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n  step {\n    condition           = \"Success\"\n    name                = \"Create Repo\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Create Repo\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"CreateGithubRepo.Git.Url.Organization\"        = \"#{Git.Url.Organization}\"\n        \"Octopus.Action.Script.Syntax\"                 = \"Python\"\n        \"Octopus.Action.RunOnServer\"                   = \"true\"\n        \"CreateGithubRepo.Git.Url.NewRepoNamePrefix\"   = \"\"\n        \"CreateGithubRepo.Git.Credentials.AccessToken\" = \"#{Git.Credentials.Password}\"\n        \"Octopus.Action.Script.ScriptBody\"             = \"# This script forks a GitHub repo. It creates a token from a GitHub App installation to avoid\\n# having to use a regular user account.\\nimport subprocess\\nimport sys\\n\\n# Install our own dependencies\\nsubprocess.check_call([sys.executable, '-m', 'pip', 'install', 'jwt', '--disable-pip-version-check'])\\n\\nimport json\\nimport subprocess\\nimport sys\\nimport os\\nimport urllib.request\\nimport base64\\nimport re\\nimport jwt\\nimport time\\nimport argparse\\nimport platform\\nfrom urllib.request import urlretrieve\\n\\n# If this script is not being run as part of an Octopus step, setting variables is a noop\\nif 'set_octopusvariable' not in globals():\\n    def set_octopusvariable(variable, value):\\n        pass\\n\\n# If this script is not being run as part of an Octopus step, return variables from environment variables.\\n# Periods are replaced with underscores, and the variable name is converted to uppercase\\nif \\\"get_octopusvariable\\\" not in globals():\\n    def get_octopusvariable(variable):\\n        return os.environ[re.sub('\\\\\\\\.', '_', variable.upper())]\\n\\n# If this script is not being run as part of an Octopus step, print directly to std out.\\nif 'printverbose' not in globals():\\n    def printverbose(msg):\\n        print(msg)\\n\\n\\ndef printverbose_noansi(output):\\n    \\\"\\\"\\\"\\n    Strip ANSI color codes and print the output as verbose\\n    :param output: The output to print\\n    \\\"\\\"\\\"\\n    output_no_ansi = re.sub(r'\\\\x1b\\\\[[0-9;]*m', '', output)\\n    printverbose(output_no_ansi)\\n\\n\\ndef get_octopusvariable_quiet(variable):\\n    \\\"\\\"\\\"\\n    Gets an octopus variable, or an empty string if it does not exist.\\n    :param variable: The variable name\\n    :return: The variable value, or an empty string if the variable does not exist\\n    \\\"\\\"\\\"\\n    try:\\n        return get_octopusvariable(variable)\\n    except:\\n        return ''\\n\\n\\ndef execute(args, cwd=None, env=None, print_args=None, print_output=printverbose_noansi, raise_on_non_zero=False,\\n            append_to_path=None):\\n    \\\"\\\"\\\"\\n        The execute method provides the ability to execute external processes while capturing and returning the\\n        output to std err and std out and exit code.\\n    \\\"\\\"\\\"\\n\\n    my_env = os.environ.copy() if env is None else env\\n\\n    if append_to_path is not None:\\n        my_env[\\\"PATH\\\"] = append_to_path + os.pathsep + my_env['PATH']\\n\\n    process = subprocess.Popen(args,\\n                               stdout=subprocess.PIPE,\\n                               stderr=subprocess.PIPE,\\n                               stdin=open(os.devnull),\\n                               text=True,\\n                               cwd=cwd,\\n                               env=my_env)\\n    stdout, stderr = process.communicate()\\n    retcode = process.returncode\\n\\n    if not retcode == 0 and raise_on_non_zero:\\n        raise Exception('command returned exit code ' + retcode)\\n\\n    if print_args is not None:\\n        print_output(' '.join(args))\\n\\n    if print_output is not None:\\n        print_output(stdout)\\n        print_output(stderr)\\n\\n    return stdout, stderr, retcode\\n\\n\\ndef init_argparse():\\n    parser = argparse.ArgumentParser(\\n        usage='%(prog)s [OPTION]',\\n        description='Create a GitHub repo'\\n    )\\n    parser.add_argument('--new-repo-name', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGithubRepo.Git.Url.NewRepoName') or get_octopusvariable_quiet(\\n                            'Git.Url.NewRepoName') or get_octopusvariable_quiet('Octopus.Project.Name'))\\n    parser.add_argument('--new-repo-name-prefix', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGithubRepo.Git.Url.NewRepoNamePrefix') or get_octopusvariable_quiet(\\n                            'Git.Url.NewRepoNamePrefix'))\\n    parser.add_argument('--git-organization', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGithubRepo.Git.Url.Organization') or get_octopusvariable_quiet(\\n                            'Git.Url.Organization'))\\n    parser.add_argument('--github-app-id', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGithubRepo.GitHub.App.Id') or get_octopusvariable_quiet('GitHub.App.Id'))\\n    parser.add_argument('--github-app-installation-id', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGithubRepo.GitHub.App.InstallationId') or get_octopusvariable_quiet(\\n                            'GitHub.App.InstallationId'))\\n    parser.add_argument('--github-app-private-key', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGithubRepo.GitHub.App.PrivateKey') or get_octopusvariable_quiet(\\n                            'GitHub.App.PrivateKey'))\\n    parser.add_argument('--github-access-token', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGithubRepo.Git.Credentials.AccessToken') or get_octopusvariable_quiet(\\n                            'Git.Credentials.AccessToken'),\\n                        help='The git password')\\n\\n    return parser.parse_known_args()\\n\\n\\ndef generate_github_token(github_app_id, github_app_private_key, github_app_installation_id):\\n    # Generate the tokens used by git and the GitHub API\\n    app_id = github_app_id\\n    signing_key = jwt.jwk_from_pem(github_app_private_key.encode('utf-8'))\\n\\n    payload = {\\n        # Issued at time\\n        'iat': int(time.time()),\\n        # JWT expiration time (10 minutes maximum)\\n        'exp': int(time.time()) + 600,\\n        # GitHub App's identifier\\n        'iss': app_id\\n    }\\n\\n    # Create JWT\\n    jwt_instance = jwt.JWT()\\n    encoded_jwt = jwt_instance.encode(payload, signing_key, alg='RS256')\\n\\n    # Create access token\\n    url = 'https://api.github.com/app/installations/' + github_app_installation_id + '/access_tokens'\\n    headers = {\\n        'Authorization': 'Bearer ' + encoded_jwt,\\n        'Accept': 'application/vnd.github+json',\\n        'X-GitHub-Api-Version': '2022-11-28'\\n    }\\n    request = urllib.request.Request(url, headers=headers, method='POST')\\n    response = urllib.request.urlopen(request)\\n    response_json = json.loads(response.read().decode())\\n    return response_json['token']\\n\\n\\ndef generate_auth_header(token):\\n    auth = base64.b64encode(('x-access-token:' + token).encode('ascii'))\\n    return 'Basic ' + auth.decode('ascii')\\n\\n\\ndef verify_new_repo(token, cac_org, new_repo):\\n    # Attempt to view the new repo\\n    try:\\n        url = 'https://api.github.com/repos/' + cac_org + '/' + new_repo\\n        headers = {\\n            'Accept': 'application/vnd.github+json',\\n            'Authorization': 'Bearer ' + token,\\n            'X-GitHub-Api-Version': '2022-11-28'\\n        }\\n        request = urllib.request.Request(url, headers=headers)\\n        urllib.request.urlopen(request)\\n        return True\\n    except:\\n        return False\\n\\n\\ndef create_new_repo(token, cac_org, new_repo):\\n    # If we could not view the repo, assume it needs to be created.\\n    # https://docs.github.com/en/rest/repos/repos?apiVersion=2022-11-28#create-an-organization-repository\\n    # Note you have to use the token rather than the JWT:\\n    # https://stackoverflow.com/questions/39600396/bad-credentails-for-jwt-for-github-integrations-api\\n\\n    headers = {\\n        'Authorization': 'token ' + token,\\n        'Content-Type': 'application/json',\\n        'Accept': 'application/vnd.github+json',\\n        'X-GitHub-Api-Version': '2022-11-28',\\n    }\\n\\n    try:\\n        # First try to create an organization repo:\\n        # https://docs.github.com/en/free-pro-team@latest/rest/repos/repos#create-an-organization-repository\\n        url = 'https://api.github.com/orgs/' + cac_org + '/repos'\\n        body = {'name': new_repo}\\n        request = urllib.request.Request(url, headers=headers, data=json.dumps(body).encode('utf-8'))\\n        urllib.request.urlopen(request)\\n    except urllib.error.URLError as ex:\\n        # Then fall back to creating a repo for the user:\\n        # https://docs.github.com/en/free-pro-team@latest/rest/repos/repos?apiVersion=2022-11-28#create-a-repository-for-the-authenticated-user\\n        if ex.code == 404:\\n            url = 'https://api.github.com/user/repos'\\n            body = {'name': new_repo}\\n            request = urllib.request.Request(url, headers=headers, data=json.dumps(body).encode('utf-8'))\\n            urllib.request.urlopen(request)\\n        else:\\n            raise ValueError(\\\"Failed to create thew new repository. This could indicate bad credentials.\\\") from ex\\n\\n\\ndef is_windows():\\n    return platform.system() == 'Windows'\\n\\n\\nparser, _ = init_argparse()\\n\\nif not parser.github_access_token.strip() and not (\\n        parser.github_app_id.strip() and parser.github_app_private_key.strip() and parser.github_app_installation_id.strip()):\\n    print(\\\"You must supply the GitHub token, or the GitHub App ID and private key and installation ID\\\")\\n    sys.exit(1)\\n\\nif not parser.new_repo_name.strip():\\n    print(\\\"You must define the new repo name\\\")\\n    sys.exit(1)\\n\\n# The access token is generated from a github app or supplied directly as an access token\\ntoken = generate_github_token(parser.github_app_id, parser.github_app_private_key, parser.github_app_installation_id) \\\\\\n    if not parser.github_access_token.strip() else parser.github_access_token.strip()\\n\\ncac_org = parser.git_organization.strip()\\nnew_repo_custom_prefix = re.sub('[^a-zA-Z0-9-]', '_', parser.new_repo_name_prefix.strip())\\nproject_repo_sanitized = re.sub('[^a-zA-Z0-9-]', '_', parser.new_repo_name.strip())\\n\\n# The prefix is optional\\nnew_repo_prefix_with_separator = new_repo_custom_prefix + '_' if new_repo_custom_prefix else ''\\n\\n# The new repo name is the prefix + the name of thew new project\\nnew_repo = new_repo_prefix_with_separator + project_repo_sanitized\\n\\n# This is the value of the forked git repo\\nset_octopusvariable('NewRepoUrl', 'https://github.com/' + cac_org + '/' + new_repo)\\nset_octopusvariable('NewRepo', new_repo)\\n\\nif not verify_new_repo(token, cac_org, new_repo):\\n    create_new_repo(token, cac_org, new_repo)\\n    print(\\n        'New repo was created at https://github.com/' + cac_org + '/' + new_repo)\\nelse:\\n    print('Repo at https://github.com/' + cac_org + '/' + new_repo + ' already exists and has not been modified')\\n\\nprint('New repo URL is defined in the output variable \\\"NewRepoUrl\\\": #{Octopus.Action[' +\\n      get_octopusvariable_quiet('Octopus.Step.Name') + '].Output.NewRepoUrl}')\\nprint('New repo name is defined in the output variable \\\"NewRepo\\\": #{Octopus.Action[' +\\n      get_octopusvariable_quiet('Octopus.Step.Name') + '].Output.NewRepo}')\\n\"\n        \"CreateGithubRepo.Git.Url.NewRepoName\"         = \"#{Git.Url.Repo}\"\n        \"Octopus.Action.Script.ScriptSource\"           = \"Inline\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n  step {\n    condition           = \"Success\"\n    name                = \"Create Octopus API Key Secret\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Create Octopus API Key Secret\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"Octopus.Action.Script.Syntax\"                = \"Python\"\n        \"CreateGitHubSecret.Git.Credentials.Password\" = \"#{Git.Credentials.Password}\"\n        \"CreateGitHubSecret.GitHub.Secret.Value\"      = \"#{Octopus.ApiKey}\"\n        \"CreateGitHubSecret.Git.Url.Repo\"             = \"#{Octopus.Action[Create Repo].Output.NewRepo}\"\n        \"Octopus.Action.RunOnServer\"                  = \"true\"\n        \"Octopus.Action.Script.ScriptSource\"          = \"Inline\"\n        \"CreateGitHubSecret.GitHub.Secret.Name\"       = \"OCTOPUS_API_TOKEN\"\n        \"CreateGitHubSecret.Git.Url.Organization\"     = \"#{Git.Url.Organization}\"\n        \"Octopus.Action.Script.ScriptBody\"            = \"# https://gist.github.com/comdotlinux/9a53bb00767a16d6646464c4b8249094\\n\\n# This script forks a GitHub repo. It creates a token from a GitHub App installation to avoid\\n# having to use a regular user account.\\nimport subprocess\\nimport sys\\n\\n# Install our own dependencies\\nsubprocess.check_call([sys.executable, '-m', 'pip', 'install', 'jwt', '--disable-pip-version-check'])\\nsubprocess.check_call([sys.executable, '-m', 'pip', 'install', 'pynacl', '--disable-pip-version-check'])\\n\\nimport requests\\nimport json\\nimport subprocess\\nimport sys\\nimport os\\nimport urllib.request\\nimport base64\\nimport re\\nimport jwt\\nimport time\\nimport argparse\\nimport urllib3\\nfrom base64 import b64encode\\nfrom typing import TypedDict\\nfrom nacl import public, encoding\\n\\n# Disable insecure http request warnings\\nurllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)\\n\\n# If this script is not being run as part of an Octopus step, setting variables is a noop\\nif 'set_octopusvariable' not in globals():\\n    def set_octopusvariable(variable, value):\\n        pass\\n\\n# If this script is not being run as part of an Octopus step, return variables from environment variables.\\n# Periods are replaced with underscores, and the variable name is converted to uppercase\\nif \\\"get_octopusvariable\\\" not in globals():\\n    def get_octopusvariable(variable):\\n        return os.environ[re.sub('\\\\\\\\.', '_', variable.upper())]\\n\\n# If this script is not being run as part of an Octopus step, print directly to std out.\\nif 'printverbose' not in globals():\\n    def printverbose(msg):\\n        print(msg)\\n\\n\\ndef printverbose_noansi(output):\\n    \\\"\\\"\\\"\\n    Strip ANSI color codes and print the output as verbose\\n    :param output: The output to print\\n    \\\"\\\"\\\"\\n    output_no_ansi = re.sub(r'\\\\x1b\\\\[[0-9;]*m', '', output)\\n    printverbose(output_no_ansi)\\n\\n\\ndef get_octopusvariable_quiet(variable):\\n    \\\"\\\"\\\"\\n    Gets an octopus variable, or an empty string if it does not exist.\\n    :param variable: The variable name\\n    :return: The variable value, or an empty string if the variable does not exist\\n    \\\"\\\"\\\"\\n    try:\\n        return get_octopusvariable(variable)\\n    except:\\n        return ''\\n\\n\\ndef execute(args, cwd=None, env=None, print_args=None, print_output=printverbose_noansi, raise_on_non_zero=False,\\n            append_to_path=None):\\n    \\\"\\\"\\\"\\n        The execute method provides the ability to execute external processes while capturing and returning the\\n        output to std err and std out and exit code.\\n    \\\"\\\"\\\"\\n\\n    my_env = os.environ.copy() if env is None else env\\n\\n    if append_to_path is not None:\\n        my_env[\\\"PATH\\\"] = append_to_path + os.pathsep + my_env['PATH']\\n\\n    process = subprocess.Popen(args,\\n                               stdout=subprocess.PIPE,\\n                               stderr=subprocess.PIPE,\\n                               stdin=open(os.devnull),\\n                               text=True,\\n                               cwd=cwd,\\n                               env=my_env)\\n    stdout, stderr = process.communicate()\\n    retcode = process.returncode\\n\\n    if not retcode == 0 and raise_on_non_zero:\\n        raise Exception('command returned exit code ' + retcode)\\n\\n    if print_args is not None:\\n        print_output(' '.join(args))\\n\\n    if print_output is not None:\\n        print_output(stdout)\\n        print_output(stderr)\\n\\n    return stdout, stderr, retcode\\n\\n\\ndef init_argparse():\\n    parser = argparse.ArgumentParser(\\n        usage='%(prog)s [OPTION]',\\n        description='Fork a GitHub repo'\\n    )\\n\\n    parser.add_argument('--secret-name', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.GitHub.Secret.Name') or get_octopusvariable_quiet(\\n                            'GitHub.Secret.Name'))\\n    parser.add_argument('--secret-value', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.GitHub.Secret.Value') or get_octopusvariable_quiet(\\n                            'GitHub.Secret.Value'))\\n\\n    parser.add_argument('--repo', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.Git.Url.Repo') or get_octopusvariable_quiet(\\n                            'Git.Url.Repo') or get_octopusvariable_quiet('Octopus.Project.Name'))\\n    parser.add_argument('--git-organization', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.Git.Url.Organization') or get_octopusvariable_quiet(\\n                            'Git.Url.Organization'))\\n    parser.add_argument('--github-app-id', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.GitHub.App.Id') or get_octopusvariable_quiet('GitHub.App.Id'))\\n    parser.add_argument('--github-app-installation-id', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.GitHub.App.InstallationId') or get_octopusvariable_quiet(\\n                            'GitHub.App.InstallationId'))\\n    parser.add_argument('--github-app-private-key', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.GitHub.App.PrivateKey') or get_octopusvariable_quiet(\\n                            'GitHub.App.PrivateKey'))\\n    parser.add_argument('--git-password', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.Git.Credentials.Password') or get_octopusvariable_quiet(\\n                            'Git.Credentials.Password'),\\n                        help='The git password. This takes precedence over the --github-app-id,  --github-app-installation-id, and --github-app-private-key')\\n\\n    return parser.parse_known_args()\\n\\n\\ndef generate_github_token(github_app_id, github_app_private_key, github_app_installation_id):\\n    # Generate the tokens used by git and the GitHub API\\n    app_id = github_app_id\\n    signing_key = jwt.jwk_from_pem(github_app_private_key.encode('utf-8'))\\n\\n    payload = {\\n        # Issued at time\\n        'iat': int(time.time()),\\n        # JWT expiration time (10 minutes maximum)\\n        'exp': int(time.time()) + 600,\\n        # GitHub App's identifier\\n        'iss': app_id\\n    }\\n\\n    # Create JWT\\n    jwt_instance = jwt.JWT()\\n    encoded_jwt = jwt_instance.encode(payload, signing_key, alg='RS256')\\n\\n    # Create access token\\n    url = 'https://api.github.com/app/installations/' + github_app_installation_id + '/access_tokens'\\n    headers = {\\n        'Authorization': 'Bearer ' + encoded_jwt,\\n        'Accept': 'application/vnd.github+json',\\n        'X-GitHub-Api-Version': '2022-11-28'\\n    }\\n    request = urllib.request.Request(url, headers=headers, method='POST')\\n    response = urllib.request.urlopen(request)\\n    response_json = json.loads(response.read().decode())\\n    return response_json['token']\\n\\n\\ndef generate_auth_header(token):\\n    auth = base64.b64encode(('x-access-token:' + token).encode('ascii'))\\n    return 'Basic ' + auth.decode('ascii')\\n\\n\\ndef verify_new_repo(token, cac_org, new_repo):\\n    # Attempt to view the new repo\\n    try:\\n        url = 'https://api.github.com/repos/' + cac_org + '/' + new_repo\\n        headers = {\\n            'Accept': 'application/vnd.github+json',\\n            'Authorization': 'Bearer ' + token,\\n            'X-GitHub-Api-Version': '2022-11-28'\\n        }\\n        request = urllib.request.Request(url, headers=headers)\\n        urllib.request.urlopen(request)\\n        return True\\n    except:\\n        return False\\n\\n\\ndef encrypt(public_key_for_repo: str, secret_value_input: str) -> str:\\n    \\\"\\\"\\\"Encrypt a Unicode string using the public key.\\\"\\\"\\\"\\n    sealed_box = public.SealedBox(public.PublicKey(public_key_for_repo.encode(\\\"utf-8\\\"), encoding.Base64Encoder()))\\n    encrypted = sealed_box.encrypt(secret_value_input.encode(\\\"utf-8\\\"))\\n    return b64encode(encrypted).decode(\\\"utf-8\\\")\\n\\n\\ndef get_public_key(gh_base_url: str, gh_owner: str, gh_repo: str, gh_auth_token: str) -> (str, str):\\n    public_key_endpoint: str = f\\\"{gh_base_url}/{gh_owner}/{gh_repo}/actions/secrets/public-key\\\"\\n    headers: TypedDict[str, str] = {\\\"Authorization\\\": f\\\"Bearer {gh_auth_token}\\\"}\\n    response = requests.get(url=public_key_endpoint, headers=headers)\\n    if response.status_code != 200:\\n        raise IOError(\\n            f\\\"Could not get public key for repository {gh_owner}/{gh_repo}. The Response code was {response.status_code}\\\")\\n\\n    public_key_json = response.json()\\n    return public_key_json['key_id'], public_key_json['key']\\n\\n\\ndef set_secret(gh_base_url: str, gh_owner: str, gh_repo: str, gh_auth_token: str, public_key_id: str, secret_key: str,\\n               encrypted_secret_value: str):\\n    secret_creation_url = f\\\"{gh_base_url}/{gh_owner}/{gh_repo}/actions/secrets/{secret_key}\\\"\\n    secret_creation_body = {\\\"key_id\\\": public_key_id, \\\"encrypted_value\\\": encrypted_secret_value}\\n    headers: TypedDict[str, str] = {\\\"Authorization\\\": f\\\"Bearer {gh_auth_token}\\\", \\\"Content-Type\\\": \\\"application/json\\\"}\\n\\n    secret_creation_response = requests.put(url=secret_creation_url, json=secret_creation_body, headers=headers)\\n    if secret_creation_response.status_code == 201 or secret_creation_response.status_code == 204:\\n        print(\\\"--Secret Created / Updated!--\\\")\\n    else:\\n        print(f\\\"-- Error creating / updating github secret, the reason was : {secret_creation_response.reason}\\\")\\n\\n\\nparser, _ = init_argparse()\\n\\nif not parser.git_password.strip() and not (\\n        parser.github_app_id.strip() and parser.github_app_private_key.strip() and parser.github_app_installation_id.strip()):\\n    print(\\\"You must supply the GitHub token, or the GitHub App ID and private key and installation ID\\\")\\n    sys.exit(1)\\n\\nif not parser.git_organization.strip():\\n    print(\\\"You must define the organization\\\")\\n    sys.exit(1)\\n\\nif not parser.repo.strip():\\n    print(\\\"You must define the repo name\\\")\\n    sys.exit(1)\\n\\ntoken = generate_github_token(parser.github_app_id, parser.github_app_private_key,\\n                              parser.github_app_installation_id) if len(\\n    parser.git_password.strip()) == 0 else parser.git_password.strip()\\n\\nif not parser.git_password.strip() and not (\\n        parser.github_app_id.strip() and parser.github_app_private_key.strip() and parser.github_app_installation_id.strip()):\\n    print(\\\"You must supply the GitHub token, or the GitHub App ID and private key and installation ID\\\")\\n    sys.exit(1)\\n\\nif not parser.git_organization.strip():\\n    print(\\\"You must define the organization\\\")\\n    sys.exit(1)\\n\\nif not parser.repo.strip():\\n    print(\\\"You must define the repo name\\\")\\n    sys.exit(1)\\n\\nif not parser.secret_name.strip():\\n    print(\\\"You must define the secret name\\\")\\n    sys.exit(1)\\n    \\nif not verify_new_repo(token, parser.git_organization, parser.repo):\\n    print(\\\"Could not find the repo\\\")\\n    sys.exit(1)\\n\\nkey_id, public_key = get_public_key('https://api.github.com/repos', parser.git_organization, parser.repo,\\n                                    token)\\nencrypted_secret: str = encrypt(public_key_for_repo=public_key, secret_value_input=parser.secret_value)\\nset_secret(gh_base_url='https://api.github.com/repos', gh_owner=parser.git_organization, gh_repo=parser.repo,\\n           gh_auth_token=token, public_key_id=key_id, secret_key=parser.secret_name,\\n           encrypted_secret_value=encrypted_secret)\\n\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n  step {\n    condition           = \"Success\"\n    name                = \"Create Docker Hub Password Secret\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Create Docker Hub Password Secret\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"CreateGitHubSecret.Git.Credentials.Password\" = \"#{Git.Credentials.Password}\"\n        \"CreateGitHubSecret.GitHub.Secret.Name\"       = \"DOCKERHUB_TOKEN\"\n        \"Octopus.Action.Script.Syntax\"                = \"Python\"\n        \"CreateGitHubSecret.GitHub.Secret.Value\"      = \"#{Docker.Credentials.Password}\"\n        \"CreateGitHubSecret.Git.Url.Organization\"     = \"#{Git.Url.Organization}\"\n        \"Octopus.Action.Script.ScriptSource\"          = \"Inline\"\n        \"Octopus.Action.RunOnServer\"                  = \"true\"\n        \"CreateGitHubSecret.Git.Url.Repo\"             = \"#{Octopus.Action[Create Repo].Output.NewRepo}\"\n        \"Octopus.Action.Script.ScriptBody\"            = \"# https://gist.github.com/comdotlinux/9a53bb00767a16d6646464c4b8249094\\n\\n# This script forks a GitHub repo. It creates a token from a GitHub App installation to avoid\\n# having to use a regular user account.\\nimport subprocess\\nimport sys\\n\\n# Install our own dependencies\\nsubprocess.check_call([sys.executable, '-m', 'pip', 'install', 'jwt', '--disable-pip-version-check'])\\nsubprocess.check_call([sys.executable, '-m', 'pip', 'install', 'pynacl', '--disable-pip-version-check'])\\n\\nimport requests\\nimport json\\nimport subprocess\\nimport sys\\nimport os\\nimport urllib.request\\nimport base64\\nimport re\\nimport jwt\\nimport time\\nimport argparse\\nimport urllib3\\nfrom base64 import b64encode\\nfrom typing import TypedDict\\nfrom nacl import public, encoding\\n\\n# Disable insecure http request warnings\\nurllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)\\n\\n# If this script is not being run as part of an Octopus step, setting variables is a noop\\nif 'set_octopusvariable' not in globals():\\n    def set_octopusvariable(variable, value):\\n        pass\\n\\n# If this script is not being run as part of an Octopus step, return variables from environment variables.\\n# Periods are replaced with underscores, and the variable name is converted to uppercase\\nif \\\"get_octopusvariable\\\" not in globals():\\n    def get_octopusvariable(variable):\\n        return os.environ[re.sub('\\\\\\\\.', '_', variable.upper())]\\n\\n# If this script is not being run as part of an Octopus step, print directly to std out.\\nif 'printverbose' not in globals():\\n    def printverbose(msg):\\n        print(msg)\\n\\n\\ndef printverbose_noansi(output):\\n    \\\"\\\"\\\"\\n    Strip ANSI color codes and print the output as verbose\\n    :param output: The output to print\\n    \\\"\\\"\\\"\\n    output_no_ansi = re.sub(r'\\\\x1b\\\\[[0-9;]*m', '', output)\\n    printverbose(output_no_ansi)\\n\\n\\ndef get_octopusvariable_quiet(variable):\\n    \\\"\\\"\\\"\\n    Gets an octopus variable, or an empty string if it does not exist.\\n    :param variable: The variable name\\n    :return: The variable value, or an empty string if the variable does not exist\\n    \\\"\\\"\\\"\\n    try:\\n        return get_octopusvariable(variable)\\n    except:\\n        return ''\\n\\n\\ndef execute(args, cwd=None, env=None, print_args=None, print_output=printverbose_noansi, raise_on_non_zero=False,\\n            append_to_path=None):\\n    \\\"\\\"\\\"\\n        The execute method provides the ability to execute external processes while capturing and returning the\\n        output to std err and std out and exit code.\\n    \\\"\\\"\\\"\\n\\n    my_env = os.environ.copy() if env is None else env\\n\\n    if append_to_path is not None:\\n        my_env[\\\"PATH\\\"] = append_to_path + os.pathsep + my_env['PATH']\\n\\n    process = subprocess.Popen(args,\\n                               stdout=subprocess.PIPE,\\n                               stderr=subprocess.PIPE,\\n                               stdin=open(os.devnull),\\n                               text=True,\\n                               cwd=cwd,\\n                               env=my_env)\\n    stdout, stderr = process.communicate()\\n    retcode = process.returncode\\n\\n    if not retcode == 0 and raise_on_non_zero:\\n        raise Exception('command returned exit code ' + retcode)\\n\\n    if print_args is not None:\\n        print_output(' '.join(args))\\n\\n    if print_output is not None:\\n        print_output(stdout)\\n        print_output(stderr)\\n\\n    return stdout, stderr, retcode\\n\\n\\ndef init_argparse():\\n    parser = argparse.ArgumentParser(\\n        usage='%(prog)s [OPTION]',\\n        description='Fork a GitHub repo'\\n    )\\n\\n    parser.add_argument('--secret-name', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.GitHub.Secret.Name') or get_octopusvariable_quiet(\\n                            'GitHub.Secret.Name'))\\n    parser.add_argument('--secret-value', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.GitHub.Secret.Value') or get_octopusvariable_quiet(\\n                            'GitHub.Secret.Value'))\\n\\n    parser.add_argument('--repo', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.Git.Url.Repo') or get_octopusvariable_quiet(\\n                            'Git.Url.Repo') or get_octopusvariable_quiet('Octopus.Project.Name'))\\n    parser.add_argument('--git-organization', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.Git.Url.Organization') or get_octopusvariable_quiet(\\n                            'Git.Url.Organization'))\\n    parser.add_argument('--github-app-id', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.GitHub.App.Id') or get_octopusvariable_quiet('GitHub.App.Id'))\\n    parser.add_argument('--github-app-installation-id', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.GitHub.App.InstallationId') or get_octopusvariable_quiet(\\n                            'GitHub.App.InstallationId'))\\n    parser.add_argument('--github-app-private-key', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.GitHub.App.PrivateKey') or get_octopusvariable_quiet(\\n                            'GitHub.App.PrivateKey'))\\n    parser.add_argument('--git-password', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.Git.Credentials.Password') or get_octopusvariable_quiet(\\n                            'Git.Credentials.Password'),\\n                        help='The git password. This takes precedence over the --github-app-id,  --github-app-installation-id, and --github-app-private-key')\\n\\n    return parser.parse_known_args()\\n\\n\\ndef generate_github_token(github_app_id, github_app_private_key, github_app_installation_id):\\n    # Generate the tokens used by git and the GitHub API\\n    app_id = github_app_id\\n    signing_key = jwt.jwk_from_pem(github_app_private_key.encode('utf-8'))\\n\\n    payload = {\\n        # Issued at time\\n        'iat': int(time.time()),\\n        # JWT expiration time (10 minutes maximum)\\n        'exp': int(time.time()) + 600,\\n        # GitHub App's identifier\\n        'iss': app_id\\n    }\\n\\n    # Create JWT\\n    jwt_instance = jwt.JWT()\\n    encoded_jwt = jwt_instance.encode(payload, signing_key, alg='RS256')\\n\\n    # Create access token\\n    url = 'https://api.github.com/app/installations/' + github_app_installation_id + '/access_tokens'\\n    headers = {\\n        'Authorization': 'Bearer ' + encoded_jwt,\\n        'Accept': 'application/vnd.github+json',\\n        'X-GitHub-Api-Version': '2022-11-28'\\n    }\\n    request = urllib.request.Request(url, headers=headers, method='POST')\\n    response = urllib.request.urlopen(request)\\n    response_json = json.loads(response.read().decode())\\n    return response_json['token']\\n\\n\\ndef generate_auth_header(token):\\n    auth = base64.b64encode(('x-access-token:' + token).encode('ascii'))\\n    return 'Basic ' + auth.decode('ascii')\\n\\n\\ndef verify_new_repo(token, cac_org, new_repo):\\n    # Attempt to view the new repo\\n    try:\\n        url = 'https://api.github.com/repos/' + cac_org + '/' + new_repo\\n        headers = {\\n            'Accept': 'application/vnd.github+json',\\n            'Authorization': 'Bearer ' + token,\\n            'X-GitHub-Api-Version': '2022-11-28'\\n        }\\n        request = urllib.request.Request(url, headers=headers)\\n        urllib.request.urlopen(request)\\n        return True\\n    except:\\n        return False\\n\\n\\ndef encrypt(public_key_for_repo: str, secret_value_input: str) -> str:\\n    \\\"\\\"\\\"Encrypt a Unicode string using the public key.\\\"\\\"\\\"\\n    sealed_box = public.SealedBox(public.PublicKey(public_key_for_repo.encode(\\\"utf-8\\\"), encoding.Base64Encoder()))\\n    encrypted = sealed_box.encrypt(secret_value_input.encode(\\\"utf-8\\\"))\\n    return b64encode(encrypted).decode(\\\"utf-8\\\")\\n\\n\\ndef get_public_key(gh_base_url: str, gh_owner: str, gh_repo: str, gh_auth_token: str) -> (str, str):\\n    public_key_endpoint: str = f\\\"{gh_base_url}/{gh_owner}/{gh_repo}/actions/secrets/public-key\\\"\\n    headers: TypedDict[str, str] = {\\\"Authorization\\\": f\\\"Bearer {gh_auth_token}\\\"}\\n    response = requests.get(url=public_key_endpoint, headers=headers)\\n    if response.status_code != 200:\\n        raise IOError(\\n            f\\\"Could not get public key for repository {gh_owner}/{gh_repo}. The Response code was {response.status_code}\\\")\\n\\n    public_key_json = response.json()\\n    return public_key_json['key_id'], public_key_json['key']\\n\\n\\ndef set_secret(gh_base_url: str, gh_owner: str, gh_repo: str, gh_auth_token: str, public_key_id: str, secret_key: str,\\n               encrypted_secret_value: str):\\n    secret_creation_url = f\\\"{gh_base_url}/{gh_owner}/{gh_repo}/actions/secrets/{secret_key}\\\"\\n    secret_creation_body = {\\\"key_id\\\": public_key_id, \\\"encrypted_value\\\": encrypted_secret_value}\\n    headers: TypedDict[str, str] = {\\\"Authorization\\\": f\\\"Bearer {gh_auth_token}\\\", \\\"Content-Type\\\": \\\"application/json\\\"}\\n\\n    secret_creation_response = requests.put(url=secret_creation_url, json=secret_creation_body, headers=headers)\\n    if secret_creation_response.status_code == 201 or secret_creation_response.status_code == 204:\\n        print(\\\"--Secret Created / Updated!--\\\")\\n    else:\\n        print(f\\\"-- Error creating / updating github secret, the reason was : {secret_creation_response.reason}\\\")\\n\\n\\nparser, _ = init_argparse()\\n\\nif not parser.git_password.strip() and not (\\n        parser.github_app_id.strip() and parser.github_app_private_key.strip() and parser.github_app_installation_id.strip()):\\n    print(\\\"You must supply the GitHub token, or the GitHub App ID and private key and installation ID\\\")\\n    sys.exit(1)\\n\\nif not parser.git_organization.strip():\\n    print(\\\"You must define the organization\\\")\\n    sys.exit(1)\\n\\nif not parser.repo.strip():\\n    print(\\\"You must define the repo name\\\")\\n    sys.exit(1)\\n\\ntoken = generate_github_token(parser.github_app_id, parser.github_app_private_key,\\n                              parser.github_app_installation_id) if len(\\n    parser.git_password.strip()) == 0 else parser.git_password.strip()\\n\\nif not parser.git_password.strip() and not (\\n        parser.github_app_id.strip() and parser.github_app_private_key.strip() and parser.github_app_installation_id.strip()):\\n    print(\\\"You must supply the GitHub token, or the GitHub App ID and private key and installation ID\\\")\\n    sys.exit(1)\\n\\nif not parser.git_organization.strip():\\n    print(\\\"You must define the organization\\\")\\n    sys.exit(1)\\n\\nif not parser.repo.strip():\\n    print(\\\"You must define the repo name\\\")\\n    sys.exit(1)\\n\\nif not parser.secret_name.strip():\\n    print(\\\"You must define the secret name\\\")\\n    sys.exit(1)\\n    \\nif not verify_new_repo(token, parser.git_organization, parser.repo):\\n    print(\\\"Could not find the repo\\\")\\n    sys.exit(1)\\n\\nkey_id, public_key = get_public_key('https://api.github.com/repos', parser.git_organization, parser.repo,\\n                                    token)\\nencrypted_secret: str = encrypt(public_key_for_repo=public_key, secret_value_input=parser.secret_value)\\nset_secret(gh_base_url='https://api.github.com/repos', gh_owner=parser.git_organization, gh_repo=parser.repo,\\n           gh_auth_token=token, public_key_id=key_id, secret_key=parser.secret_name,\\n           encrypted_secret_value=encrypted_secret)\\n\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n  step {\n    condition           = \"Success\"\n    name                = \"Create Docker Hub Password Username\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Create Docker Hub Password Username\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = false\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"CreateGitHubSecret.Git.Credentials.Password\" = \"#{Git.Credentials.Password}\"\n        \"Octopus.Action.RunOnServer\"                  = \"true\"\n        \"CreateGitHubSecret.GitHub.Secret.Value\"      = \"#{Docker.Credentials.Username}\"\n        \"CreateGitHubSecret.Git.Url.Repo\"             = \"#{Octopus.Action[Create Repo].Output.NewRepo}\"\n        \"Octopus.Action.Script.ScriptSource\"          = \"Inline\"\n        \"Octopus.Action.Script.ScriptBody\"            = \"# https://gist.github.com/comdotlinux/9a53bb00767a16d6646464c4b8249094\\n\\n# This script forks a GitHub repo. It creates a token from a GitHub App installation to avoid\\n# having to use a regular user account.\\nimport subprocess\\nimport sys\\n\\n# Install our own dependencies\\nsubprocess.check_call([sys.executable, '-m', 'pip', 'install', 'jwt', '--disable-pip-version-check'])\\nsubprocess.check_call([sys.executable, '-m', 'pip', 'install', 'pynacl', '--disable-pip-version-check'])\\n\\nimport requests\\nimport json\\nimport subprocess\\nimport sys\\nimport os\\nimport urllib.request\\nimport base64\\nimport re\\nimport jwt\\nimport time\\nimport argparse\\nimport urllib3\\nfrom base64 import b64encode\\nfrom typing import TypedDict\\nfrom nacl import public, encoding\\n\\n# Disable insecure http request warnings\\nurllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)\\n\\n# If this script is not being run as part of an Octopus step, setting variables is a noop\\nif 'set_octopusvariable' not in globals():\\n    def set_octopusvariable(variable, value):\\n        pass\\n\\n# If this script is not being run as part of an Octopus step, return variables from environment variables.\\n# Periods are replaced with underscores, and the variable name is converted to uppercase\\nif \\\"get_octopusvariable\\\" not in globals():\\n    def get_octopusvariable(variable):\\n        return os.environ[re.sub('\\\\\\\\.', '_', variable.upper())]\\n\\n# If this script is not being run as part of an Octopus step, print directly to std out.\\nif 'printverbose' not in globals():\\n    def printverbose(msg):\\n        print(msg)\\n\\n\\ndef printverbose_noansi(output):\\n    \\\"\\\"\\\"\\n    Strip ANSI color codes and print the output as verbose\\n    :param output: The output to print\\n    \\\"\\\"\\\"\\n    output_no_ansi = re.sub(r'\\\\x1b\\\\[[0-9;]*m', '', output)\\n    printverbose(output_no_ansi)\\n\\n\\ndef get_octopusvariable_quiet(variable):\\n    \\\"\\\"\\\"\\n    Gets an octopus variable, or an empty string if it does not exist.\\n    :param variable: The variable name\\n    :return: The variable value, or an empty string if the variable does not exist\\n    \\\"\\\"\\\"\\n    try:\\n        return get_octopusvariable(variable)\\n    except:\\n        return ''\\n\\n\\ndef execute(args, cwd=None, env=None, print_args=None, print_output=printverbose_noansi, raise_on_non_zero=False,\\n            append_to_path=None):\\n    \\\"\\\"\\\"\\n        The execute method provides the ability to execute external processes while capturing and returning the\\n        output to std err and std out and exit code.\\n    \\\"\\\"\\\"\\n\\n    my_env = os.environ.copy() if env is None else env\\n\\n    if append_to_path is not None:\\n        my_env[\\\"PATH\\\"] = append_to_path + os.pathsep + my_env['PATH']\\n\\n    process = subprocess.Popen(args,\\n                               stdout=subprocess.PIPE,\\n                               stderr=subprocess.PIPE,\\n                               stdin=open(os.devnull),\\n                               text=True,\\n                               cwd=cwd,\\n                               env=my_env)\\n    stdout, stderr = process.communicate()\\n    retcode = process.returncode\\n\\n    if not retcode == 0 and raise_on_non_zero:\\n        raise Exception('command returned exit code ' + retcode)\\n\\n    if print_args is not None:\\n        print_output(' '.join(args))\\n\\n    if print_output is not None:\\n        print_output(stdout)\\n        print_output(stderr)\\n\\n    return stdout, stderr, retcode\\n\\n\\ndef init_argparse():\\n    parser = argparse.ArgumentParser(\\n        usage='%(prog)s [OPTION]',\\n        description='Fork a GitHub repo'\\n    )\\n\\n    parser.add_argument('--secret-name', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.GitHub.Secret.Name') or get_octopusvariable_quiet(\\n                            'GitHub.Secret.Name'))\\n    parser.add_argument('--secret-value', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.GitHub.Secret.Value') or get_octopusvariable_quiet(\\n                            'GitHub.Secret.Value'))\\n\\n    parser.add_argument('--repo', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.Git.Url.Repo') or get_octopusvariable_quiet(\\n                            'Git.Url.Repo') or get_octopusvariable_quiet('Octopus.Project.Name'))\\n    parser.add_argument('--git-organization', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.Git.Url.Organization') or get_octopusvariable_quiet(\\n                            'Git.Url.Organization'))\\n    parser.add_argument('--github-app-id', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.GitHub.App.Id') or get_octopusvariable_quiet('GitHub.App.Id'))\\n    parser.add_argument('--github-app-installation-id', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.GitHub.App.InstallationId') or get_octopusvariable_quiet(\\n                            'GitHub.App.InstallationId'))\\n    parser.add_argument('--github-app-private-key', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.GitHub.App.PrivateKey') or get_octopusvariable_quiet(\\n                            'GitHub.App.PrivateKey'))\\n    parser.add_argument('--git-password', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'CreateGitHubSecret.Git.Credentials.Password') or get_octopusvariable_quiet(\\n                            'Git.Credentials.Password'),\\n                        help='The git password. This takes precedence over the --github-app-id,  --github-app-installation-id, and --github-app-private-key')\\n\\n    return parser.parse_known_args()\\n\\n\\ndef generate_github_token(github_app_id, github_app_private_key, github_app_installation_id):\\n    # Generate the tokens used by git and the GitHub API\\n    app_id = github_app_id\\n    signing_key = jwt.jwk_from_pem(github_app_private_key.encode('utf-8'))\\n\\n    payload = {\\n        # Issued at time\\n        'iat': int(time.time()),\\n        # JWT expiration time (10 minutes maximum)\\n        'exp': int(time.time()) + 600,\\n        # GitHub App's identifier\\n        'iss': app_id\\n    }\\n\\n    # Create JWT\\n    jwt_instance = jwt.JWT()\\n    encoded_jwt = jwt_instance.encode(payload, signing_key, alg='RS256')\\n\\n    # Create access token\\n    url = 'https://api.github.com/app/installations/' + github_app_installation_id + '/access_tokens'\\n    headers = {\\n        'Authorization': 'Bearer ' + encoded_jwt,\\n        'Accept': 'application/vnd.github+json',\\n        'X-GitHub-Api-Version': '2022-11-28'\\n    }\\n    request = urllib.request.Request(url, headers=headers, method='POST')\\n    response = urllib.request.urlopen(request)\\n    response_json = json.loads(response.read().decode())\\n    return response_json['token']\\n\\n\\ndef generate_auth_header(token):\\n    auth = base64.b64encode(('x-access-token:' + token).encode('ascii'))\\n    return 'Basic ' + auth.decode('ascii')\\n\\n\\ndef verify_new_repo(token, cac_org, new_repo):\\n    # Attempt to view the new repo\\n    try:\\n        url = 'https://api.github.com/repos/' + cac_org + '/' + new_repo\\n        headers = {\\n            'Accept': 'application/vnd.github+json',\\n            'Authorization': 'Bearer ' + token,\\n            'X-GitHub-Api-Version': '2022-11-28'\\n        }\\n        request = urllib.request.Request(url, headers=headers)\\n        urllib.request.urlopen(request)\\n        return True\\n    except:\\n        return False\\n\\n\\ndef encrypt(public_key_for_repo: str, secret_value_input: str) -> str:\\n    \\\"\\\"\\\"Encrypt a Unicode string using the public key.\\\"\\\"\\\"\\n    sealed_box = public.SealedBox(public.PublicKey(public_key_for_repo.encode(\\\"utf-8\\\"), encoding.Base64Encoder()))\\n    encrypted = sealed_box.encrypt(secret_value_input.encode(\\\"utf-8\\\"))\\n    return b64encode(encrypted).decode(\\\"utf-8\\\")\\n\\n\\ndef get_public_key(gh_base_url: str, gh_owner: str, gh_repo: str, gh_auth_token: str) -> (str, str):\\n    public_key_endpoint: str = f\\\"{gh_base_url}/{gh_owner}/{gh_repo}/actions/secrets/public-key\\\"\\n    headers: TypedDict[str, str] = {\\\"Authorization\\\": f\\\"Bearer {gh_auth_token}\\\"}\\n    response = requests.get(url=public_key_endpoint, headers=headers)\\n    if response.status_code != 200:\\n        raise IOError(\\n            f\\\"Could not get public key for repository {gh_owner}/{gh_repo}. The Response code was {response.status_code}\\\")\\n\\n    public_key_json = response.json()\\n    return public_key_json['key_id'], public_key_json['key']\\n\\n\\ndef set_secret(gh_base_url: str, gh_owner: str, gh_repo: str, gh_auth_token: str, public_key_id: str, secret_key: str,\\n               encrypted_secret_value: str):\\n    secret_creation_url = f\\\"{gh_base_url}/{gh_owner}/{gh_repo}/actions/secrets/{secret_key}\\\"\\n    secret_creation_body = {\\\"key_id\\\": public_key_id, \\\"encrypted_value\\\": encrypted_secret_value}\\n    headers: TypedDict[str, str] = {\\\"Authorization\\\": f\\\"Bearer {gh_auth_token}\\\", \\\"Content-Type\\\": \\\"application/json\\\"}\\n\\n    secret_creation_response = requests.put(url=secret_creation_url, json=secret_creation_body, headers=headers)\\n    if secret_creation_response.status_code == 201 or secret_creation_response.status_code == 204:\\n        print(\\\"--Secret Created / Updated!--\\\")\\n    else:\\n        print(f\\\"-- Error creating / updating github secret, the reason was : {secret_creation_response.reason}\\\")\\n\\n\\nparser, _ = init_argparse()\\n\\nif not parser.git_password.strip() and not (\\n        parser.github_app_id.strip() and parser.github_app_private_key.strip() and parser.github_app_installation_id.strip()):\\n    print(\\\"You must supply the GitHub token, or the GitHub App ID and private key and installation ID\\\")\\n    sys.exit(1)\\n\\nif not parser.git_organization.strip():\\n    print(\\\"You must define the organization\\\")\\n    sys.exit(1)\\n\\nif not parser.repo.strip():\\n    print(\\\"You must define the repo name\\\")\\n    sys.exit(1)\\n\\ntoken = generate_github_token(parser.github_app_id, parser.github_app_private_key,\\n                              parser.github_app_installation_id) if len(\\n    parser.git_password.strip()) == 0 else parser.git_password.strip()\\n\\nif not parser.git_password.strip() and not (\\n        parser.github_app_id.strip() and parser.github_app_private_key.strip() and parser.github_app_installation_id.strip()):\\n    print(\\\"You must supply the GitHub token, or the GitHub App ID and private key and installation ID\\\")\\n    sys.exit(1)\\n\\nif not parser.git_organization.strip():\\n    print(\\\"You must define the organization\\\")\\n    sys.exit(1)\\n\\nif not parser.repo.strip():\\n    print(\\\"You must define the repo name\\\")\\n    sys.exit(1)\\n\\nif not parser.secret_name.strip():\\n    print(\\\"You must define the secret name\\\")\\n    sys.exit(1)\\n    \\nif not verify_new_repo(token, parser.git_organization, parser.repo):\\n    print(\\\"Could not find the repo\\\")\\n    sys.exit(1)\\n\\nkey_id, public_key = get_public_key('https://api.github.com/repos', parser.git_organization, parser.repo,\\n                                    token)\\nencrypted_secret: str = encrypt(public_key_for_repo=public_key, secret_value_input=parser.secret_value)\\nset_secret(gh_base_url='https://api.github.com/repos', gh_owner=parser.git_organization, gh_repo=parser.repo,\\n           gh_auth_token=token, public_key_id=key_id, secret_key=parser.secret_name,\\n           encrypted_secret_value=encrypted_secret)\\n\"\n        \"CreateGitHubSecret.Git.Url.Organization\"     = \"#{Git.Url.Organization}\"\n        \"CreateGitHubSecret.GitHub.Secret.Name\"       = \"DOCKERHUB_USERNAME\"\n        \"Octopus.Action.Script.Syntax\"                = \"Python\"\n      }\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n      features              = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n  step {\n    condition           = \"Success\"\n    name                = \"Generate and Push\"\n    package_requirement = \"LetOctopusDecide\"\n    start_trigger       = \"StartAfterPrevious\"\n\n    action {\n      action_type                        = \"Octopus.Script\"\n      name                               = \"Generate and Push\"\n      condition                          = \"Success\"\n      run_on_server                      = true\n      is_disabled                        = false\n      can_be_used_for_project_versioning = true\n      is_required                        = false\n      worker_pool_id                     = local.worker_pool_id\n      properties                         = {\n        \"PopulateGithubRepo.Yeoman.Generator.SubGenerator\" = \"nodejs-docker-webapp\"\n        \"PopulateGithubRepo.Yeoman.Generator.Arguments\"    = \"--octopusUrl #{Octopus.Action[Get Variables].Output.Web.ServerUri} --octopusSpace \\\"#{Octopus.Action[Get Variables].Output.Space.Name}\\\" --octopusApi #{Octopus.ApiKey} --octopusProject \\\"#{Application.Octopus.Project}\\\" --dockerImage #{Application.Docker.Image}\"\n        \"PopulateGithubRepo.Yeoman.Generator.Name\"         = \"octopus-reference-architecture-apps\"\n        \"Octopus.Action.Script.Syntax\"                     = \"Python\"\n        \"Octopus.Action.Script.ScriptSource\"               = \"Inline\"\n        \"Octopus.Action.Script.ScriptBody\"                 = \"# This script forks a GitHub repo. It creates a token from a GitHub App installation to avoid\\n# having to use a regular user account.\\nimport subprocess\\nimport sys\\n\\n# Install our own dependencies\\nenv_vars = os.environ.copy()\\nenv_vars['PIP_ROOT_USER_ACTION'] = 'ignore'\\nsubprocess.check_call([sys.executable, '-m', 'pip', 'install', 'jwt', '--disable-pip-version-check'], env=env_vars)\\nsubprocess.check_call([sys.executable, '-m', 'pip', 'install', 'requests', '--disable-pip-version-check'], env=env_vars)\\nsubprocess.check_call([sys.executable, '-m', 'pip', 'install', 'anyascii', '--disable-pip-version-check'], env=env_vars)\\n\\nimport requests\\nimport json\\nimport subprocess\\nimport sys\\nimport os\\nimport urllib.request\\nimport base64\\nimport re\\nimport jwt\\nimport time\\nimport argparse\\nimport platform\\nimport zipfile\\nimport lzma\\nimport tarfile\\nimport shutil\\nimport urllib3\\nfrom shlex import split\\nfrom anyascii import anyascii\\n\\n# Disable insecure http request warnings\\nurllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)\\n\\n# If this script is not being run as part of an Octopus step, setting variables is a noop\\nif 'set_octopusvariable' not in globals():\\n    def set_octopusvariable(variable, value):\\n        pass\\n\\n# If this script is not being run as part of an Octopus step, return variables from environment variables.\\n# Periods are replaced with underscores, and the variable name is converted to uppercase\\nif \\\"get_octopusvariable\\\" not in globals():\\n    def get_octopusvariable(variable):\\n        return os.environ[re.sub('\\\\\\\\.', '_', variable.upper())]\\n\\n# If this script is not being run as part of an Octopus step, print directly to std out.\\nif 'printverbose' not in globals():\\n    def printverbose(msg):\\n        print(msg)\\n\\n\\ndef printverbose_noansi(output):\\n    \\\"\\\"\\\"\\n    Strip ANSI color codes and print the output as verbose\\n    :param output: The output to print\\n    \\\"\\\"\\\"\\n    output_no_ansi = re.sub(r'\\\\x1b\\\\[[0-9;]*m', '', output)\\n    printverbose(output_no_ansi)\\n\\n\\ndef get_octopusvariable_quiet(variable):\\n    \\\"\\\"\\\"\\n    Gets an octopus variable, or an empty string if it does not exist.\\n    :param variable: The variable name\\n    :return: The variable value, or an empty string if the variable does not exist\\n    \\\"\\\"\\\"\\n    try:\\n        return get_octopusvariable(variable)\\n    except Exception as inst:\\n        return ''\\n\\n\\ndef execute(args, cwd=None, env=None, print_args=None, print_output=printverbose_noansi, raise_on_non_zero=False,\\n            append_to_path=None):\\n    \\\"\\\"\\\"\\n        The execute method provides the ability to execute external processes while capturing and returning the\\n        output to std err and std out and exit code.\\n    \\\"\\\"\\\"\\n\\n    my_env = os.environ.copy() if env is None else env\\n\\n    if append_to_path is not None:\\n        my_env[\\\"PATH\\\"] = append_to_path + os.pathsep + my_env['PATH']\\n\\n    process = subprocess.Popen(args,\\n                               stdout=subprocess.PIPE,\\n                               stderr=subprocess.PIPE,\\n                               stdin=open(os.devnull),\\n                               text=True,\\n                               cwd=cwd,\\n                               env=my_env)\\n    stdout, stderr = process.communicate()\\n    retcode = process.returncode\\n\\n    if not retcode == 0 and raise_on_non_zero:\\n        raise Exception('command returned exit code ' + retcode)\\n\\n    if print_args is not None:\\n        print_output(' '.join(args))\\n\\n    if print_output is not None:\\n        print_output(stdout)\\n        print_output(stderr)\\n\\n    return stdout, stderr, retcode\\n\\n\\ndef init_argparse():\\n    parser = argparse.ArgumentParser(\\n        usage='%(prog)s [OPTION]',\\n        description='Fork a GitHub repo'\\n    )\\n    parser.add_argument('--generator', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'PopulateGithubRepo.Yeoman.Generator.Name') or get_octopusvariable_quiet(\\n                            'Yeoman.Generator.Name'))\\n    parser.add_argument('--sub-generator', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'PopulateGithubRepo.Yeoman.Generator.SubGenerator') or get_octopusvariable_quiet(\\n                            'Yeoman.Generator.SubGenerator'))\\n    parser.add_argument('--generator-arguments', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'PopulateGithubRepo.Yeoman.Generator.Arguments') or get_octopusvariable_quiet(\\n                            'Yeoman.Generator.Arguments'),\\n                        help='The arguments to pas to yo. Pass all arguments as a single string. This string is then parsed as if it were yo arguments.')\\n    parser.add_argument('--repo', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'PopulateGithubRepo.Git.Url.Repo') or get_octopusvariable_quiet(\\n                            'Git.Url.Repo'))\\n    parser.add_argument('--git-organization', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'PopulateGithubRepo.Git.Url.Organization') or get_octopusvariable_quiet(\\n                            'Git.Url.Organization'))\\n    parser.add_argument('--github-app-id', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'PopulateGithubRepo.GitHub.App.Id') or get_octopusvariable_quiet('GitHub.App.Id'))\\n    parser.add_argument('--github-app-installation-id', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'PopulateGithubRepo.GitHub.App.InstallationId') or get_octopusvariable_quiet(\\n                            'GitHub.App.InstallationId'))\\n    parser.add_argument('--github-app-private-key', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'PopulateGithubRepo.GitHub.App.PrivateKey') or get_octopusvariable_quiet(\\n                            'GitHub.App.PrivateKey'))\\n    parser.add_argument('--git-password', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'PopulateGithubRepo.Git.Credentials.Password') or get_octopusvariable_quiet(\\n                            'Git.Credentials.Password'),\\n                        help='The git password. This takes precedence over the --github-app-id,  --github-app-installation-id, and --github-app-private-key')\\n    parser.add_argument('--git-username', action='store',\\n                        default=get_octopusvariable_quiet(\\n                            'PopulateGithubRepo.Git.Credentials.Username') or get_octopusvariable_quiet(\\n                            'Git.Credentials.Username'),\\n                        help='The git username. This will be used for both the git authentication and the username associated with any commits.')\\n\\n    return parser.parse_known_args()\\n\\n\\ndef generate_github_token(github_app_id, github_app_private_key, github_app_installation_id):\\n    # Generate the tokens used by git and the GitHub API\\n    app_id = github_app_id\\n    signing_key = jwt.jwk_from_pem(github_app_private_key.encode('utf-8'))\\n\\n    payload = {\\n        # Issued at time\\n        'iat': int(time.time()),\\n        # JWT expiration time (10 minutes maximum)\\n        'exp': int(time.time()) + 600,\\n        # GitHub App's identifier\\n        'iss': app_id\\n    }\\n\\n    # Create JWT\\n    jwt_instance = jwt.JWT()\\n    encoded_jwt = jwt_instance.encode(payload, signing_key, alg='RS256')\\n\\n    # Create access token\\n    url = 'https://api.github.com/app/installations/' + github_app_installation_id + '/access_tokens'\\n    headers = {\\n        'Authorization': 'Bearer ' + encoded_jwt,\\n        'Accept': 'application/vnd.github+json',\\n        'X-GitHub-Api-Version': '2022-11-28'\\n    }\\n    request = urllib.request.Request(url, headers=headers, method='POST')\\n    response = urllib.request.urlopen(request)\\n    response_json = json.loads(response.read().decode())\\n    return response_json['token']\\n\\n\\ndef generate_auth_header(token):\\n    auth = base64.b64encode(('x-access-token:' + token).encode('ascii'))\\n    return 'Basic ' + auth.decode('ascii')\\n\\n\\ndef verify_new_repo(token, cac_org, new_repo):\\n    # Attempt to view the new repo\\n    try:\\n        url = 'https://api.github.com/repos/' + cac_org + '/' + new_repo\\n        headers = {\\n            'Accept': 'application/vnd.github+json',\\n            'Authorization': 'Bearer ' + token,\\n            'X-GitHub-Api-Version': '2022-11-28'\\n        }\\n        request = urllib.request.Request(url, headers=headers)\\n        urllib.request.urlopen(request)\\n        return True\\n    except Exception as inst:\\n        return False\\n\\n\\ndef is_windows():\\n    return platform.system() == 'Windows'\\n\\n\\ndef download_file(url, filename, verify_ssl=True):\\n    r = requests.get(url, verify=verify_ssl)\\n    with open(filename, 'wb') as file:\\n        file.write(r.content)\\n\\n\\ndef ensure_git_exists():\\n    if is_windows():\\n        print(\\\"Checking git is installed\\\")\\n        try:\\n            stdout, _, exit_code = execute(['git', 'version'])\\n            printverbose(stdout)\\n            if not exit_code == 0:\\n                raise \\\"git not found\\\"\\n        except:\\n            print(\\\"Downloading git\\\")\\n            download_file('https://www.7-zip.org/a/7zr.exe', '7zr.exe')\\n            download_file(\\n                'https://github.com/git-for-windows/git/releases/download/v2.42.0.windows.2/PortableGit-2.42.0.2-64-bit.7z.exe',\\n                'PortableGit.7z.exe')\\n            print(\\\"Installing git\\\")\\n            print(\\\"Consider installing git on the worker or using a standard worker-tools image\\\")\\n            execute(['7zr.exe', 'x', 'PortableGit.7z.exe', '-o' + os.path.join(os.getcwd(), 'git'), '-y'])\\n            return os.path.join(os.getcwd(), 'git', 'bin', 'git')\\n\\n    return 'git'\\n\\n\\ndef install_npm_linux():\\n    print(\\\"Downloading node\\\")\\n    download_file(\\n        'https://nodejs.org/dist/v18.18.2/node-v18.18.2-linux-x64.tar.xz',\\n        'node.tar.xz')\\n    print(\\\"Installing node on Linux\\\")\\n    with lzma.open(\\\"node.tar.xz\\\", \\\"r\\\") as lzma_ref:\\n        with open(\\\"node.tar\\\", \\\"wb\\\") as fdst:\\n            shutil.copyfileobj(lzma_ref, fdst)\\n    with tarfile.open(\\\"node.tar\\\", \\\"r\\\") as tar_ref:\\n        tar_ref.extractall(os.getcwd())\\n\\n    try:\\n        _, _, exit_code = execute([os.getcwd() + '/node-v18.18.2-linux-x64/bin/npm', '--version'],\\n                                  append_to_path=os.getcwd() + '/node-v18.18.2-linux-x64/bin')\\n        if not exit_code == 0:\\n            raise Exception(\\\"Failed to run npm\\\")\\n    except Exception as ex:\\n        print('Failed to install npm ' + str(ex))\\n        sys.exit(1)\\n    return os.getcwd() + '/node-v18.18.2-linux-x64/bin/npm', os.getcwd() + '/node-v18.18.2-linux-x64/bin'\\n\\n\\ndef install_npm_windows():\\n    print(\\\"Downloading node\\\")\\n    download_file('https://nodejs.org/dist/v18.18.2/node-v18.18.2-win-x64.zip', 'node.zip', False)\\n    print(\\\"Installing node on Windows\\\")\\n    with zipfile.ZipFile(\\\"node.zip\\\", \\\"r\\\") as zip_ref:\\n        zip_ref.extractall(os.getcwd())\\n    try:\\n        _, _, exit_code = execute([os.path.join(os.getcwd(), 'node-v18.18.2-win-x64', 'npm.cmd'), '--version'],\\n                                  append_to_path=os.path.join(os.getcwd(), 'node-v18.18.2-win-x64'))\\n        if not exit_code == 0:\\n            raise Exception(\\\"Failed to run npm\\\")\\n    except Exception as ex:\\n        print('Failed to install npm ' + str(ex))\\n        sys.exit(1)\\n\\n    return (os.path.join(os.getcwd(), 'node-v18.18.2-win-x64', 'npm.cmd'),\\n            os.path.join(os.getcwd(), 'node-v18.18.2-win-x64'))\\n\\n\\ndef ensure_node_exists():\\n    try:\\n        print(\\\"Checking node is installed\\\")\\n        _, _, exit_code = execute(['npm', '--version'])\\n        if not exit_code == 0:\\n            raise Exception(\\\"npm not found\\\")\\n    except:\\n        if is_windows():\\n            return install_npm_windows()\\n        else:\\n            return install_npm_linux()\\n\\n    return 'npm', None\\n\\n\\ndef ensure_yo_exists(npm_executable, npm_path):\\n    try:\\n        print(\\\"Checking Yeoman is installed\\\")\\n        _, _, exit_code = execute(['yo', '--version'])\\n        if not exit_code == 0:\\n            raise Exception(\\\"yo not found\\\")\\n    except:\\n        print('Installing Yeoman')\\n\\n        _, _, retcode = execute([npm_executable, 'install', '-g', 'yo'], append_to_path=npm_path)\\n\\n        if not retcode == 0:\\n            print(\\\"Failed to set install Yeoman. Check the verbose logs for details.\\\")\\n            sys.exit(1)\\n\\n        npm_bin, _, retcode = execute([npm_executable, 'config', 'get', 'prefix'], append_to_path=npm_path)\\n\\n        if not retcode == 0:\\n            print(\\\"Failed to set get the npm prefix directory. Check the verbose logs for details.\\\")\\n            sys.exit(1)\\n\\n        try:\\n            if is_windows():\\n                _, _, exit_code = execute([os.path.join(npm_bin.strip(), 'yo.cmd'), '--version'],\\n                                          append_to_path=npm_path)\\n            else:\\n                _, _, exit_code = execute([os.path.join(npm_bin.strip(), 'bin', 'yo'), '--version'],\\n                                          append_to_path=npm_path)\\n\\n            if not exit_code == 0:\\n                raise Exception(\\\"Failed to run yo\\\")\\n        except Exception as ex:\\n            print('Failed to install yo ' + str(ex))\\n            sys.exit(1)\\n\\n        # Windows and Linux save NPM binaries in different directories\\n        if is_windows():\\n            return os.path.join(npm_bin.strip(), 'yo.cmd')\\n\\n        return os.path.join(npm_bin.strip(), 'bin', 'yo')\\n\\n    return 'yo'\\n\\n\\ngit_executable = ensure_git_exists()\\nnpm_executable, npm_path = ensure_node_exists()\\nyo_executable = ensure_yo_exists(npm_executable, npm_path)\\nparser, _ = init_argparse()\\n\\nif not parser.git_password.strip() and not (\\n        parser.github_app_id.strip() and parser.github_app_private_key.strip() and parser.github_app_installation_id.strip()):\\n    print(\\\"You must supply the GitHub token, or the GitHub App ID and private key and installation ID\\\")\\n    sys.exit(1)\\n\\nif not parser.git_organization.strip():\\n    print(\\\"You must define the organization\\\")\\n    sys.exit(1)\\n\\nif not parser.repo.strip():\\n    print(\\\"You must define the repo name\\\")\\n    sys.exit(1)\\n\\nif not parser.generator.strip():\\n    print(\\\"You must define the Yeoman generator\\\")\\n    sys.exit(1)\\n\\n# Create a dir for the git clone\\nif os.path.exists('downstream'):\\n    shutil.rmtree('downstream')\\n\\nos.mkdir('downstream')\\n\\n# Create a dir for yeoman to use\\nif os.path.exists('downstream-yeoman'):\\n    shutil.rmtree('downstream-yeoman')\\n\\nos.mkdir('downstream-yeoman')\\n# Yeoman will use a less privileged user to write to this directory, so grant full access\\nif not is_windows():\\n    os.chmod('downstream-yeoman', 0o777)\\n\\ndownstream_dir = os.path.join(os.getcwd(), 'downstream')\\ndownstream_yeoman_dir = os.path.join(os.getcwd(), 'downstream-yeoman')\\n\\n# The access token is generated from a github app or supplied directly as an access token\\ntoken = generate_github_token(parser.github_app_id, parser.github_app_private_key,\\n                              parser.github_app_installation_id) if len(\\n    parser.git_password.strip()) == 0 else parser.git_password.strip()\\n\\nif not verify_new_repo(token, parser.git_organization, parser.repo):\\n    print('Repo at https://github.com/' + parser.git_organization + '/' + parser.repo + ' could not be accessed')\\n    sys.exit(1)\\n\\n# We need to disable the credentials helper prompt, which will pop open a GUI prompt that we can never close\\nif is_windows():\\n    _, _, retcode = execute([git_executable, 'config', '--system', 'credential.helper', 'manager'])\\n\\n    if not retcode == 0:\\n        print(\\\"Failed to set the credential.helper setting. Check the verbose logs for details.\\\")\\n        sys.exit(1)\\n\\n    _, _, retcode = execute([git_executable, 'config', '--system', 'credential.modalprompt', 'false'])\\n\\n    if not retcode == 0:\\n        print(\\\"Failed to srt the credential.modalprompt setting. Check the verbose logs for details.\\\")\\n        sys.exit(1)\\n\\n    # We need to disable the credentials helper prompt, which will pop open a GUI prompt that we can never close\\n    _, _, retcode = execute(\\n        [git_executable, 'config', '--system', 'credential.microsoft.visualstudio.com.interactive', 'never'])\\n\\n    if not retcode == 0:\\n        print(\\n            \\\"Failed to set the credential.microsoft.visualstudio.com.interactive setting. Check the verbose logs for details.\\\")\\n        sys.exit(1)\\n\\n_, _, retcode = execute([git_executable, 'config', '--global', 'user.email', 'octopus@octopus.com'])\\n\\nif not retcode == 0:\\n    print(\\\"Failed to set the user.email setting. Check the verbose logs for details.\\\")\\n    sys.exit(1)\\n\\n_, _, retcode = execute([git_executable, 'config', '--global', 'core.autocrlf', 'input'])\\n\\nif not retcode == 0:\\n    print(\\\"Failed to set the core.autocrlf setting. Check the verbose logs for details.\\\")\\n    sys.exit(1)\\n\\nusername = parser.git_username if len(parser.git_username) != 0 else 'Octopus'\\n_, _, retcode = execute([git_executable, 'config', '--global', 'user.name', username])\\n\\nif not retcode == 0:\\n    print(\\\"Failed to set the git username. Check the verbose logs for details.\\\")\\n    sys.exit(1)\\n\\n_, _, retcode = execute([git_executable, 'config', '--global', 'credential.helper', 'cache'])\\n\\nif not retcode == 0:\\n    print(\\\"Failed to set the git credential helper. Check the verbose logs for details.\\\")\\n    sys.exit(1)\\n\\nprint('Cloning repo')\\n\\n_, _, retcode = execute(\\n    [git_executable, 'clone',\\n     'https://' + username + ':' + token + '@github.com/' + parser.git_organization + '/' + parser.repo + '.git',\\n     'downstream'])\\n\\nif not retcode == 0:\\n    print(\\\"Failed to clone the git repo. Check the verbose logs for details.\\\")\\n    sys.exit(1)\\n\\nprint('Configuring Yeoman Generator')\\n\\n_, _, retcode = execute([npm_executable, 'install'], cwd=os.path.join(os.getcwd(), 'YeomanGenerator'), append_to_path=npm_path)\\n\\nif not retcode == 0:\\n    print(\\\"Failed to install the generator dependencies. Check the verbose logs for details.\\\")\\n    sys.exit(1)\\n\\n_, _, retcode = execute([npm_executable, 'link'], cwd=os.path.join(os.getcwd(), 'YeomanGenerator'), append_to_path=npm_path)\\n\\nif not retcode == 0:\\n    print(\\\"Failed to link the npm module. Check the verbose logs for details.\\\")\\n    sys.exit(1)\\n\\nprint('Running Yeoman Generator')\\n\\n# Treat the string of yo arguments as a raw input and parse it again. The resulting list of unknown arguments\\n# is then passed to yo. We have to convert the incoming values from utf to ascii when parsing a second time.\\nyo_args = split(anyascii(parser.generator_arguments))\\n\\ngenerator_name = parser.generator + ':' + parser.sub_generator if len(parser.sub_generator) != 0 else parser.generator\\n\\nyo_arguments = [yo_executable, generator_name, '--force', '--skip-install']\\n\\n# Yeoman has issues running as root, which it will often do in a container.\\n# So we run Yeoman in its own directory, and then copy the changes to the git directory.\\n_, _, retcode = execute(yo_arguments + yo_args, cwd=downstream_yeoman_dir, append_to_path=npm_path)\\n\\nif not retcode == 0:\\n    print(\\\"Failed to run Yeoman. Check the verbose logs for details.\\\")\\n    sys.exit(1)\\n\\nshutil.copytree(downstream_yeoman_dir, downstream_dir, dirs_exist_ok=True)\\n\\nprint('Adding changes to git')\\n\\n_, _, retcode = execute([git_executable, 'add', '.'], cwd=downstream_dir)\\n\\nif not retcode == 0:\\n    print(\\\"Failed to add the git changes. Check the verbose logs for details.\\\")\\n    sys.exit(1)\\n\\n# Check for pending changes\\n_, _, retcode = execute([git_executable, 'diff-index', '--quiet', 'HEAD'], cwd=downstream_dir)\\n\\nif not retcode == 0:\\n    print('Committing changes to git')\\n    _, _, retcode = execute([git_executable, 'commit', '-m',\\n                             'Added files from Yeoman generator ' + parser.generator + ':' + parser.sub_generator],\\n                            cwd=downstream_dir)\\n\\n    if not retcode == 0:\\n        print(\\\"Failed to set commit the git changes. Check the verbose logs for details.\\\")\\n        sys.exit(1)\\n\\n    print('Pushing changes to git')\\n\\n    _, _, retcode = execute([git_executable, 'push', 'origin', 'main'], cwd=downstream_dir)\\n\\n    if not retcode == 0:\\n        print(\\\"Failed to push the git changes. Check the verbose logs for details.\\\")\\n        sys.exit(1)\\n\"\n        \"PopulateGithubRepo.Yeoman.Generator.Package\"      = jsonencode({\n          \"PackageId\" = \"OctopusSolutionsEngineering/ReferenceArchitectureAppGenerators\"\n          \"FeedId\"    = local.github_feed_id\n        })\n        \"Octopus.Action.RunOnServer\"                  = \"true\"\n        \"PopulateGithubRepo.Git.Url.Organization\"     = \"#{Git.Url.Organization}\"\n        \"PopulateGithubRepo.Git.Url.Repo\"             = \"#{Octopus.Action[Create Repo].Output.NewRepo}\"\n        \"PopulateGithubRepo.Git.Credentials.Password\" = \"#{Git.Credentials.Password}\"\n      }\n\n      container {\n        feed_id = local.docker_hub_feed_id\n        image   = \"octopussamples/node-workertools\"\n      }\n\n      environments          = []\n      excluded_environments = []\n      channels              = []\n      tenant_tags           = []\n\n      package {\n        name                      = \"YeomanGenerator\"\n        package_id                = \"OctopusSolutionsEngineering/ReferenceArchitectureAppGenerators\"\n        acquisition_location      = \"Server\"\n        extract_during_deployment = false\n        feed_id                   = local.github_feed_id\n        properties                = {\n          Extract       = \"True\", PackageParameterName = \"PopulateGithubRepo.Yeoman.Generator.Package\", Purpose = \"\",\n          SelectionMode = \"deferred\"\n        }\n      }\n      features = []\n    }\n\n    properties   = {}\n    target_roles = []\n  }\n}\n#endregion\n\n#endregion\n",
    "Octopus.Action.Terraform.TemplateParameters": "{\"octopus_server\":\"#{ReferenceArchitecture.WebApp.Octopus.ServerUrl}\",\"octopus_apikey\":\"#{ReferenceArchitecture.WebApp.Octopus.ApiKey}\",\"octopus_space_id\":\"#{ReferenceArchitecture.WebApp.Octopus.SpaceId}\",\"feed_docker_hub_username\":\"#{ReferenceArchitecture.WebApp.Docker.Username}\",\"feed_docker_hub_password\":\"#{ReferenceArchitecture.WebApp.Docker.Password}\",\"github_access_token\":\"#{ReferenceArchitecture.WebApp.GitHub.AccessToken}\",\"azure_account_application_id\":\"#{ReferenceArchitecture.WebApp.Azure.ApplicationId}\",\"azure_account_subscription_id\":\"#{ReferenceArchitecture.WebApp.Azure.SubscriptionId}\",\"azure_account_tenant_id\":\"#{ReferenceArchitecture.WebApp.Azure.TenantId}\",\"azure_account_password\":\"#{ReferenceArchitecture.WebApp.Azure.AccountPassword}\"}",
    "OctopusUseBundledTooling": "False",
    "Octopus.Action.Terraform.AdditionalInitParams": "#{if ReferenceArchitecture.Terraform.InitArgs}#{ReferenceArchitecture.Terraform.InitArgs}#{/if}",
    "Octopus.Action.Terraform.AdditionalActionParams": "#{if ReferenceArchitecture.Terraform.ApplyArgs}#{ReferenceArchitecture.Terraform.ApplyArgs}#{/if}"
  },
  "Category": "Octopus",
  "HistoryUrl": "https://github.com/OctopusDeploy/Library/commits/master/step-templates//opt/buildagent/work/75443764cd38076d/step-templates/octopus-reference-architecture-webapp.json",
  "Website": "/step-templates/614ec627-22a1-442a-b6a1-d51ae7009999",
  "Logo": "iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAMAAACahl6sAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAC1QTFRFT6Tl////L5Pg8vj9Y67omsvwPJrisdfzfbzs5fL7y+T32Ov5isLucLXqvt31CJPHWwAABMJJREFUeNrs3deW4jAMAFDF3U75/89dlp0ZhiU4blJEjvQ8hYubLJsA00UCBCIQgQhEIAIRiEAEIhCBCEQgAhGIQAQiEIEIhD8kJm+t+QprfdKfB9HbYpx6CWfspj8HMi+gMgHL/AmQA8W3JTKH+ALFvzCeL0RbpyoCPE9IJeNOSQwh5Z3qd6yRGWQ2qi2cZQWxqj1WzQYSjeoJmJlAklOd4VlArOqPhQEkqBERToeMcfRJBkC0Uep8CfBpjz4JsHJ0zF3dkEWNje0kiB/sUC6eApndaIiCMyAa1PiwJ0AWhRGJHJJQHG2dC7h1rNbO1QOxSA7lNCkkKrQIpJCAB1GREILYIC1NAiwbpKFJgGWDNExcwGstfExcZBCHC6nOglshHtmhViLIig1RNBCN7qjtW8C0Z1UvJcC1Z9XmwMBzzvobmgAyEzgq91dtEEsBsQSQQAFZCSBAATEEEApHZbrVBIkkEIUPSVeB+KtALA0kXQUSrwKZBCIQBnk8Y4i5CsReBeKvkqLM+BCSDWJlrZFvGk9SRTHshkgjZCGAaArIxm3H3grhVzFlW2msfl1ca79UJ1bofYvsDHHlNdTZnlh5MghuPd5NdBDUNZHyCkfktIh03XzALGRPlBDPac7qgWjHZzWcmF5zmmkhidMQ6boKiDXcDTUEaylZqCGJ0Vjvu/fLJtHqhSANEvqb2OYqkOUqEHuVMbJcZdZCGiPhKhC4yjqiIjEE7XThMp8fAWII3mY3kUIQD+AMKQTzPiBhgQ63HlT/KSvgtoi0dq5mCPah1UIE0eh3sT0NhOByvKeAkFzi8PgQomumFhsyOxpIzZN4gLOj5plVwNpR0b2AuePWKBEHQu24pSsJA+LVCeHHQxZ1SiyDIdqok8IOhSSnTottHEQTdyt4ettAj4KkzA4dMikk2Dht2S5ptm1vswnPDxn0YyDZ5oDM3iToo2T5voWaYe+Q+vdjH80QyAzZhCgcDtLMI1Tmtz9w++XHgziHQHJJu/OZ3bs9Xn8gQ72NcP3dKqEfkp10F51xhoIi2I91R+LurXV/5q7pH+wx061CzO16oSQleMyr8fXvwMA0Pro8432DPD/ySx8XrHfSuDAM8n6UhnjQabaiXf5Bq/lREHvEeNtn1rJ08+C/uXkQZHeguxAPC3UvtcJYUogLzZX5hhZZvS6onG5lxXtzWGaygwb79vT/IXhdlNibwlKYOR6T8xjI7W8n+xV7T+GH4tMzWwR+lZhRkJYSsC0thpmCYqyngOz3rN2FLBZ2wZflBCggUHF0Vnp88JKienzIXLSEZCZqU7IKr/gQW9yx3pzV7Y9kvWZWTRRIqDmTtRUnU7b2lLcTYmoqHqnmiO1poER0SPkAeZMAZxaJx0Y3TCdAclsIqDz03ALcyxfTCZBsthoGXWmigGyVhWPLFJJfuuKQWycoEFdXbH4dJJoJxNR1eD/kshz6yn48cF8yW8sFoitflB1w6Q8n+/15Za7oA17/pYNmYgP5fmWm8L1NOHPWgK8kuFew1/JXtOA0yJCv7ah7X8ObUuT5kObU30+fDZm8+zqP+HTIpK0xQ796b5Kv2hSIQAQiEIEIRCACEYhABCIQgQhEIAIRiEAEIpBf8UeAAQAEjtYmlDTcCgAAAABJRU5ErkJggg==",
  "$Meta": {
    "Type": "ActionTemplate"
  }
}

History

Page updated on Sunday, November 12, 2023