Getting Started with Bigtable Instance Administrative Operations

This example is a very simple "Instance Admin" application, which illustrates how to:

  • Create a production instance.
  • List the existing instances.
  • Get the metadata for an instance.
  • List all the clusters in an instance.
  • Delete an instance.

Run the example

This example uses the Cloud Bigtable C++ Client Library to communicate with Cloud Bigtable.

To run the example program, follow the instructions for the example on GitHub.

Include the Necessary Headers

The example uses the following headers:

#include "google/cloud/bigtable/admin/bigtable_instance_admin_client.h" 

Define aliases

To make the example less verbose we define some aliases:

 namespace cbt = ::google::cloud::bigtable; namespace cbta = ::google::cloud::bigtable_admin; using ::google::cloud::future; using ::google::cloud::Location; using ::google::cloud::Project; using ::google::cloud::Status; using ::google::cloud::StatusOr; 

Connect to the Cloud Bigtable Instance Admin Endpoint.

Create an object of type bigtable_admin::BigtableInstanceAdminClient to obtain information about Instances, Clusters, Application Profiles, and to change the IAM permissions in a Cloud Bigtable instance:

 auto instance_admin = cbta::BigtableInstanceAdminClient( cbta::MakeBigtableInstanceAdminConnection()); 
See Also

https://cloud.google.com/bigtable/docs/instances-clusters-nodes for more information about Cloud Bigtable instances, clusters, and nodes.

See Also

https://cloud.google.com/bigtable/docs/app-profiles for more information about Cloud Bigtable application profiles.

See Also

https://cloud.google.com/bigtable/docs/access-control for more information about access controls via IAM permissions on Cloud Bigtable.

Check if an Instance already exists

 std::cout << "\nCheck Instance exists:\n"; auto const project = Project(project_id); std::string const project_name = project.FullName(); StatusOr<google::bigtable::admin::v2::ListInstancesResponse> instances = instance_admin.ListInstances(project_name); if (!instances) throw std::move(instances).status(); if (!instances->failed_locations().empty()) { std::cerr << "The service tells us it has no information about these locations:"; for (auto const& failed_location : instances->failed_locations()) { std::cerr << " " << failed_location; } std::cerr << ". Continuing anyway\n"; } std::string const instance_name = cbt::InstanceName(project_id, instance_id); auto is_instance = [&instance_name](google::bigtable::admin::v2::Instance const& i) { return i.name() == instance_name; }; auto const& ins = instances->instances(); auto instance_exists = std::find_if(ins.begin(), ins.end(), is_instance) != ins.end(); std::cout << "The instance " << instance_id << (instance_exists ? " already exists" : " does not exist") << "\n"; 
See Also

BigtableInstanceAdminClient::GetInstance() for another operation to query if an instance exists.

Create a Production Instance

Use BigtableInstanceAdminClient::CreateInstance() to create a new instance:

 std::cout << "\nCreating a PRODUCTION Instance: "; // production instance needs at least 3 nodes google::bigtable::admin::v2::Cluster c; c.set_location(Location(project, zone).FullName()); c.set_serve_nodes(3); c.set_default_storage_type(google::bigtable::admin::v2::HDD); google::bigtable::admin::v2::Instance in; in.set_display_name("Sample Instance"); in.set_type(google::bigtable::admin::v2::Instance::PRODUCTION); future<void> creation_done = instance_admin .CreateInstance(project_name, instance_id, std::move(in), {{cluster_id, std::move(c)}}) .then( [instance_id]( future<StatusOr<google::bigtable::admin::v2::Instance>> f) { auto instance = f.get(); if (!instance) { std::cerr << "Could not create instance " << instance_id << "\n"; throw std::move(instance).status(); } std::cout << "Successfully created instance: " << instance->DebugString() << "\n"; }); // Note how this blocks until the instance is created. In production code // you may want to perform this task asynchronously. creation_done.get(); std::cout << "DONE\n"; 

List Instances in a Project

Use BigtableInstanceAdminClient::ListInstances() to list all the instances in the project:

 std::cout << "\nListing Instances:\n"; instances = instance_admin.ListInstances(project_name); if (!instances) throw std::move(instances).status(); if (!instances->failed_locations().empty()) { std::cerr << "The service tells us it has no information about these locations:"; for (auto const& failed_location : instances->failed_locations()) { std::cerr << " " << failed_location; } std::cerr << ". Continuing anyway\n"; } for (auto const& instance : instances->instances()) { std::cout << " " << instance.name() << "\n"; } std::cout << "DONE\n"; 
See Also

The gRPC API documentation for ListInstances has more details on when failed_locations might be populated.

Get an Instance Metadata

Use BigtableInstanceAdminClient::GetInstance() to retrieve the metadata of an instance:

 std::cout << "\nGet Instance:\n"; auto instance = instance_admin.GetInstance(instance_name); if (!instance) throw std::move(instance).status(); std::cout << "Instance details :\n" << instance->DebugString() << "\n"; 

List clusters in an Instance

Use BigtableInstanceAdminClient::ListClusters() to list all the clusters in an instance (or all the clusters in a project):

 std::cout << "\nListing Clusters:\n"; StatusOr<google::bigtable::admin::v2::ListClustersResponse> cluster_list = instance_admin.ListClusters(instance_name); if (!cluster_list) throw std::move(cluster_list).status(); if (!cluster_list->failed_locations().empty()) { std::cout << "The Cloud Bigtable service reports that the following " "locations are temporarily unavailable and no information " "about clusters in these locations can be obtained:\n"; for (auto const& failed_location : cluster_list->failed_locations()) { std::cout << failed_location << "\n"; } } std::cout << "Cluster Name List:\n"; for (auto const& cluster : cluster_list->clusters()) { std::cout << "Cluster Name: " << cluster.name() << "\n"; } std::cout << "DONE\n"; 
See Also

The bigtable_admin::BigtableInstanceAdminClient class also has functions to create, update, delete, and retrieve the metadata of a Cluster.

See Also

The gRPC API documentation for ListClusters has more details on when failed_locations might be populated.

Delete an instance

Finally, use BigtableInstanceAdminClient::DeleteInstance() to delete an instance:

 std::cout << "Deleting instance " << instance_id << "\n"; Status delete_status = instance_admin.DeleteInstance(instance_name); if (!delete_status.ok()) throw std::runtime_error(delete_status.message()); std::cout << "DONE\n"; 

Put it all together

Here is the full example

 #include "google/cloud/bigtable/admin/bigtable_instance_admin_client.h" #include "google/cloud/bigtable/examples/bigtable_examples_common.h" #include "google/cloud/bigtable/resource_names.h" #include "google/cloud/bigtable/testing/cleanup_stale_resources.h" #include "google/cloud/bigtable/testing/random_names.h" #include "google/cloud/internal/getenv.h" #include "google/cloud/internal/random.h" #include "google/cloud/location.h" #include "google/cloud/log.h" #include "google/cloud/project.h" #include <algorithm> #include <iostream> namespace { using ::google::cloud::bigtable::examples::Usage; void BigtableHelloInstance(std::vector<std::string> const& argv) { if (argv.size() != 4) { throw Usage{ "hello-instance <project-id> <instance-id> <cluster-id> <zone>"}; } std::string const& project_id = argv[0]; std::string const& instance_id = argv[1]; std::string const& cluster_id = argv[2]; std::string const& zone = argv[3]; namespace cbt = ::google::cloud::bigtable; namespace cbta = ::google::cloud::bigtable_admin; using ::google::cloud::future; using ::google::cloud::Location; using ::google::cloud::Project; using ::google::cloud::Status; using ::google::cloud::StatusOr; // Connect to the Cloud Bigtable admin endpoint. auto instance_admin = cbta::BigtableInstanceAdminClient( cbta::MakeBigtableInstanceAdminConnection()); std::cout << "\nCheck Instance exists:\n"; auto const project = Project(project_id); std::string const project_name = project.FullName(); StatusOr<google::bigtable::admin::v2::ListInstancesResponse> instances = instance_admin.ListInstances(project_name); if (!instances) throw std::move(instances).status(); if (!instances->failed_locations().empty()) { std::cerr << "The service tells us it has no information about these locations:"; for (auto const& failed_location : instances->failed_locations()) { std::cerr << " " << failed_location; } std::cerr << ". Continuing anyway\n"; } std::string const instance_name = cbt::InstanceName(project_id, instance_id); auto is_instance = [&instance_name](google::bigtable::admin::v2::Instance const& i) { return i.name() == instance_name; }; auto const& ins = instances->instances(); auto instance_exists = std::find_if(ins.begin(), ins.end(), is_instance) != ins.end(); std::cout << "The instance " << instance_id << (instance_exists ? " already exists" : " does not exist") << "\n"; // Create instance if it does not exist if (!instance_exists) { std::cout << "\nCreating a PRODUCTION Instance: "; // production instance needs at least 3 nodes google::bigtable::admin::v2::Cluster c; c.set_location(Location(project, zone).FullName()); c.set_serve_nodes(3); c.set_default_storage_type(google::bigtable::admin::v2::HDD); google::bigtable::admin::v2::Instance in; in.set_display_name("Sample Instance"); in.set_type(google::bigtable::admin::v2::Instance::PRODUCTION); future<void> creation_done = instance_admin .CreateInstance(project_name, instance_id, std::move(in), {{cluster_id, std::move(c)}}) .then( [instance_id]( future<StatusOr<google::bigtable::admin::v2::Instance>> f) { auto instance = f.get(); if (!instance) { std::cerr << "Could not create instance " << instance_id << "\n"; throw std::move(instance).status(); } std::cout << "Successfully created instance: " << instance->DebugString() << "\n"; }); // Note how this blocks until the instance is created. In production code // you may want to perform this task asynchronously. creation_done.get(); std::cout << "DONE\n"; } std::cout << "\nListing Instances:\n"; instances = instance_admin.ListInstances(project_name); if (!instances) throw std::move(instances).status(); if (!instances->failed_locations().empty()) { std::cerr << "The service tells us it has no information about these locations:"; for (auto const& failed_location : instances->failed_locations()) { std::cerr << " " << failed_location; } std::cerr << ". Continuing anyway\n"; } for (auto const& instance : instances->instances()) { std::cout << " " << instance.name() << "\n"; } std::cout << "DONE\n"; std::cout << "\nGet Instance:\n"; auto instance = instance_admin.GetInstance(instance_name); if (!instance) throw std::move(instance).status(); std::cout << "Instance details :\n" << instance->DebugString() << "\n"; std::cout << "\nListing Clusters:\n"; StatusOr<google::bigtable::admin::v2::ListClustersResponse> cluster_list = instance_admin.ListClusters(instance_name); if (!cluster_list) throw std::move(cluster_list).status(); if (!cluster_list->failed_locations().empty()) { std::cout << "The Cloud Bigtable service reports that the following " "locations are temporarily unavailable and no information " "about clusters in these locations can be obtained:\n"; for (auto const& failed_location : cluster_list->failed_locations()) { std::cout << failed_location << "\n"; } } std::cout << "Cluster Name List:\n"; for (auto const& cluster : cluster_list->clusters()) { std::cout << "Cluster Name: " << cluster.name() << "\n"; } std::cout << "DONE\n"; std::cout << "Deleting instance " << instance_id << "\n"; Status delete_status = instance_admin.DeleteInstance(instance_name); if (!delete_status.ok()) throw std::runtime_error(delete_status.message()); std::cout << "DONE\n"; } void RunAll(std::vector<std::string> const& argv) { namespace examples = ::google::cloud::bigtable::examples; namespace cbta = ::google::cloud::bigtable_admin; if (!argv.empty()) throw Usage{"auto"}; if (!examples::RunAdminIntegrationTests()) return; examples::CheckEnvironmentVariablesAreSet({ "GOOGLE_CLOUD_PROJECT", "GOOGLE_CLOUD_CPP_BIGTABLE_TEST_ZONE_A", }); auto const project_id = google::cloud::internal::GetEnv("GOOGLE_CLOUD_PROJECT").value(); auto const zone_a = google::cloud::internal::GetEnv("GOOGLE_CLOUD_CPP_BIGTABLE_TEST_ZONE_A") .value(); auto generator = google::cloud::internal::DefaultPRNG(std::random_device{}()); google::cloud::bigtable::testing::CleanupStaleInstances( cbta::MakeBigtableInstanceAdminConnection(), project_id); auto const instance_id = google::cloud::bigtable::testing::RandomInstanceId(generator); auto const cluster_id = instance_id + "-c1"; std::cout << "\nRunning the BigtableHelloInstance() example" << std::endl; BigtableHelloInstance({project_id, instance_id, cluster_id, zone_a}); } } // namespace int main(int argc, char* argv[]) try { google::cloud::bigtable::examples::Example example({ {"auto", RunAll}, {"hello-instance", BigtableHelloInstance}, }); return example.Run(argc, argv); } catch (std::exception const& ex) { std::cerr << ex.what() << "\n"; ::google::cloud::LogSink::Instance().Flush(); return 1; }