> ## Documentation Index
> Fetch the complete documentation index at: https://synthetiq.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# CI

> Repo, review, merge — the production setup

Config in git, plan on PR, apply on merge — no stored credentials, and the config author needs no AWS access. Each step links to the page with the details; full background: [CI Integration](/docs/platform-docs/deployments/byoi/ci-integration).

<Note>
  Setting this up requires the `org:service-accounts` and `org:trusts` org scopes, plus your [organization id](/docs/platform-docs/deployments/byoi/prerequisites#finding-your-organization-id). See [Required Synthetiq permissions](/docs/platform-docs/deployments/byoi/prerequisites#required-synthetiq-permissions) and check yours with `synthetiq whoami`.
</Note>

<Steps>
  <Step title="Issue the two certificates">
    Request both ACM certs, add the **2 validation CNAMEs** at your DNS provider, and wait for `ISSUED`. Note the two ARNs. See [Certificates](/docs/platform-docs/deployments/byoi/certificates). (Validation can take a while — start it first.)
  </Step>

  <Step title="Create the GitHub repo">
    Create a **private** repo from [`SynthetiqAI/infra-template`](https://github.com/SynthetiqAI/infra-template) — it ships the workflow, a pinned `@synthetiq/cli`, the private-registry `.npmrc`, and an `_infra/` skeleton:

    ```bash theme={null}
    gh repo create <github-org>/synthetiq-infra \
      --template SynthetiqAI/infra-template --private
    ```

    Or use [**Use this template**](https://github.com/SynthetiqAI/infra-template/generate) in the GitHub UI.

    Then add the **`SYNTHETIQ_NPM_KEY`** repo secret (Settings → Secrets and variables → Actions → Repository secrets).
  </Step>

  <Step title="Create the two AWS roles">
    In the target AWS account, create two roles trusting GitHub OIDC, each scoped to the repo you just created. Replace `<github-org>/<repo>` with it — e.g. `acme/synthetiq-infra`:

    * **plan** — trusts `repo:<github-org>/<repo>:pull_request`; policy from `synthetiq infra permissions --stage generate`
    * **apply** — trusts `repo:<github-org>/<repo>:ref:refs/heads/main`; policy from `synthetiq infra permissions --stage provision`

    Note both role ARNs — you'll add them to the workflow when you set up the repo locally.
  </Step>

  <Step title="Create the Synthetiq service account">
    Find the role id for **CI Provision Apply**:

    ```bash theme={null}
    synthetiq role list
    ```

    Create the service account with that role (e.g. name it `CI Provisioner`):

    ```bash theme={null}
    synthetiq service-account create <name> --role-id <role-id>
    ```

    Create the OIDC trust so CI can authenticate as it — use the same repo as the apply role:

    ```bash theme={null}
    synthetiq trust create \
      --service-account-id <service-account-id> \
      --issuer https://token.actions.githubusercontent.com \
      --subject "repo:<github-org>/<repo>:ref:refs/heads/main"
    ```

    See [Service Account](/docs/platform-docs/deployments/byoi/service-account).
  </Step>

  <Step title="Set up the repo locally">
    Clone the repo:

    ```bash theme={null}
    gh repo clone <github-org>/synthetiq-infra
    cd synthetiq-infra
    ```

    Install the pinned CLI (this also generates the lockfile CI installs from):

    ```bash theme={null}
    SYNTHETIQ_NPM_KEY=<key> npm install
    ```

    Fill the three values in `.github/workflows/synthetiq-infra.yml` — the two role ARNs (use the ARNs you noted from the roles step; `<your-aws-account-id>` is your 12-digit account number) and your org id:

    ```yaml theme={null}
        with:
          plan-role-arn: arn:aws:iam::<your-aws-account-id>:role/synthetiq-infra-plan
          apply-role-arn: arn:aws:iam::<your-aws-account-id>:role/synthetiq-infra-apply
          organization-id: <your-org-id>
    ```

    See [CI Integration](/docs/platform-docs/deployments/byoi/ci-integration) for the full workflow it wraps.

    <Accordion title="Keeping the infra root in a subdirectory">
      To nest `package.json`, `.npmrc`, and `_infra/` under a subdirectory (e.g. `partner/synthetiq/`) instead of the repo root — useful inside a shared infrastructure monorepo — move them there together, add `working-directory: partner/synthetiq` to the workflow's `with:` block, and prefix the trigger `paths:` with the same directory. Run the `npm install` and `synthetiq infra` commands in the following steps from inside that directory, and adjust the `git add` paths to match. See [Nested directory layout](/docs/platform-docs/deployments/byoi/ci-integration#nested-directory-layout).
    </Accordion>
  </Step>

  <Step title="Author the config and open the PR">
    On a branch, generate the config:

    ```bash theme={null}
    git checkout -b add-infra-config
    npx synthetiq infra init --domain apps.yourcompany.com
    ```

    With no AWS credentials, init runs in offline mode: enter your VPC and public subnet ids and the two certificate ARNs. See [Generating synthetiq.yaml](/docs/platform-docs/deployments/byoi/configuration).

    Commit the workflow edit, the lockfile, and the config **together**, then push and open the PR:

    ```bash theme={null}
    git add .github/workflows/synthetiq-infra.yml package-lock.json _infra/synthetiq.yaml
    git commit -m "Configure Synthetiq infra"
    git push -u origin add-infra-config
    ```

    The pull request CI job runs against the real account and posts the proposed CloudFormation diff plus a summary of the proposed changeset as a PR comment.
  </Step>

  <Step title="Review & merge">
    Review the diff, then merge. On merge the CI applies the changeset on the target AWS account. The job log ends with the **3 app DNS records** that you will need to configure to finalize the provisioning — this is a one-time setup, only needed on the initial provisioning (unless you later change the `domain` configuration for Synthetiq apps). See [DNS setup](/docs/platform-docs/deployments/byoi/dns) for more details.
  </Step>
</Steps>

To update later: edit the config — or let a dependency bot like **Renovate** or **Dependabot** open the [version-bump PR](/docs/platform-docs/deployments/byoi/ci-integration#staying-current) — and the same PR → review → merge loop applies it.
