Hi @lancejpollard
I will be writing a tutorial but on the meantime and without a better answer I would try to explain better the “theory” with a short example.
A company can either have ALL their infrastructure in a single Terraform project, it is convenient but dangerous, so the general best practice is to have different projects limiting the scope of changes.
And the problem arises, How do you access existing Terraform resources created in a different project?
I see at least 3 options:
a. Search in AWS for the resources
b. Access TF State files from other projects to use its ouputs
c. Write a tf file with hardcoded ARNs (bad idea I think)
I will write an example for the first option, and will consider other options for a blog post.
0. Set up the VPC and other shared “basic” resources that we will reused by other Terraform projects company wide.
Project path \T0
File: Terraform_VPC.tf
Creates a VPC and a Subnet
terraform {
required_version = "~> 0.12"
}
provider "aws" {
shared_credentials_file = pathexpand("~/keys/ditwl_kp_infradmin.pem")
profile = "ditwl_infradmin"
region = "us-east-1"
version = "~> 2.0"
}
resource "aws_vpc" "ditwl-vpc" {
cidr_block = "172.17.32.0/19"
enable_dns_support = true
enable_dns_hostnames = true
tags = {
Name = "ditwl-vpc"
}
}
resource "aws_subnet" "ditwl-sn-za-pro-pub-32" {
vpc_id = aws_vpc.ditwl-vpc.id
cidr_block = "172.17.32.0/23"
availability_zone = "us-east-1a"
map_public_ip_on_launch = "true"
tags = {
Name = "ditwl-sn-za-pro-pub-32"
}
}
1. Search in AWS for the resources
A different project that uses credentials with access to the infrastructure created by the “company wide project” shown in step 0 (called T0). It doesn’t need access to project T0.
It will search for the resources like the VPC or a Subnet using a Terraform Data Source.
See available Data Sources, like subnet at https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnet
Project path \T1
File: Terraform_EC2.tf
terraform {
required_version = "~> 0.12"
}
provider "aws" {
shared_credentials_file = pathexpand("~/keys/ditwl_kp_infradmin.pem")
profile = "ditwl_infradmin"
region = "us-east-1"
version = "~> 2.0"
}
data "aws_ami" "ubuntu" {
most_recent = true
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
owners = ["099720109477"] # Canonical
}
#Find a VPC named "ditwl-vpc"
data "aws_vpc" "ditwl-vpc" {
filter {
name = "tag:Name"
values = ["ditwl-vpc"]
}
}
#Find a Subnet located at the VPC named "ditwl-vpc" with tag Name="ditwl-sn-za-pro-pub-32"
data "aws_subnet" "ditwl-sn-za-pro-pub-32" {
vpc_id = data.aws_vpc.ditwl-vpc.id
tags = {
Name = "ditwl-sn-za-pro-pub-32"
}
}
# Create an AWS instance in the Subnet "ditwl-sn-za-pro-pub-32"
resource "aws_instance" "ditwl-web-01" {
ami = data.aws_ami.ubuntu.id
instance_type = "t3.micro"
subnet_id = data.aws_subnet.ditwl-sn-za-pro-pub-32.id
tags = {
Name = "HelloWorld"
}
}
There are many ways to “search” for the resources, I have shown how to search the VPC using a filter and the subnet using a tag.
Please don’t consider this example code as a best practice, I like to use modules, vars, naming standards and tags that are not used in this short examples.