Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'doc/user/packages')
-rw-r--r--doc/user/packages/composer_repository/index.md4
-rw-r--r--doc/user/packages/conan_repository/index.md2
-rw-r--r--doc/user/packages/container_registry/index.md15
-rw-r--r--doc/user/packages/index.md11
-rw-r--r--doc/user/packages/infrastructure_registry/index.md93
-rw-r--r--doc/user/packages/maven_repository/index.md15
-rw-r--r--doc/user/packages/npm_registry/index.md9
-rw-r--r--doc/user/packages/nuget_repository/index.md2
-rw-r--r--doc/user/packages/package_registry/index.md39
-rw-r--r--doc/user/packages/pypi_repository/index.md39
-rw-r--r--doc/user/packages/rubygems_registry/index.md4
-rw-r--r--doc/user/packages/terraform_module_registry/index.md124
-rw-r--r--doc/user/packages/workflows/project_registry.md4
-rw-r--r--doc/user/packages/workflows/working_with_monorepos.md64
14 files changed, 395 insertions, 30 deletions
diff --git a/doc/user/packages/composer_repository/index.md b/doc/user/packages/composer_repository/index.md
index bc1e59e4ac2..b5170dfa55b 100644
--- a/doc/user/packages/composer_repository/index.md
+++ b/doc/user/packages/composer_repository/index.md
@@ -120,7 +120,7 @@ You can publish a Composer package to the Package Registry as part of your CI/CD
deploy:
stage: deploy
script:
- - 'curl --header "Job-Token: $CI_JOB_TOKEN" --data tag=<tag> "https://gitlab.example.com/api/v4/projects/$CI_PROJECT_ID/packages/composer"'
+ - 'curl --header "Job-Token: $CI_JOB_TOKEN" --data tag=<tag> "${CI_API_V4_URL}/projects/$CI_PROJECT_ID/packages/composer"'
```
1. Run the pipeline.
@@ -131,7 +131,7 @@ To view the published package, go to **Packages & Registries > Package Registry*
A more detailed Composer CI/CD file is also available as a `.gitlab-ci.yml` template:
-1. On the left sidebar, click **Project overview**.
+1. On the left sidebar, select **Project information**.
1. Above the file list, click **Set up CI/CD**. If this button is not available, select **CI/CD Configuration** and then **Edit**.
1. From the **Apply a template** list, select **Composer**.
diff --git a/doc/user/packages/conan_repository/index.md b/doc/user/packages/conan_repository/index.md
index 53d191cbcfe..a429e746cf2 100644
--- a/doc/user/packages/conan_repository/index.md
+++ b/doc/user/packages/conan_repository/index.md
@@ -281,7 +281,7 @@ image: conanio/gcc7
create_package:
stage: deploy
script:
- - conan remote add gitlab https://gitlab.example.com/api/v4/packages/conan
+ - conan remote add gitlab ${CI_API_V4_URL}/projects/$CI_PROJECT_ID/packages/conan
- conan new <package-name>/0.1 -t
- conan create . <group-name>+<project-name>/stable
- CONAN_LOGIN_USERNAME=ci_user CONAN_PASSWORD=${CI_JOB_TOKEN} conan upload <package-name>/0.1@<group-name>+<project-name>/stable --all --remote=gitlab
diff --git a/doc/user/packages/container_registry/index.md b/doc/user/packages/container_registry/index.md
index 6d7b009bb09..9d65c5d37ad 100644
--- a/doc/user/packages/container_registry/index.md
+++ b/doc/user/packages/container_registry/index.md
@@ -512,6 +512,17 @@ On GitLab.com, the execution time for the cleanup policy is limited, and some of
the Container Registry after the policy runs. The next time the policy runs, the remaining tags are included,
so it may take multiple runs for all tags to be deleted.
+WARNING:
+GitLab self-managed installs support for third-party container registries that comply with the
+[Docker Registry HTTP API V2](https://docs.docker.com/registry/spec/api/)
+specification. However, this specification does not include a tag delete operation. Therefore, when
+interacting with third-party container registries, GitLab uses a workaround to delete tags. See the
+[related issue](https://gitlab.com/gitlab-org/gitlab/-/issues/15737)
+for more information. Due to possible implementation variations, this workaround is not guaranteed
+to work with all third-party registries in the same predictable way. If you use the GitLab Container
+Registry, this workaround is not required because we implemented a special tag delete operation. In
+this case, you can expect cleanup policies to be consistent and predictable.
+
### Create a cleanup policy
You can create a cleanup policy in [the API](#use-the-cleanup-policy-api) or the UI.
@@ -633,7 +644,9 @@ Examples:
- Select all tags, keep at least 1 tag per image, clean up any tag older than 14 days, run once a month, preserve any images with the name `master` and the policy is enabled:
```shell
- curl --request PUT --header 'Content-Type: application/json;charset=UTF-8' --header "PRIVATE-TOKEN: <your_access_token>" --data-binary '{"container_expiration_policy_attributes":{"cadence":"1month","enabled":true,"keep_n":1,"older_than":"14d","name_regex":"","name_regex_delete":".*","name_regex_keep":".*-master"}}' "https://gitlab.example.com/api/v4/projects/2"
+ curl --request PUT --header 'Content-Type: application/json;charset=UTF-8' --header "PRIVATE-TOKEN: <your_access_token>" \
+ --data-binary '{"container_expiration_policy_attributes":{"cadence":"1month","enabled":true,"keep_n":1,"older_than":"14d","name_regex":"","name_regex_delete":".*","name_regex_keep":".*-master"}}' \
+ "https://gitlab.example.com/api/v4/projects/2"
```
Valid values for `cadence` when using the API are:
diff --git a/doc/user/packages/index.md b/doc/user/packages/index.md
index b871a08c133..f0bf2fc3363 100644
--- a/doc/user/packages/index.md
+++ b/doc/user/packages/index.md
@@ -46,7 +46,6 @@ guides you through the process.
| Puppet | [#36897](https://gitlab.com/gitlab-org/gitlab/-/issues/36897) |
| RPM | [#5932](https://gitlab.com/gitlab-org/gitlab/-/issues/5932) |
| SBT | [#36898](https://gitlab.com/gitlab-org/gitlab/-/issues/36898) |
-| Terraform | [Draft: Merge Request](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/18834) |
| Vagrant | [#36899](https://gitlab.com/gitlab-org/gitlab/-/issues/36899) |
<!-- vale gitlab.Spelling = YES -->
@@ -54,6 +53,16 @@ guides you through the process.
The GitLab [Container Registry](container_registry/index.md) is a secure and private registry for container images. It's built on open source software and completely integrated within GitLab. Use GitLab CI/CD to create and publish images. Use the GitLab [API](../../api/container_registry.md) to manage the registry across groups and projects.
+## Infrastructure Registry
+
+The GitLab [Infrastructure Registry](infrastructure_registry/index.md) is a secure and private registry for infrastructure packages. You can use GitLab CI/CD to create and publish infrastructure packages.
+
+The Infrastructure Registry supports the following formats:
+
+| Package type | GitLab version |
+| ------------ | -------------- |
+| [Terraform Module](terraform_module_registry/index.md) | 14.0+ |
+
## Dependency Proxy
The [Dependency Proxy](dependency_proxy/index.md) is a local proxy for frequently-used upstream images and packages.
diff --git a/doc/user/packages/infrastructure_registry/index.md b/doc/user/packages/infrastructure_registry/index.md
new file mode 100644
index 00000000000..00370bd2f48
--- /dev/null
+++ b/doc/user/packages/infrastructure_registry/index.md
@@ -0,0 +1,93 @@
+---
+stage: Configure
+group: Configure
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+---
+
+# Infrastructure Registry **(FREE)**
+
+> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/3221) in GitLab 14.0.
+
+With the GitLab Infrastructure Registry, you can use GitLab projects as a
+private registry for infrastructure packages. You can create and publish
+packages with GitLab CI/CD, which can then be consumed from other private
+projects.
+
+## View packages
+
+To view packages within your project or group:
+
+1. Go to the project or group.
+1. Go to **Packages & Registries > Infrastructure Registry**.
+
+You can search, sort, and filter packages on this page.
+
+When you view packages in a group:
+
+- All packages published to the group and its projects are displayed.
+- Only the projects you can access are displayed.
+- If a project is private, or you are not a member of the project, it is not displayed.
+
+For information on how to create and upload a package, view the GitLab
+documentation for your package type:
+
+- [Terraform modules](../terraform_module_registry/index.md)
+
+## Use GitLab CI/CD to build packages
+
+To use [GitLab CI/CD](../../../ci/README.md) to build packages, you can
+authenticate with the [`CI_JOB_TOKEN` predefined variable](../../../ci/variables/predefined_variables.md).
+
+CI/CD templates, which you can use to get started, are in [this repository](https://gitlab.com/gitlab-org/gitlab/-/tree/master/lib/gitlab/ci/templates).
+
+Learn more about using CI/CD to build:
+
+- [Terraform modules](../terraform_module_registry/index.md#publish-a-terraform-module-by-using-cicd)
+
+If you use CI/CD to build a package, you can find extended activity information
+when you view the package details:
+
+![Package CI/CD activity](../package_registry/img/package_activity_v12_10.png)
+
+You can see the pipeline that published the package as well as the commit and the user who triggered it. However, the history is limited to five updates per package.
+
+## Download a package
+
+To download a package:
+
+1. Go to **Packages & Registries > Infrastructure Registry**.
+1. Select the name of the package you want to download.
+1. In the **Activity** section, select the name of the package you want to download.
+
+## Delete a package
+
+You cannot edit a package after you publish it in the Infrastructure Registry. Instead, you
+must delete and recreate it.
+
+To delete a package, you must have suitable [permissions](../../permissions.md).
+
+You can delete packages by using [the API](../../../api/packages.md#delete-a-project-package) or the UI.
+
+To delete a package in the UI, from your group or project:
+
+1. Go to **Packages & Registries > Infrastructure Registry**.
+1. Find the name of the package you want to delete.
+1. Select **Delete**.
+
+The package is permanently deleted.
+
+## Disable the Infrastructure Registry
+
+The Infrastructure Registry is automatically enabled.
+
+For self-managed instances, a GitLab administrator can
+[disable](../../../administration/packages/index.md) **Packages & Registries**,
+which removes this menu item from the sidebar. **(FREE SELF)**
+
+You can also remove the Infrastructure Registry for a specific project:
+
+1. In your project, go to **Settings > General**.
+1. Expand the **Visibility, project features, permissions** section and toggle **Packages** off (in gray).
+1. Select **Save changes**.
+
+To enable it back, follow the same steps above and toggle it on (in blue).
diff --git a/doc/user/packages/maven_repository/index.md b/doc/user/packages/maven_repository/index.md
index ba7b55dc47d..2567cc3b828 100644
--- a/doc/user/packages/maven_repository/index.md
+++ b/doc/user/packages/maven_repository/index.md
@@ -341,7 +341,7 @@ file:
```groovy
repositories {
maven {
- url "https://gitlab.example.com/api/v4/groups/<group>/-/packages/maven"
+ url "${CI_API_V4_URL}/groups/<group>/-/packages/maven"
name "GitLab"
credentials(HttpHeaderCredentials) {
name = 'Job-Token'
@@ -611,8 +611,11 @@ Now navigate to your project's **Packages & Registries** page and view the publi
### Publishing a package with the same name or version
-When you publish a package with the same name or version as an existing package,
-the existing package is overwritten.
+When you publish a package with the same name and version as an existing package, the new package
+files are added to the existing package. You can still use the UI or API to access and view the
+existing package's older files.
+
+To delete these older package versions, consider using the Packages API or the UI.
#### Do not allow duplicate Maven packages
@@ -742,17 +745,17 @@ You can create a new package each time the `master` branch is updated.
<repositories>
<repository>
<id>gitlab-maven</id>
- <url>${env.CI_SERVER_URL}/api/v4/projects/${env.CI_PROJECT_ID}/packages/maven</url>
+ <url>$env{CI_API_V4_URL}/projects/${env.CI_PROJECT_ID}/packages/maven</url>
</repository>
</repositories>
<distributionManagement>
<repository>
<id>gitlab-maven</id>
- <url>${env.CI_SERVER_URL}/api/v4/projects/${env.CI_PROJECT_ID}/packages/maven</url>
+ <url>${CI_API_V4_URL}/projects/${env.CI_PROJECT_ID}/packages/maven</url>
</repository>
<snapshotRepository>
<id>gitlab-maven</id>
- <url>${env.CI_SERVER_URL}/api/v4/projects/${env.CI_PROJECT_ID}/packages/maven</url>
+ <url>${CI_API_V4_URL}/projects/${env.CI_PROJECT_ID}/packages/maven</url>
</snapshotRepository>
</distributionManagement>
```
diff --git a/doc/user/packages/npm_registry/index.md b/doc/user/packages/npm_registry/index.md
index ace432b305f..735873be237 100644
--- a/doc/user/packages/npm_registry/index.md
+++ b/doc/user/packages/npm_registry/index.md
@@ -110,7 +110,8 @@ To authenticate, use one of the following:
- It's not recommended, but you can use [OAuth tokens](../../../api/oauth2.md#resource-owner-password-credentials-flow).
Standard OAuth tokens cannot authenticate to the GitLab npm Registry. You must use a personal access token with OAuth headers.
- A [CI job token](#authenticate-with-a-ci-job-token).
-- Your npm package name must be in the format of [@scope/package-name](#package-naming-convention). It must match exactly, including the case.
+- Your npm package name must be in the format of [`@scope/package-name`](#package-naming-convention).
+ It must match exactly, including the case.
### Authenticate with a personal access token or deploy token
@@ -282,7 +283,7 @@ Prerequisites:
- [Authenticate](#authenticate-to-the-package-registry) to the Package Registry.
- Set a [project-level npm endpoint](#use-the-gitlab-endpoint-for-npm-packages).
-- Your npm package name must be in the format of [@scope/package-name](#package-naming-convention).
+- Your npm package name must be in the format of [`@scope/package-name`](#package-naming-convention).
It must match exactly, including the case. This is different than the
npm naming convention, but it is required to work with the GitLab Package Registry.
@@ -300,7 +301,7 @@ stages:
deploy:
stage: deploy
script:
- - echo "//gitlab.example.com/api/v4/projects/${CI_PROJECT_ID}/packages/npm/:_authToken=${CI_JOB_TOKEN}">.npmrc
+ - echo "//${CI_SERVER_HOST}/api/v4/projects/${CI_PROJECT_ID}/packages/npm/:_authToken=${CI_JOB_TOKEN}">.npmrc
- npm publish
```
@@ -532,7 +533,7 @@ If you get this error, ensure that:
### `npm publish` returns `npm ERR! 400 Bad Request`
If you get this error, your package name may not meet the
-[@scope/package-name package naming convention](#package-naming-convention).
+[`@scope/package-name` package naming convention](#package-naming-convention).
Ensure the name meets the convention exactly, including the case.
Then try to publish again.
diff --git a/doc/user/packages/nuget_repository/index.md b/doc/user/packages/nuget_repository/index.md
index 7e59b19076a..f19d565ef36 100644
--- a/doc/user/packages/nuget_repository/index.md
+++ b/doc/user/packages/nuget_repository/index.md
@@ -336,7 +336,7 @@ updated:
stage: deploy
script:
- dotnet pack -c Release
- - dotnet nuget add source "$CI_SERVER_URL/api/v4/projects/$CI_PROJECT_ID/packages/nuget/index.json" --name gitlab --username gitlab-ci-token --password $CI_JOB_TOKEN --store-password-in-clear-text
+ - dotnet nuget add source "${CI_API_V4_URL}/${CI_PROJECT_ID}/packages/nuget/index.json" --name gitlab --username gitlab-ci-token --password $CI_JOB_TOKEN --store-password-in-clear-text
- dotnet nuget push "bin/Release/*.nupkg" --source gitlab
only:
- master
diff --git a/doc/user/packages/package_registry/index.md b/doc/user/packages/package_registry/index.md
index f04f6f1316e..52ce7d62940 100644
--- a/doc/user/packages/package_registry/index.md
+++ b/doc/user/packages/package_registry/index.md
@@ -40,14 +40,16 @@ authenticate with GitLab by using the `CI_JOB_TOKEN`.
CI/CD templates, which you can use to get started, are in [this repository](https://gitlab.com/gitlab-org/gitlab/-/tree/master/lib/gitlab/ci/templates).
-Learn more about using CI/CD to build:
+Learn more about using the GitLab Package Registry with CI/CD:
-- [Composer packages](../composer_repository/index.md#publish-a-composer-package-by-using-cicd)
-- [Conan packages](../conan_repository/index.md#publish-a-conan-package-by-using-cicd)
-- [Generic packages](../generic_packages/index.md#publish-a-generic-package-by-using-cicd)
-- [Maven packages](../maven_repository/index.md#create-maven-packages-with-gitlab-cicd)
-- [npm packages](../npm_registry/index.md#publish-an-npm-package-by-using-cicd)
-- [NuGet packages](../nuget_repository/index.md#publish-a-nuget-package-by-using-cicd)
+- [Composer](../composer_repository/index.md#publish-a-composer-package-by-using-cicd)
+- [Conan](../conan_repository/index.md#publish-a-conan-package-by-using-cicd)
+- [Generic](../generic_packages/index.md#publish-a-generic-package-by-using-cicd)
+- [Maven](../maven_repository/index.md#create-maven-packages-with-gitlab-cicd)
+- [npm](../npm_registry/index.md#publish-an-npm-package-by-using-cicd)
+- [NuGet](../nuget_repository/index.md#publish-a-nuget-package-by-using-cicd)
+- [PyPI](../pypi_repository/#authenticate-with-a-ci-job-token)
+- [RubyGems](../rubygems_registry/#authenticate-with-a-ci-job-token)
If you use CI/CD to build a package, extended activity information is displayed
when you view the package details:
@@ -81,6 +83,22 @@ To delete a package in the UI, from your group or project:
The package is permanently deleted.
+## Delete files associated with a package
+
+To delete package files, you must have suitable [permissions](../../permissions.md).
+
+You can delete packages by using [the API](../../../api/packages.md#delete-a-package-file) or the UI.
+
+To delete package files in the UI, from your group or project:
+
+1. Go to **Packages & Registries > Package Registry**.
+1. Find the name of the package you want to delete.
+1. Select the package to view additional details.
+1. Find the name of the file you would like to delete.
+1. Expand the ellipsis and select **Delete file**.
+
+The package files are permanently deleted.
+
## Disable the Package Registry
The Package Registry is automatically enabled.
@@ -100,6 +118,9 @@ The **Packages & Registries > Package Registry** entry is removed from the sideb
## Package workflows
-Learn how to use the GitLab Package Registry to build your own custom package workflow.
+Learn how to use the GitLab Package Registry to build your own custom package workflow:
+
+- [Use a project as a package registry](../workflows/project_registry.md)
+ to publish all of your packages to one project.
-- [Use a project as a package registry](../workflows/project_registry.md) to publish all of your packages to one project.
+- Publish multiple different packages from one [monorepo project](../workflows/working_with_monorepos.md).
diff --git a/doc/user/packages/pypi_repository/index.md b/doc/user/packages/pypi_repository/index.md
index 17b51e313fa..2dd00fdc273 100644
--- a/doc/user/packages/pypi_repository/index.md
+++ b/doc/user/packages/pypi_repository/index.md
@@ -216,7 +216,7 @@ run:
script:
- pip install twine
- python setup.py sdist bdist_wheel
- - TWINE_PASSWORD=${CI_JOB_TOKEN} TWINE_USERNAME=gitlab-ci-token python -m twine upload --repository-url https://gitlab.example.com/api/v4/projects/${CI_PROJECT_ID}/packages/pypi dist/*
+ - TWINE_PASSWORD=${CI_JOB_TOKEN} TWINE_USERNAME=gitlab-ci-token python -m twine upload --repository-url ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/pypi dist/*
```
You can also use `CI_JOB_TOKEN` in a `~/.pypirc` file that you check in to
@@ -233,6 +233,14 @@ username = gitlab-ci-token
password = ${env.CI_JOB_TOKEN}
```
+### Authenticate to access packages within a group
+
+Follow the instructions above for the token type, but use the group URL in place of the project URL:
+
+```shell
+https://gitlab.example.com/api/v4/groups/<group_id>/-/packages/pypi
+```
+
## Publish a PyPI package
Prerequisites:
@@ -316,6 +324,8 @@ more than once, a `404 Bad Request` error occurs.
## Install a PyPI package
+### Install from the project level
+
To install the latest version of a package, use the following command:
```shell
@@ -350,6 +360,33 @@ Installing collected packages: mypypipackage
Successfully installed mypypipackage-0.0.1
```
+### Install from the group level
+
+To install the latest version of a package from a group, use the following command:
+
+```shell
+pip install --index-url https://<personal_access_token_name>:<personal_access_token>@gitlab.example.com/api/v4/groups/<group_id>/-/packages/pypi/simple --no-deps <package_name>
+```
+
+In this command:
+
+- `<package_name>` is the package name.
+- `<personal_access_token_name>` is a personal access token name with the `read_api` scope.
+- `<personal_access_token>` is a personal access token with the `read_api` scope.
+- `<group_id>` is the group ID.
+
+In these commands, you can use `--extra-index-url` instead of `--index-url`. However, using
+`--extra-index-url` makes you vulnerable to dependency confusion attacks because it checks the PyPi
+repository for the package before it checks the custom repository. `--extra-index-url` adds the
+provided URL as an additional registry which the client checks if the package is present.
+`--index-url` tells the client to check for the package at the provided URL only.
+
+If you're following the guide and want to install the `MyPyPiPackage` package, you can run:
+
+```shell
+pip install mypypipackage --no-deps --index-url https://<personal_access_token_name>:<personal_access_token>@gitlab.example.com/api/v4/groups/<your_group_id>/-/packages/pypi/simple
+```
+
### Package names
GitLab looks for packages that use
diff --git a/doc/user/packages/rubygems_registry/index.md b/doc/user/packages/rubygems_registry/index.md
index e4d297ac1d8..743bc229e11 100644
--- a/doc/user/packages/rubygems_registry/index.md
+++ b/doc/user/packages/rubygems_registry/index.md
@@ -88,11 +88,11 @@ run:
- mkdir ~/.gem
- echo "---" > ~/.gem/credentials
- |
- echo "https://gitlab.example.com/api/v4/projects/${CI_PROJECT_ID}/packages/rubygems: '${CI_JOB_TOKEN}'" >> ~/.gem/credentials
+ echo "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/rubygems: '${CI_JOB_TOKEN}'" >> ~/.gem/credentials
- chmod 0600 ~/.gem/credentials # rubygems requires 0600 permissions on the credentials file
script:
- gem build my_gem
- - gem push my_gem-0.0.1.gem --host https://gitlab.example.com/api/v4/projects/${CI_PROJECT_ID}/packages/rubygems
+ - gem push my_gem-0.0.1.gem --host ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/rubygems
```
You can also use `CI_JOB_TOKEN` in a `~/.gem/credentials` file that you check in to
diff --git a/doc/user/packages/terraform_module_registry/index.md b/doc/user/packages/terraform_module_registry/index.md
new file mode 100644
index 00000000000..efb2b8ddf8e
--- /dev/null
+++ b/doc/user/packages/terraform_module_registry/index.md
@@ -0,0 +1,124 @@
+---
+stage: Configure
+group: Configure
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+---
+
+# Terraform module registry **(FREE)**
+
+> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/3221) in GitLab 14.0.
+
+Publish Terraform modules in your project's Infrastructure Registry, then reference them using GitLab
+as a Terraform module registry.
+
+## Authenticate to the Terraform module registry
+
+To authenticate to the Terraform module registry, you need either:
+
+- A [personal access token](../../../api/README.md#personalproject-access-tokens) with at least `read_api` rights.
+- A [CI/CD job token](../../../api/README.md#gitlab-cicd-job-token).
+
+## Publish a Terraform Module
+
+When you publish a Terraform Module, if it does not exist, it is created.
+
+If a package with the same name and version already exists, it will not be created. It does not overwrite the existing package.
+
+Prerequisites:
+
+- You need to [authenticate with the API](../../../api/README.md#authentication). If authenticating with a deploy token, it must be configured with the `write_package_registry` scope.
+
+```plaintext
+PUT /projects/:id/packages/terraform/modules/:module_name/:module_system/:module_version/file
+```
+
+| Attribute | Type | Required | Description |
+| -------------------| --------------- | ---------| -------------------------------------------------------------------------------------------------------------------------------- |
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](../../../api/README.md#namespaced-path-encoding). |
+| `module_name` | string | yes | The package name. It can contain only lowercase letters (`a-z`), uppercase letter (`A-Z`), numbers (`0-9`), or hyphens (`-`).
+| `module_system` | string | yes | The package name. It can contain only lowercase letters (`a-z`), uppercase letter (`A-Z`), numbers (`0-9`), or hyphens (`-`).
+| `module_version` | string | yes | The package version. It must be valid according to the [Semantic Versioning Specification](https://semver.org/).
+
+Provide the file content in the request body.
+
+Example request using a personal access token:
+
+```shell
+curl --header "PRIVATE-TOKEN: <your_access_token>" \
+ --upload-file path/to/file.tgz \
+ "https://gitlab.example.com/api/v4/projects/<your_project_id>/packages/terraform/modules/my-module/my-system/0.0.1/file"
+```
+
+Example response:
+
+```json
+{
+ "message":"201 Created"
+}
+```
+
+Example request using a deploy token:
+
+```shell
+curl --header "DEPLOY-TOKEN: <deploy_token>" \
+ --upload-file path/to/file.tgz \
+ "https://gitlab.example.com/api/v4/projects/<your_project_id>/packages/terraform/modules/my-module/my-system/0.0.1/file"
+```
+
+Example response:
+
+```json
+{
+ "message":"201 Created"
+}
+```
+
+## Reference a Terraform Module
+
+Prerequisites:
+
+- You need to [authenticate with the API](../../../api/README.md#authentication). If authenticating with a personal access token, it must be configured with the `read_api` scope.
+
+Authentication tokens (Job Token or Personal Access Token) can be provided for `terraform` in your `~/.terraformrc` file:
+
+```plaintext
+credentials "gitlab.com" {
+ token = "<TOKEN>"
+}
+```
+
+Where `gitlab.com` can be replaced with the hostname of your self-managed GitLab instance.
+
+You can then reference your Terraform Module from a downstream Terraform project:
+
+```plaintext
+module "<module>" {
+ source = "gitlab.com/<namespace>/<module_name>/<module_system>"
+}
+```
+
+## Publish a Terraform module by using CI/CD
+
+To work with Terraform modules in [GitLab CI/CD](../../../ci/README.md), you can use
+`CI_JOB_TOKEN` in place of the personal access token in your commands.
+
+For example:
+
+```yaml
+image: curlimages/curl:latest
+
+stages:
+ - upload
+
+upload:
+ stage: upload
+ script:
+ - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file path/to/file.tgz "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/terraform/modules/my-module/my-system/0.0.1/file"'
+```
+
+## Example projects
+
+For examples of the Terraform module registry, check the projects below:
+
+- The [_GitLab local file_ project](https://gitlab.com/mattkasa/gitlab-local-file) creates a minimal Terraform module and uploads it into the Terraform module registry using GitLab CI/CD.
+- The [_Terraform module test_ project](https://gitlab.com/mattkasa/terraform-module-test) uses the module from the previous example.
diff --git a/doc/user/packages/workflows/project_registry.md b/doc/user/packages/workflows/project_registry.md
index 3e1c1e7f2ad..12978ad72a5 100644
--- a/doc/user/packages/workflows/project_registry.md
+++ b/doc/user/packages/workflows/project_registry.md
@@ -34,8 +34,8 @@ of each package management system to publish different package types to the same
Let's take a look at how you might create a public place to hold all of your public packages.
-1. Create a new project in GitLab. The project doesn't require any code or content. Note the project ID
- that's displayed on the project overview page.
+1. Create a new project in GitLab. The project doesn't require any code or content.
+1. On the left sidebar, select **Project information**, and note the project ID.
1. Create an access token. All package types in the Package Registry are accessible by using
[GitLab personal access tokens](../../profile/personal_access_tokens.md).
If you're using CI/CD, you can use CI job tokens (`CI_JOB_TOKEN`) to authenticate.
diff --git a/doc/user/packages/workflows/working_with_monorepos.md b/doc/user/packages/workflows/working_with_monorepos.md
new file mode 100644
index 00000000000..4e431b036de
--- /dev/null
+++ b/doc/user/packages/workflows/working_with_monorepos.md
@@ -0,0 +1,64 @@
+---
+stage: Package
+group: Package
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+---
+
+# Monorepo package management workflows
+
+One project or Git repository can contain multiple different subprojects or submodules that are all
+packaged and published individually.
+
+## Publishing different packages to the parent project
+
+The number and name of packages you can publish to one project is not limited.
+You can accomplish this by setting up different configuration files for each
+package. See the documentation for the package manager of your choice since
+each has its own specific files and instructions to follow to publish
+a given package.
+
+The example here uses [NPM](../npm_registry/index.md).
+In this example, `MyProject` is the parent project. It contains a sub-project `Foo` in the
+`components` directory:
+
+```plaintext
+MyProject/
+ |- src/
+ | |- components/
+ | |- Foo/
+ |- package.json
+```
+
+The goal is to publish the packages for `MyProject` and `Foo`. Following the instructions in the
+[GitLab NPM registry documentation](../npm_registry/index.md),
+you can publish `MyProject` by modifying the `package.json` file with a `publishConfig` section,
+and by doing one of the following:
+
+- Modify your local NPM configuration with CLI commands like `npm config set`.
+- Save a `.npmrc` file in the root of the project specifying these configuration settings.
+
+If you follow the instructions, you can publish `MyProject` by running `npm publish` from the root
+directory.
+
+Publishing `Foo` is almost exactly the same. Simply follow the same steps while in the `Foo`
+directory. `Foo` needs its own `package.json` file, which you can add manually by using `npm init`.
+`Foo` also needs its own configuration settings. Since you are publishing to the same place, if you
+used `npm config set` to set the registry for the parent project, then no additional setup is
+necessary. If you used an `.npmrc` file, you need an additional `.npmrc` file in the `Foo` directory.
+Be sure to add `.npmrc` files to the `.gitignore` file or use environment variables in place of your
+access tokens to prevent your tokens from being exposed. This `.npmrc` file can be identical to the
+one you used in `MyProject`. You can now run `npm publish` from the `Foo` directory and you can
+publish `Foo` separately from `MyProject`.
+
+You could follow a similar process for Conan packages. However, instead of `.npmrc` and
+`package.json`, you have `conanfile.py` in multiple locations within the project.
+
+## Publishing to other projects
+
+A package is associated with a project on GitLab, but the package does not need to be associated
+with the code in that project. When configuring NPM or Maven, you only use the `Project ID` to set
+the registry URL that the package uploads to. If you set this to any project that you have access to
+and update any other configuration similarly depending on the package type, your packages are
+published to that project. This means you can publish multiple packages to one project, even if
+their code does not exist in the same place. See the [project registry workflow documentation](project_registry.md)
+for more information.