Skip to content

Commit e88f2c0

Browse files
committed
docs: update terraform docs
1 parent 7a4efd8 commit e88f2c0

File tree

10 files changed

+194
-20
lines changed

10 files changed

+194
-20
lines changed

Diff for: docs/terraform/files/aws/aws-provider.tf

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
provider "aws" {
2+
region = "us-east"
3+
profile = "default"
4+
}

Diff for: docs/terraform/files/aws/iam-user-policy.tf

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# main.tf
2+
resource "aws_iam_user" "admin-user" {
3+
name = "lucy"
4+
tags = {
5+
Description = "Technical Team Leader"
6+
}
7+
}
8+
9+
resource "aws_iam_policy" "adminUser" {
10+
name = "AdminUsers"
11+
policy = <<EOF
12+
{
13+
"Version": "2012-10-17",
14+
"Statement": [
15+
{
16+
"Effect": "Allow",
17+
"Action": "*",
18+
"Resource": "*"
19+
}
20+
]
21+
}
22+
EOF
23+
}
24+
25+
resource "aws_iam_user_policy_attachment" "lucy-admin-access" {
26+
user = aws_iam_user.admin-user.name
27+
policy_arn = aws_iam_policy.adminUser.arn
28+
}

Diff for: docs/terraform/files/aws/multiple-iam-users.tf

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# main.tf
2+
variable "dev-team" {
3+
type = list(string)
4+
default = ["lucy", "john", "jane"]
5+
}
6+
7+
resource "aws_iam_user" "admin-user" {
8+
name = var.dev-team[count.index]
9+
count = length(var.dev-team)
10+
tags = {
11+
Description = "Technical Team Leader"
12+
}
13+
}

Diff for: docs/terraform/files/aws/s3-bucket-object-group.tf

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
resource "aws_s3_bucket" "finance" {
2+
bucket = "finance-21092020"
3+
tags = {
4+
Name = "Finance and Payroll"
5+
}
6+
}
7+
8+
resource "aws_s3_object" "finance-2020" {
9+
content = "/root/finance/finance-2020.doc"
10+
key = "finance-2020.doc"
11+
bucket = aws_s3_bucket.finance.id # reference to the bucket
12+
}
13+
14+
data "aws_iam_group" "finance-data" {
15+
group_name = "finance-analysts"
16+
}
17+
18+
resource "aws_s3_bucket_policy" "finance-policy" {
19+
bucket = aws_s3_bucket.finance.id
20+
policy = <<EOF
21+
{
22+
"Version": "2012-10-17",
23+
"Statement": [
24+
{
25+
"Action": "*",
26+
"Effect": "Allow",
27+
"Resource": "arn:aws:s3:::${aws_s3_bucket.finance.id}/*",
28+
"Principal": {
29+
"AWS": ["${data.aws_iam_group.finance-data.arn}"
30+
]
31+
}
32+
}
33+
]
34+
}
35+
EOF
36+
}

Diff for: docs/terraform/files/count/main.tf

+15
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,19 @@ resource "local_file" "pet" {
66

77
output "pets" {
88
value = local_file.pet
9+
}
10+
11+
resource "local_file" "pets" {
12+
count = length(var.animals)
13+
content = "I love ${var.animals[count.index]}"
14+
filename = "./${var.animals[count.index]}.txt"
15+
}
16+
17+
18+
variable "animals" {
19+
default = [
20+
"rats",
21+
"dogs",
22+
"cats"
23+
]
924
}

Diff for: docs/terraform/files/test/cats.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
We love pets!

Diff for: docs/terraform/files/test/dogs.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
We love pets!

Diff for: docs/terraform/files/test/main.tf

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# local.tf
2+
resource "local_file" "pet" {
3+
for_each = var.files
4+
content = "We love pets!"
5+
filename = each.value
6+
}
7+
8+
# variables.tf
9+
variable "files" {
10+
default = {
11+
pets = "./pets.txt"
12+
dogs = "./dogs.txt"
13+
cats = "./cats.txt"
14+
}
15+
}

Diff for: docs/terraform/files/test/pets.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
We love pets!

Diff for: docs/terraform/introduction.md

+80-20
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ To deploy a resource using Terraform, there is four step process:
124124
3. **Planning**: Create an execution plan with `terraform plan` command to preview the changes that Terraform will make.
125125
4. **Apply**: Apply the changes with `terraform apply` command to create, update, or delete the resources as per the configuration.
126126

127-
So, let's se an example of creating a file locally with some content. First we need to create a configuration file:
127+
So, let's see an example of creating a file locally with some content. First we need to create a configuration file:
128128

129129
```hcl
130130
# local.tf
@@ -303,7 +303,7 @@ resource "random_pet" "my-pet" {
303303
}
304304
```
305305

306-
We can change list type to`number`, `bool`, or `any`. It will fail if we try to use a different type of value.
306+
We can change list type to `number`, `bool`, or `any`. It will fail if we try to use a different type of value.
307307

308308
Map:
309309

@@ -542,7 +542,7 @@ Terraform automatically manages resource dependencies based on the order of reso
542542

543543
Like we saw an an example above, the `random_pet` resource depends on the `local_file` resource. So, Terraform will create the `local_file` resource first and then create the `random_pet` resource. And when we destroy the resources, Terraform will destroy the `random_pet` resource first and then destroy the `local_file` resource.
544544

545-
1. **Explicit Dependencies**: But there are times where we don't don't use the attributes of other resources and we still want to create the resources in a specific order. Because they might be indirectly dependent on each other. In such cases, we can use the `depends_on` argument to define explicit dependencies between resources. A real life example of this is when we want to create a VPC and then create an EC2 instance in that VPC. We can use the `depends_on` argument to define the dependency between the resources.
545+
2. **Explicit Dependencies**: But there are times where we don't don't use the attributes of other resources and we still want to create the resources in a specific order. Because they might be indirectly dependent on each other. In such cases, we can use the `depends_on` argument to define explicit dependencies between resources. A real life example of this is when we want to create a VPC and then create an EC2 instance in that VPC. We can use the `depends_on` argument to define the dependency between the resources.
546546

547547
For our local file and random pet example, we can define the explicit dependency like this:
548548

@@ -634,7 +634,7 @@ Mutable infrastructure, servers and resources are updated or modified in place.
634634

635635
This approach can lead to configuration drift, security vulnerabilities, and inconsistencies between environments. It can also make it difficult to scale and manage large, complex environments.
636636

637-
### Mutable Infrastructure
637+
### Immutable Infrastructure
638638

639639
Immutable infrastructure, servers and resources are treated as disposable and are replaced with new instances when changes are required. Instead of updating existing servers, new servers are created with the desired configuration and the old servers are destroyed. This approach is common in cloud-native environments and is used to ensure consistency, reliability, and scalability.
640640

@@ -651,9 +651,9 @@ resource "local_file" "pet" {
651651
}
652652
```
653653

654-
#### Lifecycle Rules
654+
## Lifecycle Rules
655655

656-
Without License Rules, Terraform will destroy the old resource and create a new one. But with Lifecycle Rules, we can control the behavior of the resources. We can use `create_before_destroy` to create the new resource before destroying the old one. This can be useful when we want to avoid downtime or data loss.
656+
Without Lifecycle Rules, Terraform will destroy the old resource and create a new one. But with Lifecycle Rules, we can control the behavior of the resources. We can use `create_before_destroy` to create the new resource before destroying the old one. This can be useful when we want to avoid downtime or data loss.
657657

658658
```hcl
659659
# local.tf
@@ -740,6 +740,7 @@ The data read from data source is available under data object. We can use the da
740740

741741
### Resource vs Data Source
742742

743+
In simple words resources are used to create and manage infrastructure resources like EC2 instances, S3 buckets, and databases. Data sources are used to fetch information from external sources like APIs, databases, and other resources.
743744
![Resource vs Data Source](https://github.com/user-attachments/assets/44c291ea-6b98-4812-a40a-49a0ca9dd564)
744745

745746
## Meta-Arguments
@@ -761,7 +762,6 @@ resource "local_file" "pet" {
761762
filename = var.filenames[count.index]
762763
}
763764
764-
765765
variable "filenames" {
766766
default = [
767767
"/root/pets.txt",
@@ -771,9 +771,9 @@ variable "filenames" {
771771
}
772772
```
773773

774-
This will create three local files with filenames `pets-0.txt`, `pets-1.txt`, and `pets-2.txt`.
774+
This will create three local files with filenames `pets.txt`, `dogs.txt`, and `cats.txt`. We can use `count.index` to reference the index of the resource. The index starts from 0.
775775

776-
### For_each
776+
### For Each
777777

778778
The `for_each` meta-argument allows you to create multiple instances of a resource or data source based on a map or set of strings. It takes a map or set of strings and creates an instance of the resource or data source for each key or value in the map or set.
779779

@@ -936,16 +936,23 @@ Data is store in form of buckets. Everything under a bucket is an object. We can
936936

937937
![AWS S3](https://github.com/user-attachments/assets/d452bd9e-1851-4840-8177-32e8be7eb934)
938938

939-
Once the bucket is created we can access it via unique URL. We can also use the bucket to host static websites. it's in format of `http://<bucket-name>.<region>.amazonaws.com`. For eg. `http://my-bucket.s3.ap-south-1.amazonaws.com`.
939+
Once the bucket is created we can access it via unique URL. We can also use the bucket to host static websites. it's in format of `http://<bucket-name>.<region>.amazonaws.com`. For eg. `http://my-bucket.ap-south-1.amazonaws.com`.
940940

941-
We can access the files in the bucket using the URL `http://<bucket-name>.<region>.amazonaws.com/<object-key>`. For eg. `http://my-bucket.s3.ap-south-1.amazonaws.com/index.html`.
941+
We can access the files in the bucket using the URL `http://<bucket-name>.<region>.amazonaws.com/<object-key>`. For eg. `http://my-bucket.ap-south-1.amazonaws.com/image.jpg`.
942942

943943
![AWS S3 bucket](https://github.com/user-attachments/assets/3c7fa44c-3d3a-4b3f-b7bf-e2565be6bb79)
944944

945945
Any object stored in the bucket has the object data and the Metadata. The metadata contains information about the object like owner, size, last modified date, etc, in key-value pairs.
946946

947947
![AWS S3 object](https://github.com/user-attachments/assets/37c4c48a-011b-4fd5-8092-addcda8901e3)
948948

949+
### DynamoDB (NoSQL Database)
950+
951+
Amazon DynamoDB is a fully managed NoSQL database service that provides fast and predictable performance with seamless scalability. DynamoDB is highly scalable, single-digit millisecond latency, and fully managed.
952+
953+
Even tho it is NoSQL database, it has a table structure. Each table has a primary key that uniquely identifies each item in the table. We can use the AWS CLI to create, update, and delete DynamoDB tables. We can also use the AWS Management Console to manage DynamoDB tables.
954+
955+
![DynamoDB](https://github.com/user-attachments/assets/99b55a27-dab6-4a9f-b8ae-2790fe7590b7)
949956

950957
## AWS and Terraform
951958

@@ -965,7 +972,9 @@ resource "aws_iam_user" "admin-user" {
965972
Description = "Technical Team Leader"
966973
}
967974
}
975+
```
968976

977+
```bash
969978
# .aws/credentials
970979
[default]
971980
aws_access_key_id = AKIAIOSFODNN7EXAMPLE
@@ -976,7 +985,7 @@ Terraform will automatically use the credentials from the `~/.aws/credentials` f
976985

977986
```hcl
978987
provider "aws" {
979-
region = "us-east
988+
region = "us-east"
980989
profile = "default"
981990
}
982991
```
@@ -1004,14 +1013,13 @@ Attaching a policy to the IAM user:
10041013

10051014
```hcl
10061015
# main.tf
1007-
resource "aws_iam_user" "admin-user" {
1016+
resource "aws_iam_user" "admin-user
10081017
name = "lucy"
10091018
tags = {
10101019
Description = "Technical Team Leader"
10111020
}
1012-
}
10131021
1014-
resource "aws_iam_policy" "adminUser" {
1022+
resource "aws_iam_policy" "admin-user-policy" {
10151023
name = "AdminUsers"
10161024
policy = <<EOF
10171025
{
@@ -1029,11 +1037,11 @@ resource "aws_iam_policy" "adminUser" {
10291037
10301038
resource "aws_iam_user_policy_attachment" "lucy-admin-access" {
10311039
user = aws_iam_user.admin-user.name
1032-
policy_arn = aws_iam_policy.adminUser.arn
1040+
policy_arn = aws_iam_policy.admin-user-policy.arn
10331041
}
10341042
```
10351043

1036-
We use heredoc syntax to define the policy (`<<EOF`). We can use `terraform plan` to see the changes and `terraform apply` to apply the changes.
1044+
What we did is first we created an IAM user, then we created an IAM policy with full access to all the resources, and then we attached the policy to the IAM user. We use heredoc syntax to define the policy (`<<EOF`). It's not mandatory to use `EOF`, we can use any string. We can use `terraform plan` to see the changes and `terraform apply` to apply the changes.
10371045

10381046
![terraform apply](https://github.com/user-attachments/assets/3f661e06-dc17-4bc6-a829-810cb4fd9ca5)
10391047

@@ -1048,7 +1056,7 @@ resource "aws_iam_user" "admin-user" {
10481056
}
10491057
}
10501058
1051-
resource "aws_iam_policy" "adminUser" {
1059+
resource "aws_iam_policy" "admin-user-policy" {
10521060
name = "AdminUsers"
10531061
policy = file("policy.json")
10541062
}
@@ -1091,6 +1099,7 @@ resource "aws_iam_user" "admin-user" {
10911099
Description = "Technical Team Leader"
10921100
}
10931101
}
1102+
```
10941103

10951104
### S3
10961105

@@ -1105,7 +1114,7 @@ resource "aws_s3_bucket" "finance" {
11051114
}
11061115
}
11071116
1108-
resource "aws_s3_bucket_object" "finance-2020" {
1117+
resource "aws_s3_object" "finance-2020" {
11091118
content = "/root/finance/finance-2020.doc"
11101119
key = "finance-2020.doc"
11111120
bucket = aws_s3_bucket.finance.id # reference to the bucket
@@ -1136,4 +1145,55 @@ resource "aws_s3_bucket_policy" "finance-policy" {
11361145
}
11371146
```
11381147

1139-
Here, `aws_s3_bucket` resource is used to create an S3 bucket, `aws_s3_bucket_object` resource is used to upload a file to the bucket, and `aws_s3_bucket_policy` resource is used to create a bucket policy to allow access to the bucket. Additionally, we are using the `data` block to fetch information about an IAM group.
1148+
Here, `aws_s3_bucket` resource is used to create an S3 bucket, `aws_s3_bucket_object` resource is used to upload a file to the bucket, and `aws_s3_bucket_policy` resource is used to create a bucket policy to allow access to the bucket. Additionally, we are using the `data` block to fetch information about an IAM group.
1149+
1150+
:::Note
1151+
The bucket naming should not contain uppercase letters, underscores, or special characters. `ss_aa` is not allowed due to DNS compatibility.
1152+
:::
1153+
1154+
### DynamoDB
1155+
1156+
Here we are creating a DynamoDB table with a primary key and a sort key.
1157+
1158+
```hcl
1159+
# main.tf
1160+
resource "aws_dynamodb_table" "cars" {
1161+
name = "cars"
1162+
hash_key = "VIN"
1163+
billing_mode = "PAY_PER_REQUEST"
1164+
attribute {
1165+
name = "VIN"
1166+
type = "S"
1167+
}
1168+
}
1169+
1170+
Here `hash_key` is the primary key and `attribute` is the sort key. We can use `billing_mode` to specify the billing mode for the table. We can use `PAY_PER_REQUEST` for on-demand capacity mode and `PROVISIONED` for provisioned capacity mode. In the attribute block, we can specify the name and type of the attribute. Here we are using `S` for string type. We can also use `N` for number type and `B` for binary type.
1171+
1172+
To insert data into the table, we can use the `aws_dynamodb_table_item` resource.
1173+
1174+
```hcl
1175+
# main.tf
1176+
# main.tf
1177+
resource "aws_dynamodb_table" "cars" {
1178+
name = "cars"
1179+
hash_key = "VIN"
1180+
billing_mode = "PAY_PER_REQUEST"
1181+
attribute {
1182+
name = "VIN"
1183+
type = "S"
1184+
}
1185+
}
1186+
1187+
resource "aws_dynamodb_table_item" "car-items" {
1188+
table_name = aws_dynamodb_table.cars.name
1189+
hash_key = aws_dynamodb_table.cars.hash_key
1190+
item = <<EOF
1191+
{
1192+
"Manufacturer": {"S": "Toyota"},
1193+
"Model": {"S": "Corolla"},
1194+
"Year": {"N": "2020"},
1195+
"VIN": {"S": "JH4KA3240JC000000"}
1196+
}
1197+
EOF
1198+
}
1199+
```

0 commit comments

Comments
 (0)