---
updatedAt: 2026-05-28T08:16:45.000Z
agentTools:
  projectIndex: https://docs.scalr.io/llms.txt
---

# Publish a Module

This endpoint creates a Module from a VCS repository.

The module's source code directory should follow the
[standard module structure](https://www.terraform.io/docs/language/modules/develop/structure.html).

Scalr extracts various meta information from the module's source:
* It's important to provide each `variable` and `output` blocks with a meaningful descriptions, as they
will be displayed in a Module and Workspace Variables pages for your internal users.
* README or README.md file will be displayed on a Module page.
* Nested modules from `modules/` directory will be searchable and available though the Registry just
like top-level modules.

Modules can be published on both `account` and `environment` scopes.
If neither scope is specified in the request body, the module will be published in the
same scope that the related `vcs-provider` is published.


# OpenAPI definition

````json
{
  "components": {
    "schemas": {
      "Module": {
        "description": "A terraform module in the [Private Module Registry](/docs/private-module-registry).",
        "properties": {
          "attributes": {
            "properties": {
              "created-at": {
                "description": "The resource creation timestamp.",
                "format": "date-time",
                "readOnly": true,
                "type": "string"
              },
              "description": {
                "description": "The description of the module.\n\nBy default, this is taken from the VCS repository description. For mono repos you likely\nwant to override this behavior by passing this argument in a\n[Create Module](modules.html#create-a-module) operation.",
                "readOnly": true,
                "type": "string"
              },
              "docker-image": {
                "description": "Docker/OCI image repository path for OCI-backed modules.",
                "maxLength": 512,
                "nullable": true,
                "type": "string"
              },
              "error-message": {
                "description": "This field contains the error description, when this module's status is `errored`.",
                "nullable": true,
                "readOnly": true,
                "type": "string"
              },
              "name": {
                "description": "The module name.",
                "maxLength": 64,
                "type": "string"
              },
              "provider": {
                "description": "A name of a system, this module was written for.\n\nFor multi-cloud modules this argument should match terraform provider name (ex: `aws` or\n`google`), in other cases the convention is to name it `system`",
                "maxLength": 64,
                "type": "string"
              },
              "source": {
                "default": "",
                "description": "The `source` by which the module should be addressed from a HCL template.",
                "readOnly": true,
                "type": "string"
              },
              "source-type": {
                "default": "vcs",
                "description": "The upstream source type for the module.",
                "enum": [
                  "vcs",
                  "docker"
                ],
                "type": "string"
              },
              "status": {
                "description": "The Module's current status.\n\nInitial status:\n* `pending` -  The initial status of a module once it has been created. Now Scalr will\ndownload the code from the VCS, and create a `module-version` resource for each matching\nGit tag.\n\nEnding statuses:\n* `no_version_tags` - a Module has been created, however the Module source repository\nhas no tags.\n* `setup_complete` - a Module has been created, and at least one ModuleVersion has been\nsuccessfully uploaded. Scalr assigns this status while some module-versions upload might\nbe still in-progress. If you want to ensure a specific version was uploaded, you can poll\n[List Module Versions](module-versions.html#list-module-versions) for the `ok` status.\n* `errored` - Module has been created, however its synchronization has failed. Attribute\n`error-message` contains the details.",
                "enum": [
                  "no_version_tags",
                  "pending",
                  "setup_complete",
                  "errored"
                ],
                "readOnly": true,
                "type": "string"
              },
              "vcs-repo": {
                "nullable": true,
                "properties": {
                  "identifier": {
                    "description": "A reference to the module's VCS repository.\n\nFor GitHub, GitHub Enterprise and GitLab the format is `<org>/<repo>`.\nAzure DevOps Services has the format `<org>/<project>/<repo>`.",
                    "type": "string"
                  },
                  "path": {
                    "description": "The repository sub-directory where the module source is located.\nIf omitted or submitted as an empty string, this defaults to the repository's root.",
                    "maxLength": 255,
                    "type": "string"
                  },
                  "tag-prefix": {
                    "description": "Specify this attribute when a module's releases are namespaced within a repository's\nGit tags. This is usually the case for a mono repos with individually versioned\ncomponents. For example if your module is tagged `my-module/v1.0.0` it's `tag_prefix`\nis  `my-module/`.",
                    "maxLength": 255,
                    "type": "string"
                  }
                },
                "required": [
                  "identifier"
                ],
                "type": "object"
              }
            },
            "type": "object"
          },
          "id": {
            "readOnly": true,
            "type": "string"
          },
          "links": {
            "properties": {
              "self": {
                "readOnly": true,
                "type": "string"
              }
            },
            "readOnly": true,
            "type": "object"
          },
          "relationships": {
            "properties": {
              "account": {
                "deprecated": true,
                "description": "The relationship `account` is deprecated. Use `namespace` instead.",
                "properties": {
                  "data": {
                    "nullable": true,
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "type": {
                        "enum": [
                          "accounts",
                          ""
                        ],
                        "type": "string"
                      }
                    },
                    "required": [
                      "type",
                      "id"
                    ],
                    "type": "object"
                  }
                },
                "readOnly": true,
                "required": [
                  "data"
                ],
                "type": "object"
              },
              "created-by": {
                "description": "The user who has created the module.",
                "properties": {
                  "data": {
                    "nullable": true,
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "type": {
                        "enum": [
                          "users",
                          ""
                        ],
                        "type": "string"
                      }
                    },
                    "required": [
                      "type",
                      "id"
                    ],
                    "type": "object"
                  }
                },
                "readOnly": true,
                "required": [
                  "data"
                ],
                "type": "object"
              },
              "docker-integration": {
                "description": "Docker registry connection used by OCI-backed modules.",
                "properties": {
                  "data": {
                    "nullable": true,
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "type": {
                        "enum": [
                          "docker-integrations",
                          ""
                        ],
                        "type": "string"
                      }
                    },
                    "required": [
                      "type",
                      "id"
                    ],
                    "type": "object"
                  }
                },
                "required": [
                  "data"
                ],
                "type": "object"
              },
              "environment": {
                "deprecated": true,
                "description": "The relationship `environment` is deprecated. Use `namespace` instead.",
                "properties": {
                  "data": {
                    "nullable": true,
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "type": {
                        "enum": [
                          "environments",
                          ""
                        ],
                        "type": "string"
                      }
                    },
                    "required": [
                      "type",
                      "id"
                    ],
                    "type": "object"
                  }
                },
                "required": [
                  "data"
                ],
                "type": "object"
              },
              "latest-module-version": {
                "description": "The module's latest version.",
                "properties": {
                  "data": {
                    "nullable": true,
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "type": {
                        "enum": [
                          "module-versions",
                          ""
                        ],
                        "type": "string"
                      }
                    },
                    "required": [
                      "type",
                      "id"
                    ],
                    "type": "object"
                  }
                },
                "readOnly": true,
                "required": [
                  "data"
                ],
                "type": "object"
              },
              "module-version": {
                "description": "The module's latest successful version.",
                "properties": {
                  "data": {
                    "nullable": true,
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "type": {
                        "enum": [
                          "module-versions",
                          ""
                        ],
                        "type": "string"
                      }
                    },
                    "required": [
                      "type",
                      "id"
                    ],
                    "type": "object"
                  }
                },
                "readOnly": true,
                "required": [
                  "data"
                ],
                "type": "object"
              },
              "module-versions": {
                "description": "The IDs of the module versions.",
                "properties": {
                  "data": {
                    "items": {
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "type": {
                          "enum": [
                            "module-versions",
                            ""
                          ],
                          "type": "string"
                        }
                      },
                      "required": [
                        "type",
                        "id"
                      ],
                      "type": "object"
                    },
                    "nullable": true,
                    "type": "array"
                  }
                },
                "readOnly": true,
                "required": [
                  "data"
                ],
                "type": "object"
              },
              "namespace": {
                "description": "The module namespace this module belongs to.",
                "properties": {
                  "data": {
                    "nullable": true,
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "type": {
                        "enum": [
                          "module-namespaces",
                          ""
                        ],
                        "type": "string"
                      }
                    },
                    "required": [
                      "type",
                      "id"
                    ],
                    "type": "object"
                  }
                },
                "required": [
                  "data"
                ],
                "type": "object"
              },
              "vcs-provider": {
                "description": "The module's VCS provider.",
                "properties": {
                  "data": {
                    "nullable": true,
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "type": {
                        "enum": [
                          "vcs-providers",
                          ""
                        ],
                        "type": "string"
                      }
                    },
                    "required": [
                      "type",
                      "id"
                    ],
                    "type": "object"
                  }
                },
                "required": [
                  "data"
                ],
                "type": "object"
              }
            },
            "type": "object"
          },
          "type": {
            "enum": [
              "modules"
            ],
            "type": "string"
          }
        },
        "required": [
          "type"
        ],
        "type": "object"
      },
      "ModuleDocument": {
        "description": "JSON:API Document.\n\nsee: https://jsonapi.org/format/#document-structure",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/Module"
          },
          "included": {
            "items": {
              "type": "object"
            },
            "readOnly": true,
            "type": "array"
          },
          "meta": {
            "readOnly": true,
            "type": "object"
          }
        },
        "type": "object"
      }
    },
    "securitySchemes": {
      "API-Key": {
        "scheme": "bearer",
        "type": "http"
      }
    }
  },
  "info": {
    "description": "Scalr IACP API",
    "license": {
      "name": "Apache 2.0",
      "url": "https://www.apache.org/licenses/LICENSE-2.0"
    },
    "title": "Scalr IACP API",
    "version": "unversioned"
  },
  "openapi": "3.0.0",
  "paths": {
    "/modules": {
      "post": {
        "description": "This endpoint creates a Module from a VCS repository.\n\nThe module's source code directory should follow the\n[standard module structure](https://www.terraform.io/docs/language/modules/develop/structure.html).\n\nScalr extracts various meta information from the module's source:\n* It's important to provide each `variable` and `output` blocks with a meaningful descriptions, as they\nwill be displayed in a Module and Workspace Variables pages for your internal users.\n* README or README.md file will be displayed on a Module page.\n* Nested modules from `modules/` directory will be searchable and available though the Registry just\nlike top-level modules.\n\nModules can be published on both `account` and `environment` scopes.\nIf neither scope is specified in the request body, the module will be published in the\nsame scope that the related `vcs-provider` is published.\n",
        "operationId": "create_module",
        "parameters": [],
        "requestBody": {
          "content": {
            "application/vnd.api+json": {
              "examples": {
                "0-repo-with-mod": {
                  "summary": "Publish a Module from a VCS",
                  "description": "In the case where a module is developed in a dedicated repository, the module's repository name\nshould follow `terraform-<PROVIDER>-<NAME>` pattern. Module `name` and `provider` attributes\nwill be extracted from the repository name. Module `description` copied the VCS repository\ndescription.\n\nThe repository Git tags are expected to be [semantically versioned](https://semver.org/)\nand named `v<SEMVER>` or `<SEMVER>`. Each matching tag will be processed and will produce\na [ModuleVersion](#the-moduleversion-resource) resource.\n\nAfter module module registration Scalr will listen for repository events, and automatically\nsynchronize changes",
                  "value": "{\n    \"data\": {\n      \"type\": \"modules\",\n      \"attributes\": {\n        \"vcs-repo\": {\n          \"identifier\": \"Scalr/terraform-aws-vpc\",\n        }\n      },\n      \"relationships\": {\n        \"account\": {\n          \"data\": {\n            \"type\": \"accounts\",\n            \"id\": \"acc-svrcncgh453bi8g\"\n          }\n        },\n        \"vcs-provider\": {\n          \"data\": {\n            \"type\": \"vcs-providers\",\n            \"id\": \"vcs-t745mjlp46208k0\"\n          }\n        }\n      }\n    }\n  }"
                },
                "1-mod-in-subdir": {
                  "summary": "Publish a Module From a Subdirectory",
                  "description": "Sometimes your module might be located in a repository subdirectory.\n\nFor example you're keeping infrastructure configuration together with an application code.\nAnd your repository files structure is looking like:\n\n```\n$ tree Scalr/scalr-io\n.\n├── ...\n└── infra\n    ├── ...\n    └── terraform\n        └── terraform-google-scalr-io\n            ├── main.tf\n            ├── providers.tf\n            ├── variables.tf\n            ├── outputs.tf\n            └── README.md\n```\n\nIn this case, the module publication requires a `path` and attribute to be set and an optional\n`description` attribute:",
                  "value": "{\n    \"data\": {\n      \"type\": \"modules\",\n      \"description\": \"Terraform module which creates Scalr.IO application infrastructure on Google Cloud\",\n      \"attributes\": {\n        \"vcs-repo\": {\n          \"identifier\": \"Scalr/scalr-io\",\n          \"path\": \"infra/terraform/terraform-google-scalr-io\"\n        }\n      },\n      \"relationships\": {\n        \"account\": {\n          \"data\": {\n            \"type\": \"accounts\",\n            \"id\": \"acc-svrcncgh453bi8g\"\n          }\n        },\n        \"vcs-provider\": {\n          \"data\": {\n            \"type\": \"vcs-providers\",\n            \"id\": \"vcs-t745mjlp46208k0\"\n          }\n        }\n      }\n    }\n  }"
                },
                "2-mono-repo-package": {
                  "summary": "Publish a Module From a Mono Repo",
                  "description": "The easiest way to model a mono repo of terraform modules, is placing all modules into\na nested `modules/` folder, and wrap them up into a top-level \"package\" module.\n\n```bash\n$ tree terraform-system-infra\n.\n├── modules/\n│   ├── primitives/        # private module\n│   │   ├── main.tf\n│   │   ├── variables.tf\n│   │   └── outputs.tf\n│   ├── networking/        # depends from ../primitives\n│   │   ├── main.tf\n│   │   ├── variables.tf\n│   │   ├── outputs.tf\n|   |   ├── README.md\n│   │   └── ...\n|   ├── mongo-cluster/     # depends from ../primitives and ../networking\n│   │   ├── variables.tf\n│   │   ├── outputs.tf\n|   |   ├── README.md\n│   │   └── ...\n│   └── ...\n|   # Package module\n├── main.tf\n└── README.md\n```\n\nThe top-level `main.tf` can have only a single `null_resource` to satisfy\nminimum requirements of the terraform module structure.\n\n```js\nresource null_resource \"package\" {\n  triggers = {\n    always = timestamp()\n  }\n  provisioner \"local-exec\" {\n    command = \"echo 'This Terraform module is a package of nested modules. You should not use the top-level module directly'; exit 1\"\n  }\n}\n```\n\nThe `README.md` should have a table of contents with the links to nested modules READMEs.\n\nThe `networking` module usage:\n\n```js\nmodule \"networking\" {\n  source = \"<scalr-registry-uri>/infra/system//modules/networking\"\n  version = \"1.7.1\"\n}\n```",
                  "value": "{\n    \"data\": {\n      \"type\": \"modules\",\n      \"attributes\": {\n        \"vcs-repo\": {\n          \"identifier\": \"Scalr/terraform-system-infra\",\n        }\n      },\n      \"relationships\": {\n        \"account\": {\n          \"data\": {\n            \"type\": \"accounts\",\n            \"id\": \"acc-svrcncgh453bi8g\"\n          }\n        },\n        \"vcs-provider\": {\n          \"data\": {\n            \"type\": \"vcs-providers\",\n            \"id\": \"vcs-t745mjlp46208k0\"\n          }\n        }\n      }\n    }\n  }"
                },
                "3-mono-repo-nss": {
                  "summary": "Publish a Module from a Mono Repo with Individually Versioned Components",
                  "description": "If your development approach is to keep many (say shared library) modules in a mono repo,\nbut release each module individually versioned, you should consider the following example.\n\nEach module should have in a repository it's own Git tag namespace, e.g. `<TAG-PREFIX>v<SEMVER>`\nand a subdirectory: `path/to/terraform-<PROVIDER>-<NAME>`.",
                  "value": "{\n    \"data\": {\n      \"type\": \"modules\",\n      \"attributes\": {\n        \"description\": \"Terraform module which creates infrastructure on AWS\",\n        \"vcs-repo\": {\n          \"identifier\": \"Scalr/infra\",\n          \"path\": \"library/terraform-aws-my-module\",\n          \"tag-prefix\": \"my-module/\"\n        }\n      },\n      \"relationships\": {\n        \"account\": {\n          \"data\": {\n            \"type\": \"accounts\",\n            \"id\": \"acc-svrcncgh453bi8g\"\n          }\n        },\n        \"vcs-provider\": {\n          \"data\": {\n            \"type\": \"vcs-providers\",\n            \"id\": \"vcs-t745mjlp46208k0\"\n          }\n        }\n      }\n    }\n  }"
                }
              },
              "schema": {
                "$ref": "#/components/schemas/ModuleDocument"
              }
            }
          }
        },
        "responses": {
          "201": {
            "content": {
              "application/vnd.api+json": {
                "examples": {
                  "default": {
                    "value": "{\n    \"data\": {\n        \"attributes\": {\n            \"created-at\": \"2021-02-16T07:35:31Z\",\n            \"description\": \"Terraform module which creates VPC resources on AWS\",\n            \"error-message\": null,\n            \"name\": \"vpc\",\n            \"permissions\": {\n                \"can-delete\": true,\n                \"can-resync\": true,\n                \"can-retry\": true\n            },\n            \"provider\": \"aws\",\n            \"source\": \"https://github.com/Scalr/terraform-aws-vpc\",\n            \"status\": \"pending\",\n            \"updated-at\": \"2021-02-16T07:35:31Z\",\n            \"vcs-repo\": {\n                \"display-identifier\": null,\n                \"identifier\": \"Scalr/terraform-aws-vpc\",\n                \"path\": null,\n                \"provider-type\": \"github\",\n                \"tag-prefix\": null\n            }\n        },\n        \"id\": \"mod-tb51l0r15hfeh38\",\n        \"links\": {\n            \"self\": \"https://my.scalr.io/api/iacp/v3/modules/mod-tb51l0r15hfeh38\"\n        },\n        \"relationships\": {\n            \"account\": {\n               \"data\": {\n                  \"type\": \"accounts\",\n                  \"id\": \"acc-svrcncgh453bi8g\"\n               }\n            },\n            \"created-by\": {\n                \"data\": {\n                    \"id\": \"user-suh84u6vhn64l0o\",\n                    \"type\": \"users\"\n                }\n            },\n            \"environment\": null,\n            \"latest-version\": null,\n            \"module-versions\": null,\n            \"vcs-provider\": {\n                \"data\": {\n                   \"type\": \"vcs-providers\",\n                   \"id\": \"vcs-t745mjlp46208k0\"\n                }\n            },\n        },\n        \"type\": \"modules\"\n    },\n    \"included\": null,\n    \"meta\": null\n}"
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ModuleDocument"
                }
              }
            },
            "description": "Successfully created module."
          },
          "403": {
            "description": "User unauthorized to perform action."
          },
          "404": {
            "description": "Relationship resource not found, or user unauthorized to perform action."
          },
          "422": {
            "description": "Malformed request body (missing attributes, wrong types, etc.)."
          },
          "4XX": {
            "description": "Client error."
          },
          "5XX": {
            "description": "Server error."
          }
        },
        "summary": "Publish a Module",
        "tags": [
          "modules"
        ],
        "x-resource": "Module",
        "x-service": "tf-api"
      }
    }
  },
  "security": [
    {
      "API-Key": []
    }
  ],
  "servers": [
    {
      "url": "https://{Domain}/api/iacp/v3",
      "variables": {
        "Domain": {
          "default": "example.scalr.io",
          "description": "Domain where Scalr is hosted"
        }
      }
    }
  ]
}
````

# Sibling pages

* [List Module Versions](https://docs.scalr.io/scalr/reference/list_module_versions.md)
* [Get a Module Version](https://docs.scalr.io/scalr/reference/get_module_version.md)
* [Resync a Module Version](https://docs.scalr.io/scalr/reference/resync_module_version.md)
* [List Modules](https://docs.scalr.io/scalr/reference/list_modules.md)
* [Unpublish a Module](https://docs.scalr.io/scalr/reference/delete_module.md)
* [Get a Module](https://docs.scalr.io/scalr/reference/get_module.md)
* [Resync a Module](https://docs.scalr.io/scalr/reference/resync_module.md)
* [Module Changelog](https://docs.scalr.io/scalr/reference/get_module_changelog.md)