diff --git a/lib/modules/manager/gitlabci/common.spec.ts b/lib/modules/manager/gitlabci/common.spec.ts
index 5000b3ccb8458764dc034df27419e76f0db7e5bf..9c491ef848f968a696e2de2cb4b84677d9d81a4c 100644
--- a/lib/modules/manager/gitlabci/common.spec.ts
+++ b/lib/modules/manager/gitlabci/common.spec.ts
@@ -4,6 +4,7 @@ import type { GitlabPipeline } from '../gitlabci/types';
 import { replaceReferenceTags } from '../gitlabci/utils';
 import {
   filterIncludeFromGitlabPipeline,
+  isGitlabIncludeComponent,
   isGitlabIncludeLocal,
   isGitlabIncludeProject,
   isNonEmptyObject,
@@ -61,6 +62,16 @@ describe('modules/manager/gitlabci/common', () => {
     });
   });
 
+  describe('isGitlabIncludeComponent()', () => {
+    it('returns true if GitlabInclude is GitlabIncludeComponent', () => {
+      expect(isGitlabIncludeComponent({ component: 'something' })).toBe(true);
+    });
+
+    it('returns false if GitlabInclude is not GitlabIncludeComponent', () => {
+      expect(isGitlabIncludeComponent(includeLocal)).toBe(false);
+    });
+  });
+
   describe('isNonEmptyObject()', () => {
     it('returns true if not empty', () => {
       expect(isNonEmptyObject({ attribute1: 1 })).toBe(true);
diff --git a/lib/modules/manager/gitlabci/common.ts b/lib/modules/manager/gitlabci/common.ts
index 7aefb628e62d00320ab6a13382cb764e292ed396..38452d1b50a954b84a504e425eeb1ad7dd0b26d2 100644
--- a/lib/modules/manager/gitlabci/common.ts
+++ b/lib/modules/manager/gitlabci/common.ts
@@ -1,6 +1,7 @@
 import is from '@sindresorhus/is';
 import type {
   GitlabInclude,
+  GitlabIncludeComponent,
   GitlabIncludeLocal,
   GitlabIncludeProject,
   GitlabPipeline,
@@ -32,3 +33,9 @@ export function isGitlabIncludeLocal(
 ): include is GitlabIncludeLocal {
   return !is.undefined((include as GitlabIncludeLocal).local);
 }
+
+export function isGitlabIncludeComponent(
+  include: GitlabInclude,
+): include is GitlabIncludeComponent {
+  return !is.undefined((include as GitlabIncludeComponent).component);
+}
diff --git a/lib/modules/manager/gitlabci/extract.spec.ts b/lib/modules/manager/gitlabci/extract.spec.ts
index db03a11829205e7e78df7cc1621e94273fa73df2..820bef53ca564b64202e84802d8468a6745ac552 100644
--- a/lib/modules/manager/gitlabci/extract.spec.ts
+++ b/lib/modules/manager/gitlabci/extract.spec.ts
@@ -1,3 +1,4 @@
+import { codeBlock } from 'common-tags';
 import { logger } from '../../../../test/util';
 import { GlobalConfig } from '../../../config/global';
 import type { RepoGlobalConfig } from '../../../config/types';
@@ -347,5 +348,63 @@ describe('modules/manager/gitlabci/extract', () => {
       expect(extractFromJob(undefined)).toBeEmptyArray();
       expect(extractFromJob({ image: 'image:test' })).toEqual(expectedRes);
     });
+
+    it('extracts component references', () => {
+      const content = codeBlock`
+        include:
+          - component: gitlab.example.com/an-org/a-project/a-component@1.0
+            inputs:
+              stage: build
+          - component: gitlab.example.com/an-org/a-subgroup/a-project/a-component@e3262fdd0914fa823210cdb79a8c421e2cef79d8
+          - component: gitlab.example.com/an-org/a-subgroup/another-project/a-component@main
+          - component: gitlab.example.com/another-org/a-project/a-component@~latest
+            inputs:
+              stage: test
+          - component: gitlab.example.com/malformed-component-reference
+          - component:
+              malformed: true
+          - component: gitlab.example.com/an-org/a-component@1.0
+          - component: other-gitlab.example.com/an-org/a-project/a-component@1.0
+      `;
+      const res = extractPackageFile(content, '', {});
+      expect(res?.deps).toMatchObject([
+        {
+          currentValue: '1.0',
+          datasource: 'gitlab-tags',
+          depName: 'an-org/a-project',
+          depType: 'repository',
+          registryUrls: ['https://gitlab.example.com'],
+        },
+        {
+          currentValue: 'e3262fdd0914fa823210cdb79a8c421e2cef79d8',
+          datasource: 'gitlab-tags',
+          depName: 'an-org/a-subgroup/a-project',
+          depType: 'repository',
+          registryUrls: ['https://gitlab.example.com'],
+        },
+        {
+          currentValue: 'main',
+          datasource: 'gitlab-tags',
+          depName: 'an-org/a-subgroup/another-project',
+          depType: 'repository',
+          registryUrls: ['https://gitlab.example.com'],
+        },
+        {
+          currentValue: '~latest',
+          datasource: 'gitlab-tags',
+          depName: 'another-org/a-project',
+          depType: 'repository',
+          registryUrls: ['https://gitlab.example.com'],
+          skipReason: 'unsupported-version',
+        },
+        {
+          currentValue: '1.0',
+          datasource: 'gitlab-tags',
+          depName: 'an-org/a-project',
+          depType: 'repository',
+          registryUrls: ['https://other-gitlab.example.com'],
+        },
+      ]);
+    });
   });
 });
diff --git a/lib/modules/manager/gitlabci/extract.ts b/lib/modules/manager/gitlabci/extract.ts
index 8a7fdae5375602a470134f23255b3a9a51b8ee16..7df1894c615d29eba02670dc62ad6c8339090dd4 100644
--- a/lib/modules/manager/gitlabci/extract.ts
+++ b/lib/modules/manager/gitlabci/extract.ts
@@ -1,18 +1,38 @@
 import is from '@sindresorhus/is';
 import { logger } from '../../../logger';
 import { readLocalFile } from '../../../util/fs';
+import { regEx } from '../../../util/regex';
 import { trimLeadingSlash } from '../../../util/url';
 import { parseSingleYaml } from '../../../util/yaml';
+import { GitlabTagsDatasource } from '../../datasource/gitlab-tags';
 import type {
   ExtractConfig,
   PackageDependency,
   PackageFile,
   PackageFileContent,
 } from '../types';
-import { isGitlabIncludeLocal } from './common';
-import type { GitlabPipeline, Image, Job, Services } from './types';
+import {
+  filterIncludeFromGitlabPipeline,
+  isGitlabIncludeComponent,
+  isGitlabIncludeLocal,
+  isNonEmptyObject,
+} from './common';
+import type {
+  GitlabInclude,
+  GitlabIncludeComponent,
+  GitlabPipeline,
+  Image,
+  Job,
+  Services,
+} from './types';
 import { getGitlabDep, replaceReferenceTags } from './utils';
 
+// See https://docs.gitlab.com/ee/ci/components/index.html#use-a-component
+const componentReferenceRegex = regEx(
+  /(?<fqdn>[^/]+)\/(?<projectPath>.+)\/(?:.+)@(?<specificVersion>.+)/,
+);
+const componentReferenceLatestVersion = '~latest';
+
 export function extractFromImage(
   image: Image | undefined,
   registryAliases?: Record<string, string>,
@@ -76,6 +96,67 @@ export function extractFromJob(
   return deps;
 }
 
+function getIncludeComponentsFromInclude(
+  includeValue: GitlabInclude[] | GitlabInclude,
+): GitlabIncludeComponent[] {
+  const includes = is.array(includeValue) ? includeValue : [includeValue];
+  return includes.filter(isGitlabIncludeComponent);
+}
+
+function getAllIncludeComponents(
+  data: GitlabPipeline,
+): GitlabIncludeComponent[] {
+  const childrenData = Object.values(filterIncludeFromGitlabPipeline(data))
+    .filter(isNonEmptyObject)
+    .map(getAllIncludeComponents)
+    .flat();
+
+  // Process include key.
+  if (data.include) {
+    childrenData.push(...getIncludeComponentsFromInclude(data.include));
+  }
+  return childrenData;
+}
+
+function extractDepFromIncludeComponent(
+  includeComponent: GitlabIncludeComponent,
+): PackageDependency | null {
+  const componentReference = componentReferenceRegex.exec(
+    includeComponent.component,
+  )?.groups;
+  if (!componentReference) {
+    logger.debug(
+      { componentReference: includeComponent.component },
+      'Ignoring malformed component reference',
+    );
+    return null;
+  }
+  const projectPathParts = componentReference.projectPath.split('/');
+  if (projectPathParts.length < 2) {
+    logger.debug(
+      { componentReference: includeComponent.component },
+      'Ignoring component reference with incomplete project path',
+    );
+    return null;
+  }
+
+  const dep: PackageDependency = {
+    datasource: GitlabTagsDatasource.id,
+    depName: componentReference.projectPath,
+    depType: 'repository',
+    currentValue: componentReference.specificVersion,
+    registryUrls: [`https://${componentReference.fqdn}`],
+  };
+  if (dep.currentValue === componentReferenceLatestVersion) {
+    logger.debug(
+      { componentVersion: dep.currentValue },
+      'Ignoring component version',
+    );
+    dep.skipReason = 'unsupported-version';
+  }
+  return dep;
+}
+
 export function extractPackageFile(
   content: string,
   packageFile: string,
@@ -84,7 +165,7 @@ export function extractPackageFile(
   let deps: PackageDependency[] = [];
   try {
     // TODO: use schema (#9610)
-    const doc = parseSingleYaml(replaceReferenceTags(content), {
+    const doc = parseSingleYaml<GitlabPipeline>(replaceReferenceTags(content), {
       json: true,
     });
     if (is.object(doc)) {
@@ -115,11 +196,26 @@ export function extractPackageFile(
       }
       deps = deps.filter(is.truthy);
     }
+
+    const includedComponents = getAllIncludeComponents(doc);
+    for (const includedComponent of includedComponents) {
+      const dep = extractDepFromIncludeComponent(includedComponent);
+      if (dep) {
+        deps.push(dep);
+      }
+    }
   } catch (err) /* istanbul ignore next */ {
-    logger.debug(
-      { err, packageFile },
-      'Error extracting GitLab CI dependencies',
-    );
+    if (err.stack?.startsWith('YAMLException:')) {
+      logger.debug(
+        { err, packageFile },
+        'YAML exception extracting GitLab CI includes',
+      );
+    } else {
+      logger.debug(
+        { err, packageFile },
+        'Error extracting GitLab CI dependencies',
+      );
+    }
   }
 
   return deps.length ? { deps } : null;
diff --git a/lib/modules/manager/gitlabci/index.ts b/lib/modules/manager/gitlabci/index.ts
index 71946b1b4aaa99b968ddf0c832c7bc3b015fd994..be554bd2b73ca6343c25d3e6beca24490d01fc46 100644
--- a/lib/modules/manager/gitlabci/index.ts
+++ b/lib/modules/manager/gitlabci/index.ts
@@ -1,5 +1,6 @@
 import type { Category } from '../../../constants';
 import { DockerDatasource } from '../../datasource/docker';
+import { GitlabTagsDatasource } from '../../datasource/gitlab-tags';
 import { extractAllPackageFiles, extractPackageFile } from './extract';
 
 export { extractAllPackageFiles, extractPackageFile };
@@ -10,4 +11,7 @@ export const defaultConfig = {
 
 export const categories: Category[] = ['ci'];
 
-export const supportedDatasources = [DockerDatasource.id];
+export const supportedDatasources = [
+  DockerDatasource.id,
+  GitlabTagsDatasource.id,
+];
diff --git a/lib/modules/manager/gitlabci/types.ts b/lib/modules/manager/gitlabci/types.ts
index 9f8d7726b2f472391cb4ca54148c24373c3b46e2..3728b393bfcd364c0ef268540b9ed05a4272a114 100644
--- a/lib/modules/manager/gitlabci/types.ts
+++ b/lib/modules/manager/gitlabci/types.ts
@@ -16,6 +16,10 @@ export interface GitlabIncludeTemplate {
   template: string;
 }
 
+export interface GitlabIncludeComponent {
+  component: string;
+}
+
 export interface GitlabPipeline {
   include?: GitlabInclude[] | GitlabInclude;
 }
@@ -39,4 +43,5 @@ export type GitlabInclude =
   | GitlabIncludeProject
   | GitlabIncludeRemote
   | GitlabIncludeTemplate
+  | GitlabIncludeComponent
   | string;