Skip to content

Commit

Permalink
Merge pull request #232 from sfeir-open-source/aws-lab-03
Browse files Browse the repository at this point in the history
Add aws lab 03 : first infrastructure deployment
  • Loading branch information
Tibeno88 authored Nov 22, 2024
2 parents 3ce57c5 + eac051f commit 97b1e07
Show file tree
Hide file tree
Showing 18 changed files with 275 additions and 3 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ typings/

#Dev
docs/test.html
.terraform/
.terraform*
terraform.tfstate.d/
terraform.tfstate
terraform.tfstate.backup
Expand Down
6 changes: 4 additions & 2 deletions steps/aws/02-installation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Cloud Shell provides an integrated terminal where you can execute commands and p

We will use tenv, the terraform version manager to install the latest version of terraform in your home directory.

First, clone tfenv project and make a symlink to include the script bin in your *$PATH* :
First, clone tenv project and make a symlink to include the script bin in your *$PATH* :

```console
$ curl -L https://github.com/tofuutils/tenv/releases/download/v1.7.1/tenv_v1.7.1_386.rpm -o tenv_v1.7.1_386.rpm && sudo yum install tenv_v1.7.1_386.rpm -y && rm tenv_v1.7.1_386.rpm
Expand Down Expand Up @@ -62,6 +62,7 @@ Set up these credentials as environment variables so that you can authenticate w
$ export AWS_ACCESS_KEY_ID=YOURAWSACCESSKEYID
$ export AWS_SECRET_ACCESS_KEY=YOURAWSSECRETACCESSKEY
```

Or you can use the AWS cli to configure your credentials.
Prior to configure your credentials, you will have to install the [AWS cli](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
After the installation you can use
Expand Down Expand Up @@ -106,7 +107,7 @@ Clone this repository on the Cloud Shell.
$ git clone https://github.com/sfeir-open-source/sfeir-school-terraform.git
```

Go in `steps/02-installation-solution/`
Go in `steps/02-installation/`

Initialize a new terraform environment and deploy the infrastructure :

Expand All @@ -127,3 +128,4 @@ Outputs:

message = "Hello World"
```

48 changes: 48 additions & 0 deletions steps/aws/03-first-infrastructure-deployment/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Sfeir Institute Terraform

## Module-3a: First Infrastructure Deployment

### Provider configuration

Official Terraform AWS provider documentation can be found on [the terraform's registry website](https://registry.terraform.io/providers/hashicorp/aws/latest/docs).

Depending on where you are running terraform, the provider needs AWS credentials to access the AWS Cloud (see Step "Installation" README).

### Your first AWS EC2 instance (aws_instance)

Create a simple AWS instance located in the default VPC, using the following settings :

| Property | Value |
| - | - |
| Name | First Instance |
| Zone | eu-west-1a |
| Machine | t2.micro |
| Image | Last ubuntu server 22.04 LTS amd64 |
| Public IP address | Yes |


Tip : To configure the Amazon Machine Image on the instance, you will have to use a datasource to get the AMI's id. You can search in the AWS console's AMI catalog to get the AMI name to configure the datasource.

To find all resource attributes, you can search in the aws provider's documentation by following the link provided above.


### Allow SSH access to your first instance (aws_security_group)

In order to connect to your instance remotely with SSH, create an *aws_security_group* resource that will allow inbound SSH access on port 22 to your instance. Associate the newly created security group to your *aws_instance*.

To connect to your instance, you will have to use an *aws_key_pair* resource bound to your aws_instance. Save the private key file locally to use it to connect to your instance (see *local_file* resource type to do that)

### Deploy

Using `terraform init`, terraform will automatically download the [terraform-provider-aws](https://github.com/hashicorp/terraform-provider-aws) required to deploy the infrastructure on Amazon Web Services cloud.

Run a `terraform plan` to view changes.
If changes are correct, use `terraform apply` to deploy resources.

### Result

After executing your deployment, all your resources should be up and functional. Your AWS instance should be accessible through SSH from your public IP.

### Cleanup

Once lab is completed, use `terraform destroy` to remove resources managed by Terraform
8 changes: 8 additions & 0 deletions steps/aws/03-first-infrastructure-deployment/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

terraform {
required_version = ">= 0.12"
}

resource "aws_instance" "my_instance" {
# Configure your instance
}
4 changes: 4 additions & 0 deletions steps/aws/03-first-infrastructure-deployment/provider.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Configure AWS Provider
provider "aws" {
region = "eu-west-1"
}
59 changes: 59 additions & 0 deletions steps/aws/03-first-infrastructure-deployment/solution/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@

terraform {
required_version = ">= 0.12"
}

data "aws_ami" "ubuntu" {
most_recent = true
owners = ["amazon"]

filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server*"]
}
}

resource "aws_security_group" "allow_ssh" {
name = "allow_ssh"
description = "Allow SSH inbound traffic"

ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["193.39.2.69/32"] # Be cautious with this setting - set only your public IP
}
}

resource "aws_instance" "my_instance" {
ami = data.aws_ami.ubuntu.id
instance_type = "t2.micro"
availability_zone = var.availability_zone

associate_public_ip_address = true

key_name = aws_key_pair.my_key_pair.key_name

security_groups = [ aws_security_group.allow_ssh.name ]

tags = {
Name = var.instance_name
}
}

# Generate a new SSH key pair locally or use an existing key
resource "tls_private_key" "my_private_key" {
algorithm = "RSA"
rsa_bits = 2048
}

resource "aws_key_pair" "my_key_pair" {
key_name = "my_key"
public_key = tls_private_key.my_private_key.public_key_openssh
}

resource "local_file" "private_key_pem" {
filename = "${path.module}/private_key.pem"
content = tls_private_key.my_private_key.private_key_pem
file_permission = "0600"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# SSH connection command to connect to the instance
output "ssh_connection_command" {
value = "ssh -i ${local_file.private_key_pem.filename} ubuntu@${aws_instance.my_instance.public_ip}"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Configure AWS Provider
provider "aws" {
region = "eu-west-1"
}
11 changes: 11 additions & 0 deletions steps/aws/03-first-infrastructure-deployment/solution/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
variable "availability_zone" {
type = string
description = "AWS availability zone"
default = "eu-west-1a"
}

variable "instance_name" {
type = string
description = "AWS Instance name"
default = "myinstance"
}
24 changes: 24 additions & 0 deletions steps/aws/04-interpolations-looping-and-conditions/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Sfeir Institute Terraform

## Module-3b: Interpolations, looping and conditions

### Objective

As a user, I would like to push 2 configurations files in cloud storage in order to create VMs using *startup-script-url*.

Do it using :

* the old way (using count terraform 0.11)
* Using new terraform 0.12 for\_each way.

=> All buckets must have versioning enabled (see *aws_s3_bucket_versioning* resource)

*Hints* : Refer to *aws_s3_bucket* to create buckets and to put objects.

| Property | Value |
| - | - |
| bucket\_name | `user_defined` |

Once the 4 objects are created using example configurations (2 with `count`, 2 with `for_each`), add a new config file `"config-pp" = "env = pp"` in `variables.tf`.

What's happened when you run `terraform plan` again ?
19 changes: 19 additions & 0 deletions steps/aws/04-interpolations-looping-and-conditions/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
terraform {
required_version = ">= 0.12.0"
}

resource "aws_s3_bucket" "config_bucket" {
bucket = var.bucket_name
}

## Since 0.12
resource "aws_s3_object" "for_each_bucket" {
// Put all files contained in var.files in AWS S3 using for_each (add -for suffix in the file name)
for_each = var.files
}

## Before 0.12
resource "aws_s3_object" "count_bucket" {
// Put all files contained in var.files in AWS S3 using count (add -count suffix in the file name)
count = length(keys(var.files))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Configure AWS Provider
provider "aws" {
region = "eu-west-1"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
terraform {
required_version = ">= 0.12"
}

resource "aws_s3_bucket" "config_bucket" {
bucket = var.bucket_name
}

resource "aws_s3_bucket_versioning" "example" {
bucket = aws_s3_bucket.config_bucket.id
versioning_configuration {
status = "Enabled"
}
}

## Since 0.12
resource "aws_s3_object" "for_each_bucket" {
// Put all files contained in var.files in AWS S3 using for_each (add -for suffix in the file name)
for_each = var.files
key = format("%s-for", lower(each.key))
content = each.value
bucket = aws_s3_bucket.config_bucket.id
}

## Before 0.12
resource "aws_s3_object" "count_bucket" {
// Put all files contained in var.files in cloud storage using count (add -count suffix in the file name)
count = length(keys(var.files))
key = format("%s-count", element(keys(var.files), count.index))
content = var.files[element(keys(var.files), count.index)]
bucket = aws_s3_bucket.config_bucket.id
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Configure AWS Provider
provider "aws" {
region = "eu-west-1"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
variable "bucket_name" {
type = string
description = "Name of the S3 bucket"
}

variable "files" {
type = map(string)
description = "Map of files to create where key is filename and value is file content"

default = {
# "filename" = "file_content"
# "config-pp" = "env = pp" ## should be added after a first "apply"
"config-prod" = "env = prod"
"config-dev" = "env = dev"
"config-pp" = "env = pp"
}
}
17 changes: 17 additions & 0 deletions steps/aws/04-interpolations-looping-and-conditions/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
variable "bucket_name" {
type = string
description = "Name of the S3 bucket"
default = "mybucket"
}

variable "files" {
type = map(string)
description = "Map of files to create where key is filename and value is file content"

default = {
# "filename" = "file_content"
# "config-pp" = "env = pp" ## should be added after a first "apply"
"config-prod" = "env = prod"
"config-dev" = "env = dev"
}
}
10 changes: 10 additions & 0 deletions steps/gcp/02-installation-solution/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
resource "null_resource" "check-version" {
triggers = {
message = "Hello World"
}
}

output "message" {
description = "A message to display"
value = null_resource.check-version.triggers.message
}
4 changes: 4 additions & 0 deletions steps/gcp/02-installation-solution/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

terraform {
required_version = ">= 0.12"
}

0 comments on commit 97b1e07

Please sign in to comment.