So i have created a project with terraform under an organization.
resource "google_project" "my_project" {
name = "My Project"
project_id = "your-project-id"
org_id = "1234567"
}
I have also created resource inside the project now i want to modify the project, i want to add "auto_create_network = false" does it effect the resources that are not using default vpc inside the project. As i don't want this change to effect the services(not using default vpc) that are running inside gcp. Any suggestion/advice is appreciated.
Related
To be Specific, I have two projects A and B. I want to add an IAM role to service account from project A in Project B. I'm executing terraform script from bitbucket pipeline
Below is the resource block I tried to implement.
resource "google_project_iam_member" "role1" {
project = var.project
role = "roles/dialogflow.admin"
member = "user:cui-server-service-account#cproject.iam.gserviceaccount.com"
}
project is the variable used for Project B and cproject is a variable used for Project A which I'll pass the project names during bitbucket pipeline execution.
member = "serviceAccount:<<service account email>>"
The prefix is to be serviceAccount rather than user from your example - see how the member/members argument is described
And check that the user (or service account) who (which) runs the terraform 'apply' - has relevant IAM roles to assign what you would like.
I'm pretty new to Terraform, my apologies if this question has an obvious answer I'm missing.
I am trying to create a terraform configuration file for an existing organization. I am able to provision everything I have in the main.tf outlined bellow except for the Shared folder that already exists within this organization.
Related github issues :
The folder operation violates display name uniqueness within the parent.
Generic error message when folder rename matches existing folder
Here are the steps I followed:
Manually create a Shared folder within the organization administration UI.
Manually create a Terraform admin project <redacted-project-name> at the root of the Shared folder.
Manually create a service account named terraform#<redacted-project-name> from the terraform admin project
Create, download and securely store a key for the terraform#<redacted-project-name> service account.
Enable APIs : cloudresourcemanager.googleapis.com, cloudbilling.googleapis.com, iam.googleapis.com, serviceusage.googleapis.com within the terraform admin project
Set permissions of the service account to role/owner, roles/resourcemanager.organizationAdmin, roles/resourcemanager.folderAdmin and roles/resourcemanager.projectCreator.
Create the main.tf
terraform {
required_providers {
google = {
source = "hashicorp/google"
version = "3.85.0"
}
}
}
provider "google" {
credentials = file(var.credentials_file)
region = var.region
zone = var.zone
}
data "google_organization" "org" {
organization = var.organization.id
}
resource "google_folder" "shared" {
display_name = "Shared"
parent = data.google_organization.org.name
}
resource "google_folder" "ddm" {
display_name = "Data and Digital Marketing"
parent = data.google_organization.org.name
}
resource "google_folder" "dtl" {
display_name = "DTL"
parent = google_folder.ddm.name
}
The error I receive :
Error: Error creating folder 'Shared' in 'organizations/<redacted-org-id>': Error waiting for creating folder: Error code 9, message: Folder reservation failed for parent [organizations/<redacted-org-id>], folder [] due to constraint: The folder operation violates display name uniqueness within the parent.
How do I include existing resources within the terraform config file?
For (organization) folders (such as the example above)
For the billing account
For projects, i.e. Am I supposed to declare or import the terraform admin project within the main.tf?
For service accounts, how to handle existing keys and permissions of the account that is running the terraform apply
For existing policies and enabling APIs
In order to include already-existing resources within the terraform template, use the import statement.
For Folders
In the Terraform documentation for google_folder :
# Both syntaxes are valid
$ terraform import google_folder.department1 1234567
$ terraform import google_folder.department1 folders/1234567
So for the example above,
Fetch the folder id using gcloud alpha resource-manager folders list --organization=<redacted_org_id> providing the organization id.
Save the folder id somewhere, and if not already done, declare the folder as a resource within the main.tf
resource "google_folder" "shared" {
display_name = "Shared"
parent = data.google_organization.org.name
}
Run the command : terraform import google_folder.shared folders/<redacted_folder_id>. You should get an output like google_folder.shared: Import prepared!
Make sure your infrastructure is updated via terraform plan.
No changes. Your infrastructure matches the configuration.
Terraform has compared your real infrastructure against your configuration
and found no differences, so no changes are needed.
I am planning to use terraform to deploy to GCP and I have read the instruction on how to set it up:
provider "google" {
project = "{{YOUR GCP PROJECT}}"
region = "us-central1"
zone = "us-central1-c"
}
it requires a project name in the provider configuration. But I am planning to create the project via terraform like below code:
resource "google_project" "my_project" {
name = "My Project"
project_id = "your-project-id"
org_id = "1234567"
}
how can I use terraform without a pre-created project?
Take a look on this tutorial (from Community):
Creating Google Cloud projects with Terraform
This tutorial assumes that you already have a Google Cloud account set up for your organization and that you are allowed to make organization-level changes in the account
First step,for example, is to setup your ENV variables with your Organization ID and your billing account ID which will allow you to create the projects using terraform:
export TF_VAR_org_id=YOUR_ORG_ID
export TF_VAR_billing_account=YOUR_BILLING_ACCOUNT_ID
export TF_ADMIN=${USER}-terraform-admin
export TF_CREDS=~/.config/gcloud/${USER}-terraform-admin.json
I read this article on using Terraform with GCP:
https://cloud.google.com/community/tutorials/managing-gcp-projects-with-terraform
I almost have it working, but I ran into some issues and wanted some clarification.
I made a terraform admin project, and made a service account in that project with the roles/viewer and roles/storage.admin roles. I then made a bucket in the admin project and use that as the terraform backend storage.
terraform {
backend "gcs" {
bucket = "test-terraform-admin-1"
prefix = "terraform/state"
credentials = "service-account.json"
}
}
I then use that service account to create another project and provision resources in that project:
provider "google" {
alias = "company_a"
credentials = "./service-account.json"
region = "us-east4"
zone = "us-east4-c"
version = "~> 2.12"
}
resource "google_project" "project" {
name = var.project_name
project_id = "${random_id.id.hex}"
billing_account = "${var.billing_account}"
org_id = "${var.org_id}"
}
I thought that it would be sufficient to enable services for the project created with terraform like this:
resource "google_project_service" "container_service" {
project = "${google_project.project.project_id}"
service = "container.googleapis.com"
}
However, I got an error when terraform tried to create my gke cluster:
resource "google_container_cluster" "primary" {
project = "${google_project.project.project_id}"
name = "main-gke-cluster"
node_pool {
....
}
network = "${google_compute_network.vpc_network.self_link}"
}
It said that the container service was not enabled yet for my project, and it referenced the terraform admin project ID (not the project created with the google_project resource!). It seems that I have to enable the services on the terraform admin project in order for the service account to access those services on any projects created by the service account.
In fact, I can get it working without ever enabling the container, servicenetworking, etc. services on the create project as long as they are enabled on the terraform admin project.
Is there some parent/child relationship between the projects where services in one project are inherited by projects created from a service account in the parent project? This seems to be the case, but I cannot find any documentation about this anywhere.
Thanks for listening!
In my company, we created a folder and a service account in this folder. Then, we created a project for terraform and each terraform job use the folder level service account for creating projects and resources into this folder.
As the role and permission are inherited from folder to lower level (folders or projects) we don't have issue to create resources.
I don't if it helps your specific issue, but for us, it solved a lot and simplify the service account management.
Google recommends deleting and creating your own VPC for prod
This resource manages the default VPC: https://www.terraform.io/docs/providers/aws/r/default_vpc.html
But I want to set a different VPC to be the default and delete the auto created one.
How is this possible?
You can avoid/skip the default network creation by setting an Organization Policy Constraint.
gcloud resource-manager org-policies enable-enforce \
constraints/compute.skipDefaultNetworkCreation \
--organization ORGANIZATION_ID
more details in Organization Policy Constraints and Using boolean constraints in organization policy
The default network does not have any specific configuration that makes it be the default network. It is just the one network that is always created together with a new project, and whenever a network is not specified (for instance, when deploying a GAE flex application), the network used will be the one with the name default. When you create a project with Terraform, you can specify auto_network_creation = "false".
However, this will not prevent the creation of the default network, it will just delete it before the project is fully created. This means that, during the Terraform creation, it is not possible to create another network called default. That must be done after the original default network is created, hence, after the project creation.
You can try creating projects with Terraform using this tutorial.
The next snippet is part of the tutorial, in which I included the line to delete the default network on project creation.
variable "project_name" {}
variable "billing_account" {}
variable "org_id" {}
variable "region" {}
provider "google" {
region = "${var.region}"
}
resource "random_id" "id" {
byte_length = 4
prefix = "${var.project_name}-"
}
resource "google_project" "project" {
name = "${var.project_name}"
project_id = "${random_id.id.hex}"
billing_account = "${var.billing_account}"
org_id = "${var.org_id}"
auto_create_network = "false" //This is supposed to delete default network on project creation
}
resource "google_project_services" "project" {
project = "${google_project.project.project_id}"
services = [
"compute.googleapis.com"
]
}
output "project_id" {
value = "${google_project.project.project_id}"
}
Nonetheless, I have tried it myself and the default network was still there.
As in Terraform you describe desired state of your configuration it is not possible to implicit send "destroy request" to a resource that is not managed by Terraform.
However you could try importing it firstly then it will be managed by Terraform and as you do not include it in your *.tf files the default subnet should be deleted during terraform apply step.
Setting property auto_create_network = "false" and mentioning a billing account ID, while creating a GCP project as in the below code snippet, ensures that default network gets deleted.
resource "google_project" "project" {
name = "test"
project_id = "test-523"
billing_account = "xxxxx"
auto_create_network = "false"
}