Skip to content

Commit

Permalink
Merge pull request #152 from jfrog/remove-repos-recommendation-from-doc
Browse files Browse the repository at this point in the history
Update 'project.repos' doc and guide
  • Loading branch information
alexhung authored Aug 7, 2024
2 parents 26d2689 + 578318a commit 609b296
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 56 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 1.7.2 (August 8, 2024). Tested on Artifactory 7.90.6 with Terraform 1.9.3 and OpenTofu 1.8.1

IMPROVEMENTS:

* resource/project: Update documentation for `repos` attribute and "Adding repositories to the project" guide to reflect new way of assigning repository to project. PR: [#152](https://github.com/jfrog/terraform-provider-project/pull/152)

## 1.7.1 (July 25, 2024)

BUG FIXES:
Expand Down
94 changes: 44 additions & 50 deletions docs/guides/repositories_in_project.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,75 +2,57 @@
page_title: "Adding repositories to the project"
---

The guide provides information and the example on how to add repositories to the project.
The guide provides information and the example on how to add repositories to the project.

## Artifactory behavior
## Resources creation sequence

The attribute `project_environments` (`environments` in the API call) is ignored by Artifactory, if the repository is not assigned to an existing project.
That attribute can only be set to the repository if it's assigned to the project already.
The project can't be created with the list of non-existing repositories, and the repository can't be assigned to non-existing project.
Thus, if the project and the repository/repositories are created at the same time in one Terraform configuration, we have a state drift
for the `project_environments` attribute.
1. Create `project` resource
2. Create repository resource(s), the ordering of these first 2 steps doesn't matter.
3. Create `project_repository` resource, using attributes from #1 and #2 as reference values for this resource

This is happening, because the repositories need to be created first, then the project with the list of repositories gets
created. Since `project_environments` attribute is ignored in the first step, we will only have this attribute in the Terraform state, and
not in the actual repository properties.
## Artifactory repository state drift

On the next step, when the repo gets assigned to the project by the project resource, the default value `DEV` is assigned to
repositories' `project_environments` attribute. If the desired value on the first step was `DEV`, then the values match and no state
drift occurs. But if the desired value was `PROD`, we will get an error message when updating the config by `terraform plan`/`terraform apply`.
When a repository in Artifactory is assigned to a project, the API field `projectKey` is set with the project's key. While using the `project_key` attribute in the Artifactory provider to set the project key for the repository is possible, we **strongly** recommend using the `project_repository` resource instead.

```
# artifactory_local_docker_v2_repository.docker-v2-local will be updated in-place
~ resource "artifactory_local_docker_v2_repository" "docker-v2-local" {
id = "myproj-docker-v2-local"
~ project_environments = [
- "DEV",
+ "PROD",
]
}
```

## Workaround
However the next time `terraform plan` or `terraform apply` is run, a state drift will occur for the `project_key` attribute. To avoid this, use Terraform meta argument `lifecycle.ignore_changes`. e.g.

~> In the Project provider documentation, we strongly recommend using the `repos` attribute to manage the list of repositories.
Do not use `project_key` attribute of the repository resource.
```hcl
resource "artifactory_local_docker_v2_repository" "docker-v2-local" {
key = "myproj-docker-v2-local"
tag_retention = 3
max_unique_tags = 5
project_environments = ["PROD"]
Unfortunately, we can't fix the behavior described above right now. The workaround is simply to run `terraform apply` twice.
When the user applies the configuration second time, the repository is already assigned to the project, and `project_environments`
attribute won't be ignored.
lifecycle {
ignore_changes = [
project_key
]
}
}
```

## Full HCL example

```hcl
terraform {
required_providers {
artifactory = {
source = "registry.terraform.io/jfrog/artifactory"
version = "6.21.4"
source = "jfrog/artifactory"
version = "11.5.0"
}
project = {
source = "registry.terraform.io/jfrog/project"
version = "1.1.1"
source = "jfrog/project"
version = "1.7.1"
}
}
}
provider "artifactory" {
// supply ARTIFACTORY_ACCESS_TOKEN / JFROG_ACCESS_TOKEN / ARTIFACTORY_API_KEY and ARTIFACTORY_URL / JFROG_URL as env vars
// supply JFROG_ACCESS_TOKEN / JFROG_URL as env vars
}
resource "artifactory_local_docker_v2_repository" "docker-v2-local" {
key = "myproj-docker-v2-local"
tag_retention = 3
max_unique_tags = 5
project_environments = ["PROD"]
lifecycle {
ignore_changes = [
project_key
]
}
provider "project" {
// supply JFROG_ACCESS_TOKEN / JFROG_URL as env vars
}
resource "project" "myproject" {
Expand All @@ -85,11 +67,23 @@ resource "project" "myproject" {
max_storage_in_gibibytes = 10
block_deployments_on_limit = false
email_notification = true
}
repos = ["myproj-docker-v2-local"]
resource "artifactory_local_docker_v2_repository" "docker-v2-local" {
key = "docker-v2-local"
tag_retention = 3
max_unique_tags = 5
project_environments = ["PROD"]
depends_on = [ artifactory_local_docker_v2_repository.docker-v2-local ]
lifecycle {
ignore_changes = [
project_key
]
}
}
resource "project_repository" "myproject-docker-v2-local" {
project_key = project.myproject.key
key = artifactory_local_docker_v2_repository.docker-v2-local.key
}
```
~> Apply `lifecycle.ignore_changes` to `project_key` attribute, otherwise it will be removed from the repository,
which means it will be unassigned from the project on the configuration update.
12 changes: 7 additions & 5 deletions docs/resources/project.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ subcategory: ""
description: |-
Provides an Artifactory project resource. This can be used to create and manage Artifactory project, maintain users/groups/roles/repos.
Repository Configuration
After the project configuration is applied, the repository's attributes project_key and project_environments would be updated with the project's data. This will generate a state drift in the next Terraform plan/apply for the repository resource. To avoid this, apply lifecycle.ignore_changes:
After the project configuration is applied with `repos` attribute set, the repository's attributes project_key and project_environments would be updated with the project's data. This will generate a state drift in the next Terraform plan/apply for the repository resource. To avoid this, apply lifecycle.ignore_changes:
```hcl
resource "artifactorylocalmavenrepository" "mymaven_releases" {
key = "my-maven-releases"
Expand All @@ -19,7 +19,8 @@ description: |-
}
```
~>We strongly recommend using the 'repos' attribute to manage the list of repositories. See below for additional details.
~>We strongly recommend using the 'preject_repository' resource instead to manage the list of repositories.
---

# project (Resource)
Expand All @@ -28,7 +29,7 @@ Provides an Artifactory project resource. This can be used to create and manage

## Repository Configuration

After the project configuration is applied, the repository's attributes `project_key` and `project_environments` would be updated with the project's data. This will generate a state drift in the next Terraform plan/apply for the repository resource. To avoid this, apply `lifecycle.ignore_changes`:
After the project configuration is applied with `repos` attribute set, the repository's attributes `project_key` and `project_environments` would be updated with the project's data. This will generate a state drift in the next Terraform plan/apply for the repository resource. To avoid this, apply `lifecycle.ignore_changes`:
```hcl
resource "artifactory_local_maven_repository" "my_maven_releases" {
key = "my-maven-releases"
Expand All @@ -42,7 +43,8 @@ resource "artifactory_local_maven_repository" "my_maven_releases" {
}
}
```
~>We strongly recommend using the 'repos' attribute to manage the list of repositories. See below for additional details.

~>We strongly recommend using the 'preject_repository' resource instead to manage the list of repositories.

## Example Usage

Expand Down Expand Up @@ -81,7 +83,7 @@ resource "project" "myproject" {
- `group` (Block Set, Deprecated) Project group. Element has one to one mapping with the [JFrog Project Groups API](https://www.jfrog.com/confluence/display/JFROG/Artifactory+REST+API#ArtifactoryRESTAPI-UpdateGroupinProject) (see [below for nested schema](#nestedblock--group))
- `max_storage_in_gibibytes` (Number) Storage quota in GiB. Must be 1 or larger. Set to -1 for unlimited storage. This is translated to binary bytes for Artifactory API. So for a 1TB quota, this should be set to 1024 (vs 1000) which will translate to 1099511627776 bytes for the API.
- `member` (Block Set, Deprecated) Member of the project. Element has one to one mapping with the [JFrog Project Users API](https://www.jfrog.com/confluence/display/JFROG/Artifactory+REST+API#ArtifactoryRESTAPI-UpdateUserinProject). (see [below for nested schema](#nestedblock--member))
- `repos` (Set of String, Deprecated) (Optional) List of existing repo keys to be assigned to the project. **Note** We *strongly* recommend using this attribute to manage the list of repositories. If you wish to use the alternate method of setting `project_key` attribute in each `artifactory_*_repository` resource in the `artifactory` provider, you will need to use `lifecycle.ignore_changes` in the `project` resource to avoid state drift.
- `repos` (Set of String, Deprecated) (Optional) List of existing repo keys to be assigned to the project. If you wish to use the alternate method of setting `project_key` attribute in each `artifactory_*_repository` resource in the `artifactory` provider, you will need to use `lifecycle.ignore_changes` in the `project` resource to avoid state drift.

```hcl
lifecycle {
Expand Down
2 changes: 1 addition & 1 deletion pkg/project/resource/resource_project.go
Original file line number Diff line number Diff line change
Expand Up @@ -686,7 +686,7 @@ func (r *ProjectResource) Schema(ctx context.Context, req resource.SchemaRequest
Validators: []validator.Set{
setvalidator.SizeAtLeast(1),
},
Description: "(Optional) List of existing repo keys to be assigned to the project. **Note** We *strongly* recommend using this attribute to manage the list of repositories. If you wish to use the alternate method of setting `project_key` attribute in each `artifactory_*_repository` resource in the `artifactory` provider, you will need to use `lifecycle.ignore_changes` in the `project` resource to avoid state drift.\n\n```hcl\nlifecycle {\n\tignore_changes = [\n\t\trepos\n\t]\n}\n```",
Description: "(Optional) List of existing repo keys to be assigned to the project. If you wish to use the alternate method of setting `project_key` attribute in each `artifactory_*_repository` resource in the `artifactory` provider, you will need to use `lifecycle.ignore_changes` in the `project` resource to avoid state drift.\n\n```hcl\nlifecycle {\n\tignore_changes = [\n\t\trepos\n\t]\n}\n```",
DeprecationMessage: "Replaced by `project_repository` resource. This should not be used in combination with `project_repository` resource. Use `use_project_repository_resource` attribute to control which resource manages project repositories.",
},
}),
Expand Down

0 comments on commit 609b296

Please sign in to comment.