# Migration Guides

## cdk-v1-constructs to cdk-v2-constructs

1. Remove projen if not already done
   1. **remove projen** dependencies from `package.json`
   2. **copy over** necessary tasks from `.projen/tasks.json` to `package.json`
   3. **remove** `.projen` directory
   * **avoid `eject`** as the resulting tasks script is unreadable and it contains unnecessary/unused features
   * find a more detailed description [here](https://collaboration.msi.audi.com/confluence/display/RIOCLAID/Remove+Projen)
2. Update `aws-cdk` in `package-json` to latest 2.x version: 
   1. **install CDK v2**: `npm install --save-dev aws-cdk@2`
   2. **remove CDK v1 dependencies** (e.g., `@aws-cdk/...`, `constructs`, `@rioclaid/cdk-constructs`) from `package.json`
   3. **add `aws-cdk-lib`**: `npm install aws-cdk-lib`
   3. **add `constructs`**: `npm install constructs@10`
   4. **replace imports**: `$ npx -p aws-cdk-migration rewrite-imports-v2 <your-source-root-here>/**/*.ts`
   5. update `cdk.json` (e.g., by generating a new CDKv2 app in another folder with `npx cdk@2 init app --language=typescript` and comparing its `cdk.json` with yours)
   6. replace `@aws-cdk/assert` with `aws-cdk-lib/assertions` and migrate expectations to `Template.fromStack(...).hasResource`
   * additional information: [Official Migration Guide](https://docs.aws.amazon.com/cdk/v2/guide/migrating-v2.html)
5. Replace `@rioclaid/cdk-constructs` with `@rio-cloud/cdk-v2-constructs`
   * **add `@rio-cloud/cdk-v2-constructs`**: `npm install @rio-cloud/cdk-v2-constructs`
   * replace imports `import * as rio from '@rioclaid/cdk-constructs'` with `import * as rio from '@rio-cloud/cdk-v2-constructs'` 
6. In case you use `Claidometer`:\
   There is a breaking change as the property `package` is a reserved keyword in some languages and thus has been renamed to `packageName`
7. Adopt `renovate.json`


## Migration guide for `9.0.0`

### Breaking migration to the internal npm namespace

Starting with `9.0.0`, this package is published as
`@rio-cloud-internal/cdk-v2-constructs` in the RIO CodeArtifact `internal`
repository. This is a package and installation breaking change for consumers:

- Replace the dependency and every import/subpath reference from
  `@rio-cloud/cdk-v2-constructs` with `@rio-cloud-internal/cdk-v2-constructs`.
  Preserve any subpath after the package name.
- Add the following `login` script to the consuming workspace's `package.json`:

  ```json
  "login": "aws codeartifact login --region eu-west-1 --tool npm --domain rio --domain-owner 577146897785 --repository internal --namespace @rio-cloud-internal"
  ```

- Authenticate npm before installing dependencies by running `npm run login`
  in the consuming workspace before `npm ci` or `npm install`:

  ```bash
  npm run login
  npm ci
  ```

- In CodeBuild or CodePipeline, call `npm run login` immediately before the
  dependency installation in every relevant synth, branch, and auxiliary build
  step. The build role must be allowed to call
  `codeartifact:GetAuthorizationToken`, `codeartifact:GetRepositoryEndpoint`,
  `codeartifact:ReadFromRepository`, and
  `sts:GetServiceBearerToken` for the RIO `internal` repository. Do not commit
  the generated npm credentials or an authentication token.

  For a CDK `CodeBuildStep`, the relevant permissions are equivalent to:

  ```typescript
  new iam.PolicyStatement({
    actions: ['codeartifact:GetAuthorizationToken'],
    resources: ['arn:aws:codeartifact:eu-west-1:577146897785:domain/rio'],
  });
  new iam.PolicyStatement({
    actions: ['sts:GetServiceBearerToken'],
    resources: ['*'],
    conditions: {
      StringEquals: { 'sts:AWSServiceName': 'codeartifact.amazonaws.com' },
    },
  });
  new iam.PolicyStatement({
    actions: ['codeartifact:GetRepositoryEndpoint', 'codeartifact:ReadFromRepository'],
    resources: ['arn:aws:codeartifact:eu-west-1:577146897785:repository/rio/internal'],
  });
  ```

  Ensure these statements are attached to the actual CodeBuild synth or build
  role. Adding only the npm login command is insufficient.
- Regenerate the lockfile after authenticating. Do not reuse the integrity hash
  from the public npm tarball when the resolved URL changes to CodeArtifact.

### Two-phase migration

Prepare registry access before changing package namespaces so the deployed pipeline can install the internal packages:

1. **Prepare CodeArtifact access.** Update the relevant public `@rio-cloud` package versions, add the CodeArtifact login script to each affected workspace, and configure the actual pipeline build roles with the read permissions they need. Run the login command before dependency installation in each pipeline shell that installs dependencies. Keep dependency names, imports, and lockfile package names in the public namespace during this phase.
2. **Switch to the internal namespace.** After the access setup has deployed successfully, change the affected dependencies and references to `@rio-cloud-internal`, regenerate the lockfiles using authenticated access, and validate the affected workspaces. Ensure the deployed login and permissions are still applied before dependency installation.

If pipeline self-mutation is involved, allow the access setup to deploy before switching namespaces. When it is not involved, retain the same order and avoid adding IAM changes if the pipeline already has the required access.

### Migration checks and common mistakes

Use this sequence when migrating a consumer:

1. Confirm the target workspace and the package version to install. Read the
   workspace's `package.json` and lockfile before changing dependency versions;
   do not apply guidance for a later release just because the package name is
   changing.
2. Ensure that a npm token for the RIO CodeArtifact repository is available;
   the consuming workspace must define the `login` npm script shown above;
   agents usually do not have, and do not need, AWS credentials for this
   migration. If `npm install` or `npm ci` fails because the npm credentials
   are missing or invalid, ask the user to run `npm run login` with AWS
   credentials. An AWS Developer role is sufficient. After the user has
   logged in, retry the installation and lockfile generation.
3. Replace the dependency name and all imports/context keys. Preserve the
   requested package version unless the migration explicitly includes a
   version upgrade.
4. With authentication active, regenerate the lockfile. If the dependency
   name is the only intended dependency change, `npm install
   --package-lock-only --ignore-scripts` is sufficient; then run `npm ci` to
   verify the lockfile and install a clean dependency tree. Do not copy the
   old public-package `resolved` URL or integrity value into the new lockfile.
5. Verify that no old package-name references remain, then run the consumer's
   build, lint, tests, synthesis, and whitespace checks.

Do not treat a successful `npm view` or an existing npm cache as proof that the
workspace has been authenticated correctly. The lockfile must resolve the
internal CodeArtifact package URL, and a clean install must be able to fetch
it without relying on a stale cache.

The CodeArtifact login command is required only in environments that need to
obtain npm credentials. If an approved CI action or runner already provisions
the npm registry credentials, do not add a second login command; verify that
the credentials are available before the install instead.

Consumers do not need to add CodeArtifact permissions to their CDK application
roles merely because they use this package. Add the documented permissions to
the actual CodeBuild or CodePipeline execution role only when that role runs
the npm login/install commands. Do not add package-publish permissions to a
consumer role.

For example, the package dependency and root import change as follows:

```diff
-"@rio-cloud/cdk-v2-constructs": "..."
+"@rio-cloud-internal/cdk-v2-constructs": "..."

-import * as rio from '@rio-cloud/cdk-v2-constructs';
+import * as rio from '@rio-cloud-internal/cdk-v2-constructs';
```

The old public package name is not an alias for the internal package. A
consumer that keeps the old name, or runs `npm ci` before CodeArtifact login,
will fail to resolve the migrated package.

Read the relevant declaration comments and examples before writing or changing infrastructure code.

This section applies when upgrading a consuming project to `9.0.0` or
later. Confirm the installed package version and its `package.json` exports
before applying it. The guidance below is based on the implementation and
tests in this release; it intentionally does not prescribe replacements for
environment variables for which this wrapper exposes no one-to-one prop.

### Datadog Lambda instrumentation: Datadog v5 environment handling

`DatadogLambdaInstrumentation` now uses `datadog-cdk-constructs-v2` v5. Before
calling `addLambdaFunctions()`, the construct rejects a Lambda whose CDK
environment already contains any of these variables:

```text
DD_TRACE_ENABLED
DD_MERGE_XRAY_TRACES
DD_LOGS_INJECTION
DD_SERVERLESS_LOGS_ENABLED
DD_CAPTURE_LAMBDA_PAYLOAD
DD_TRACE_CLOUD_REQUEST_PAYLOAD_TAGGING
DD_TRACE_CLOUD_RESPONSE_PAYLOAD_TAGGING
DD_LOG_LEVEL
DD_APPSEC_ENABLED
DD_SERVERLESS_APPSEC_ENABLED
AWS_LAMBDA_EXEC_WRAPPER
DD_TAGS
```

Datadog v4 read existing values differently. With v5, values configured
before instrumentation can be overwritten, so remove these settings from the
Lambda constructor and from any `addEnvironment()` call made before
`addLambdaFunctions()`.

Use the instrumentation props for settings that have a corresponding public
prop. The direct mappings established by this package are:

| Lambda environment variable | `DatadogLambdaInstrumentation` prop |
| --- | --- |
| `DD_TRACE_ENABLED` | `enableDatadogTracing` |
| `DD_MERGE_XRAY_TRACES` | `enableMergeXrayTraces` |
| `DD_LOGS_INJECTION` | `injectLogContext` |
| `DD_SERVERLESS_LOGS_ENABLED` | `enableDatadogLogs` |
| `DD_CAPTURE_LAMBDA_PAYLOAD` | `captureLambdaPayload` |
| `DD_LOG_LEVEL` | `logLevel` |
| `DD_TAGS` | `tags` |

The wrapper also exposes `enableDatadogASM` and `datadogAppSecMode`, but the
repository does not document a mechanical mapping for every AppSec-related
environment variable. Do not invent one; inspect the installed declarations
and the Datadog v5 behavior for the desired AppSec configuration. The same
applies to the two cloud-payload-tagging variables and
`AWS_LAMBDA_EXEC_WRAPPER`, for which this wrapper has no same-named prop.

If a per-function override is intentional, apply it only after instrumentation:

```typescript
datadog.addLambdaFunctions([handler]);
handler.addEnvironment('DD_LOG_LEVEL', 'debug');
```

An override of `DD_TAGS` at that point replaces all tags generated by the
construct, including Git metadata added through `addGitCommitMetadata()`.
`addLambdaFunctions()` validates the complete batch before changing any of its
functions. The validation covers the underlying CDK `Function` environment,
including `SingletonFunction` and values added with `addEnvironment()`; it
does not inspect `CfnFunction` escape-hatch overrides.

Source-code integration is enabled by default and can change generated
`DD_TAGS`. For snapshot tests that must disable it, set this exact context key
on the test `App` to either boolean `false` or string `"false"`:

```typescript
const app = new App({
  context: {
    '@rio-cloud-internal/cdk-v2-constructs:enableSourceCodeIntegration': false,
  },
});
```

Do not substitute the unrelated `datadog-cdk-constructs-v2` context key. Layer
version props remain required; choose versions compatible with the installed
Datadog Lambda Node and extension layer releases rather than copying stale
values from tests.

### Pipeline license-checker prerequisite

Before upgrading a project that uses the Team Transport pipeline, add
`@rio-cloud/rio-license-checker` as a direct dev dependency and commit the
corresponding lockfile:

```bash
npm install --save-dev @rio-cloud/rio-license-checker
```

The generated buildspecs call `npx rio-license-checker` after `npm ci`; the
construct no longer supplies this package transitively. Add it to the package
whose `npm ci` precedes the call:

| Generated pipeline feature | Workspace in which the checker is invoked | Package that needs the dev dependency |
| --- | --- | --- |
| Infrastructure synth | `infrastructure/` | `infrastructure/package.json` |
| `gradleBuild` | repository root | root `package.json` |
| `npmBuild` | repository root | root `package.json` |

If a project enables more than one of these generated build paths, make the
checker available in each corresponding workspace. A custom main/branch or
vulnerability buildspec is loaded instead of the generated one, so inspect
that file separately for its own license-check command and install location.
The package's release notes link to the internal [RIO license-check
guidance](https://confluence.collaboration-man.com/spaces/RIOSHIPPER/pages/448924008/License+Checks).

### Contribution imports and package dependencies

Contribution constructs are no longer exported from the package root. Use the
owner-level subpaths that are present in the installed package's `exports` map:

| Owner | Internal import path in `9.0.0` |
| --- | --- |
| Team Claid | `@rio-cloud-internal/cdk-v2-constructs/contributions/team-claid` |
| Team Outbound Order Book | `@rio-cloud-internal/cdk-v2-constructs/contributions/team-outbound-order-book` |
| Team Shipper Inbound Blue | `@rio-cloud-internal/cdk-v2-constructs/contributions/team-shipper-inbound-blue` |
| Smart Route / GitLab Runner | `@rio-cloud-internal/cdk-v2-constructs/contributions/smart-route` |
| Team Transport | `@rio-cloud-internal/cdk-v2-constructs/contributions/team-transport` |
| CoP Frontend | `@rio-cloud-internal/cdk-v2-constructs/contributions/cop-frontend` |

For example, change a root import while keeping the named imports:

```diff
-import { PipelineStack, PipelineType } from '@rio-cloud-internal/cdk-v2-constructs';
+import { PipelineStack, PipelineType } from '@rio-cloud-internal/cdk-v2-constructs/contributions/team-transport';
```

Team Transport was renamed from `team-transport-two` to `team-transport`.
Import its pipeline, Datadog, and synthetics constructs from the single
owner-level path above. Do not infer additional public subpaths from the
source directory layout; the installed `package.json` `exports` map is the
authority.

GitLab Runner consumers must also install
`@pepperize/cdk-autoscaling-gitlab-runner` as a direct project dependency:

```bash
npm install @pepperize/cdk-autoscaling-gitlab-runner
```

It is an optional peer dependency of this package, not a regular dependency
that a consuming project can obtain transitively. This additional dependency
is required only by projects importing the Smart Route GitLab Runner
constructs.

### TypeScript resolver required for contribution subpaths

The contribution imports depend on Node package export maps. A legacy
`moduleResolution: "node"` configuration does not resolve these imports
reliably. Use a resolver that honors `exports` and keep the `module` and
`moduleResolution` settings compatible. For example, a CommonJS-oriented
project can use:

```json
{
  "compilerOptions": {
    "module": "Node16",
    "moduleResolution": "node16"
  }
}
```

A bundler-managed project can instead use the corresponding `bundler`
resolution mode with its existing bundler-compatible module setting. Do not
change only `moduleResolution` in a configuration whose `module` setting is
incompatible; preserve the consuming project's module model and verify it with
the project's typecheck and synth commands.

### Team Transport CodeBuild runtime options

This is an alpha.4 pipeline feature rather than a breaking migration, but it
is relevant when updating pipeline code. Generated main, branch, and
vulnerability buildspecs continue to use Node.js 24 by default. To require an
exact toolchain, set `codeBuildOptions.nodejsVersion` and/or
`codeBuildOptions.npmVersion` to an exact `major.minor.patch` value. The
generated install phase checks the selected versions before installing project
dependencies; it does not install npm globally. These options affect only
generated buildspecs. A custom buildspec supplied through
`partialBuildSpecPath` or `vulnerabilityPartialBuildSpecPath` is responsible
for its own runtime and version checks.

