diff --git a/ci/cloudbuild/dockerfiles/demo-rockylinux-9.Dockerfile b/ci/cloudbuild/dockerfiles/demo-rockylinux-9.Dockerfile
new file mode 100644
index 0000000000000..6444d6b1124a2
--- /dev/null
+++ b/ci/cloudbuild/dockerfiles/demo-rockylinux-9.Dockerfile
@@ -0,0 +1,187 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+FROM rockylinux/rockylinux:9
+ARG NCPU=4
+
+## [BEGIN packaging.md]
+
+# Install the minimal development tools, libcurl, OpenSSL, and the c-ares
+# library (required by gRPC):
+
+# ```bash
+RUN dnf makecache && \
+ dnf update -y && \
+ dnf install -y epel-release && \
+ dnf makecache && \
+ dnf install -y ccache cmake curl findutils gcc-c++ git make openssl-devel \
+ patch re2-devel zlib-devel libcurl-devel c-ares-devel tar wget which
+# ```
+
+# Rocky Linux's version of `pkg-config` (https://github.com/pkgconf/pkgconf) is
+# slow when handling `.pc` files with lots of `Requires:` deps, which happens
+# with Abseil. If you plan to use `pkg-config` with any of the installed
+# artifacts, you may want to use a recent version of the standard `pkg-config`
+# binary. If not, `dnf install pkgconfig` should work.
+
+# ```bash
+WORKDIR /var/tmp/build/pkg-config-cpp
+RUN curl -sSL https://pkgconfig.freedesktop.org/releases/pkg-config-0.29.2.tar.gz | \
+ tar -xzf - --strip-components=1 && \
+ ./configure --with-internal-glib && \
+ make -j ${NCPU:-4} && \
+ make install && \
+ ldconfig
+# ```
+
+# The following steps will install libraries and tools in `/usr/local`. By
+# default, Rocky Linux 9 does not search for shared libraries in these
+# directories, there are multiple ways to solve this problem, the following
+# steps are one solution:
+
+# ```bash
+RUN (echo "/usr/local/lib" ; echo "/usr/local/lib64") | \
+ tee /etc/ld.so.conf.d/usrlocal.conf
+ENV PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:/usr/local/lib64/pkgconfig:/usr/lib64/pkgconfig
+ENV PATH=/usr/local/bin:${PATH}
+# ```
+
+# #### Abseil
+
+# Rocky Linux 9 includes a package for Abseil, unfortunately, this package is
+# incomplete, as it lacks the CMake support files for it. We need to compile
+# Abseiil from source.
+
+# :warning: By default, Abseil's ABI changes depending on whether it is used
+# with C++ >= 17 enabled or not. Installing Abseil with the default
+# configuration is error-prone, unless you can guarantee that all the code using
+# Abseil (gRPC, google-cloud-cpp, your own code, etc.) is compiled with the same
+# C++ version. We recommend that you switch the default configuration to pin
+# Abseil's ABI to the version used at compile time. In Rocky Linux 9 the
+# compiler defaults to C++17. Therefore, we change `absl/base/options.h` to
+# **always** use `std::any`, `std::string_view`, and `std::variant`. See
+# [abseil/abseil-cpp#696] for more information.
+
+# ```bash
+WORKDIR /var/tmp/build/abseil-cpp
+RUN curl -sSL https://github.com/abseil/abseil-cpp/archive/20220623.1.tar.gz | \
+ tar -xzf - --strip-components=1 && \
+ sed -i 's/^#define ABSL_OPTION_USE_\(.*\) 2/#define ABSL_OPTION_USE_\1 1/' "absl/base/options.h" && \
+ cmake \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DABSL_BUILD_TESTING=OFF \
+ -DBUILD_SHARED_LIBS=yes \
+ -S . -B cmake-out && \
+ cmake --build cmake-out -- -j ${NCPU:-4} && \
+ cmake --build cmake-out --target install -- -j ${NCPU:-4} && \
+ ldconfig
+# ```
+
+# #### Protobuf
+
+# Rocky Linux ships with Protobuf 3.14.x. Some of the libraries in
+# `google-cloud-cpp` require Protobuf >= 3.15.8. For simplicity, we will just
+# install Protobuf (and any downstream packages) from source.
+
+# ```bash
+WORKDIR /var/tmp/build/protobuf
+RUN curl -sSL https://github.com/protocolbuffers/protobuf/archive/v21.9.tar.gz | \
+ tar -xzf - --strip-components=1 && \
+ cmake \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DBUILD_SHARED_LIBS=yes \
+ -Dprotobuf_BUILD_TESTS=OFF \
+ -Dprotobuf_ABSL_PROVIDER=package \
+ -S . -B cmake-out && \
+ cmake --build cmake-out -- -j ${NCPU:-4} && \
+ cmake --build cmake-out --target install -- -j ${NCPU:-4} && \
+ ldconfig
+# ```
+
+# #### gRPC
+
+# We also need a version of gRPC that is recent enough to support the Google
+# Cloud Platform proto files. Note that gRPC overrides the default C++ standard
+# version to C++14, we need to configure it to use the platform's default. We
+# manually install it using:
+
+# ```bash
+WORKDIR /var/tmp/build/grpc
+RUN curl -sSL https://github.com/grpc/grpc/archive/v1.49.1.tar.gz | \
+ tar -xzf - --strip-components=1 && \
+ cmake \
+ -DCMAKE_CXX_STANDARD=17 \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DBUILD_SHARED_LIBS=yes \
+ -DgRPC_INSTALL=ON \
+ -DgRPC_BUILD_TESTS=OFF \
+ -DgRPC_ABSL_PROVIDER=package \
+ -DgRPC_CARES_PROVIDER=package \
+ -DgRPC_PROTOBUF_PROVIDER=package \
+ -DgRPC_RE2_PROVIDER=package \
+ -DgRPC_SSL_PROVIDER=package \
+ -DgRPC_ZLIB_PROVIDER=package \
+ -S . -B cmake-out && \
+ cmake --build cmake-out -- -j ${NCPU:-4} && \
+ cmake --build cmake-out --target install -- -j ${NCPU:-4} && \
+ ldconfig
+# ```
+
+# #### crc32c
+
+# The project depends on the Crc32c library, we need to compile this from
+# source:
+
+# ```bash
+WORKDIR /var/tmp/build/crc32c
+RUN curl -sSL https://github.com/google/crc32c/archive/1.1.2.tar.gz | \
+ tar -xzf - --strip-components=1 && \
+ cmake \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DBUILD_SHARED_LIBS=yes \
+ -DCRC32C_BUILD_TESTS=OFF \
+ -DCRC32C_BUILD_BENCHMARKS=OFF \
+ -DCRC32C_USE_GLOG=OFF \
+ -S . -B cmake-out && \
+ cmake --build cmake-out -- -j ${NCPU:-4} && \
+ cmake --build cmake-out --target install -- -j ${NCPU:-4} && \
+ ldconfig
+# ```
+
+# #### nlohmann_json library
+
+# The project depends on the nlohmann_json library. We use CMake to
+# install it as this installs the necessary CMake configuration files.
+# Note that this is a header-only library, and often installed manually.
+# This leaves your environment without support for CMake pkg-config.
+
+# ```bash
+WORKDIR /var/tmp/build/json
+RUN curl -sSL https://github.com/nlohmann/json/archive/v3.11.2.tar.gz | \
+ tar -xzf - --strip-components=1 && \
+ cmake \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DBUILD_SHARED_LIBS=yes \
+ -DBUILD_TESTING=OFF \
+ -DJSON_BuildTests=OFF \
+ -S . -B cmake-out && \
+ cmake --build cmake-out --target install -- -j ${NCPU:-4} && \
+ ldconfig
+# ```
+
+## [DONE packaging.md]
+
+# Some of the above libraries may have installed in /usr/local, so make sure
+# those library directories will be found.
+RUN ldconfig /usr/local/lib*
diff --git a/ci/cloudbuild/triggers/demo-rockylinux-9-ci.yaml b/ci/cloudbuild/triggers/demo-rockylinux-9-ci.yaml
new file mode 100644
index 0000000000000..b29a98b528600
--- /dev/null
+++ b/ci/cloudbuild/triggers/demo-rockylinux-9-ci.yaml
@@ -0,0 +1,13 @@
+filename: ci/cloudbuild/cloudbuild.yaml
+github:
+ name: google-cloud-cpp
+ owner: googleapis
+ push:
+ branch: ^main$
+name: demo-rockylinux-9-ci
+substitutions:
+ _BUILD_NAME: demo-install
+ _DISTRO: demo-rockylinux-9
+ _TRIGGER_TYPE: ci
+tags:
+- ci
diff --git a/ci/cloudbuild/triggers/demo-rockylinux-9-pr.yaml b/ci/cloudbuild/triggers/demo-rockylinux-9-pr.yaml
new file mode 100644
index 0000000000000..3ed901205e778
--- /dev/null
+++ b/ci/cloudbuild/triggers/demo-rockylinux-9-pr.yaml
@@ -0,0 +1,14 @@
+filename: ci/cloudbuild/cloudbuild.yaml
+github:
+ name: google-cloud-cpp
+ owner: googleapis
+ pullRequest:
+ branch: ^main$
+ commentControl: COMMENTS_ENABLED_FOR_EXTERNAL_CONTRIBUTORS_ONLY
+name: demo-rockylinux-9-pr
+substitutions:
+ _BUILD_NAME: demo-install
+ _DISTRO: demo-rockylinux-9
+ _TRIGGER_TYPE: pr
+tags:
+- pr
diff --git a/ci/generate-markdown/generate-packaging.sh b/ci/generate-markdown/generate-packaging.sh
index 8ace3ce1bb5ac..e5dac648981e3 100755
--- a/ci/generate-markdown/generate-packaging.sh
+++ b/ci/generate-markdown/generate-packaging.sh
@@ -176,6 +176,7 @@ DOCKER_DISTROS=(
"demo-debian-bullseye.Dockerfile,Debian (11 - Bullseye)"
"demo-debian-buster.Dockerfile,Debian (10 - Buster)"
"demo-rockylinux-8.Dockerfile,Rocky Linux (8)"
+ "demo-rockylinux-9.Dockerfile,Rocky Linux (9)"
"demo-centos-7.Dockerfile,CentOS (7)"
)
for distro in "${DOCKER_DISTROS[@]}"; do
diff --git a/doc/packaging.md b/doc/packaging.md
index 9c49193c63f1c..67c9f44492ce2 100644
--- a/doc/packaging.md
+++ b/doc/packaging.md
@@ -1501,6 +1501,191 @@ cmake --build cmake-out --target install
+
+Rocky Linux (9)
+
+
+Install the minimal development tools, libcurl, OpenSSL, and the c-ares
+library (required by gRPC):
+
+```bash
+sudo dnf makecache && \
+sudo dnf update -y && \
+sudo dnf install -y epel-release && \
+sudo dnf makecache && \
+sudo dnf install -y ccache cmake curl findutils gcc-c++ git make openssl-devel \
+ patch re2-devel zlib-devel libcurl-devel c-ares-devel tar wget which
+```
+
+Rocky Linux's version of `pkg-config` (https://github.com/pkgconf/pkgconf) is
+slow when handling `.pc` files with lots of `Requires:` deps, which happens
+with Abseil. If you plan to use `pkg-config` with any of the installed
+artifacts, you may want to use a recent version of the standard `pkg-config`
+binary. If not, `sudo dnf install pkgconfig` should work.
+
+```bash
+mkdir -p $HOME/Downloads/pkg-config-cpp && cd $HOME/Downloads/pkg-config-cpp
+curl -sSL https://pkgconfig.freedesktop.org/releases/pkg-config-0.29.2.tar.gz | \
+ tar -xzf - --strip-components=1 && \
+ ./configure --with-internal-glib && \
+ make -j ${NCPU:-4} && \
+sudo make install && \
+sudo ldconfig
+```
+
+The following steps will install libraries and tools in `/usr/local`. By
+default, Rocky Linux 9 does not search for shared libraries in these
+directories, there are multiple ways to solve this problem, the following
+steps are one solution:
+
+```bash
+(echo "/usr/local/lib" ; echo "/usr/local/lib64") | \
+sudo tee /etc/ld.so.conf.d/usrlocal.conf
+export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:/usr/local/lib64/pkgconfig:/usr/lib64/pkgconfig
+export PATH=/usr/local/bin:${PATH}
+```
+
+#### Abseil
+
+Rocky Linux 9 includes a package for Abseil, unfortunately, this package is
+incomplete, as it lacks the CMake support files for it. We need to compile
+Abseiil from source.
+
+:warning: By default, Abseil's ABI changes depending on whether it is used
+with C++ >= 17 enabled or not. Installing Abseil with the default
+configuration is error-prone, unless you can guarantee that all the code using
+Abseil (gRPC, google-cloud-cpp, your own code, etc.) is compiled with the same
+C++ version. We recommend that you switch the default configuration to pin
+Abseil's ABI to the version used at compile time. In Rocky Linux 9 the
+compiler defaults to C++17. Therefore, we change `absl/base/options.h` to
+**always** use `std::any`, `std::string_view`, and `std::variant`. See
+[abseil/abseil-cpp#696] for more information.
+
+```bash
+mkdir -p $HOME/Downloads/abseil-cpp && cd $HOME/Downloads/abseil-cpp
+curl -sSL https://github.com/abseil/abseil-cpp/archive/20220623.1.tar.gz | \
+ tar -xzf - --strip-components=1 && \
+ sed -i 's/^#define ABSL_OPTION_USE_\(.*\) 2/#define ABSL_OPTION_USE_\1 1/' "absl/base/options.h" && \
+ cmake \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DABSL_BUILD_TESTING=OFF \
+ -DBUILD_SHARED_LIBS=yes \
+ -S . -B cmake-out && \
+ cmake --build cmake-out -- -j ${NCPU:-4} && \
+sudo cmake --build cmake-out --target install -- -j ${NCPU:-4} && \
+sudo ldconfig
+```
+
+#### Protobuf
+
+Rocky Linux ships with Protobuf 3.14.x. Some of the libraries in
+`google-cloud-cpp` require Protobuf >= 3.15.8. For simplicity, we will just
+install Protobuf (and any downstream packages) from source.
+
+```bash
+mkdir -p $HOME/Downloads/protobuf && cd $HOME/Downloads/protobuf
+curl -sSL https://github.com/protocolbuffers/protobuf/archive/v21.9.tar.gz | \
+ tar -xzf - --strip-components=1 && \
+ cmake \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DBUILD_SHARED_LIBS=yes \
+ -Dprotobuf_BUILD_TESTS=OFF \
+ -Dprotobuf_ABSL_PROVIDER=package \
+ -S . -B cmake-out && \
+ cmake --build cmake-out -- -j ${NCPU:-4} && \
+sudo cmake --build cmake-out --target install -- -j ${NCPU:-4} && \
+sudo ldconfig
+```
+
+#### gRPC
+
+We also need a version of gRPC that is recent enough to support the Google
+Cloud Platform proto files. Note that gRPC overrides the default C++ standard
+version to C++14, we need to configure it to use the platform's default. We
+manually install it using:
+
+```bash
+mkdir -p $HOME/Downloads/grpc && cd $HOME/Downloads/grpc
+curl -sSL https://github.com/grpc/grpc/archive/v1.49.1.tar.gz | \
+ tar -xzf - --strip-components=1 && \
+ cmake \
+ -DCMAKE_CXX_STANDARD=17 \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DBUILD_SHARED_LIBS=yes \
+ -DgRPC_INSTALL=ON \
+ -DgRPC_BUILD_TESTS=OFF \
+ -DgRPC_ABSL_PROVIDER=package \
+ -DgRPC_CARES_PROVIDER=package \
+ -DgRPC_PROTOBUF_PROVIDER=package \
+ -DgRPC_RE2_PROVIDER=package \
+ -DgRPC_SSL_PROVIDER=package \
+ -DgRPC_ZLIB_PROVIDER=package \
+ -S . -B cmake-out && \
+ cmake --build cmake-out -- -j ${NCPU:-4} && \
+sudo cmake --build cmake-out --target install -- -j ${NCPU:-4} && \
+sudo ldconfig
+```
+
+#### crc32c
+
+The project depends on the Crc32c library, we need to compile this from
+source:
+
+```bash
+mkdir -p $HOME/Downloads/crc32c && cd $HOME/Downloads/crc32c
+curl -sSL https://github.com/google/crc32c/archive/1.1.2.tar.gz | \
+ tar -xzf - --strip-components=1 && \
+ cmake \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DBUILD_SHARED_LIBS=yes \
+ -DCRC32C_BUILD_TESTS=OFF \
+ -DCRC32C_BUILD_BENCHMARKS=OFF \
+ -DCRC32C_USE_GLOG=OFF \
+ -S . -B cmake-out && \
+ cmake --build cmake-out -- -j ${NCPU:-4} && \
+sudo cmake --build cmake-out --target install -- -j ${NCPU:-4} && \
+sudo ldconfig
+```
+
+#### nlohmann_json library
+
+The project depends on the nlohmann_json library. We use CMake to
+install it as this installs the necessary CMake configuration files.
+Note that this is a header-only library, and often installed manually.
+This leaves your environment without support for CMake pkg-config.
+
+```bash
+mkdir -p $HOME/Downloads/json && cd $HOME/Downloads/json
+curl -sSL https://github.com/nlohmann/json/archive/v3.11.2.tar.gz | \
+ tar -xzf - --strip-components=1 && \
+ cmake \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DBUILD_SHARED_LIBS=yes \
+ -DBUILD_TESTING=OFF \
+ -DJSON_BuildTests=OFF \
+ -S . -B cmake-out && \
+sudo cmake --build cmake-out --target install -- -j ${NCPU:-4} && \
+sudo ldconfig
+```
+
+#### Compile and install the main project
+
+We can now compile and install `google-cloud-cpp`:
+
+```bash
+# Pick a location to install the artifacts, e.g., `/usr/local` or `/opt`
+PREFIX="${HOME}/google-cloud-cpp-installed"
+cmake -H. -Bcmake-out \
+ -DCMAKE_INSTALL_PREFIX="${PREFIX}" \
+ -DCMAKE_INSTALL_MESSAGE=NEVER \
+ -DBUILD_TESTING=OFF \
+ -DGOOGLE_CLOUD_CPP_ENABLE_EXAMPLES=OFF
+cmake --build cmake-out -- -j "$(nproc)"
+cmake --build cmake-out --target install
+```
+
+
+
CentOS (7)