Skip to content

Commit 9938394

Browse files
Enhance CodeGen
1 parent e28a50f commit 9938394

File tree

7 files changed

+519
-0
lines changed

7 files changed

+519
-0
lines changed
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
<p align="center">
2+
<img src="https://github.com/intel/terraform-intel-aws-vm/blob/main/images/logo-classicblue-800px.png?raw=true" alt="Intel Logo" width="250"/>
3+
</p>
4+
5+
# Intel® Optimized Cloud Modules for Terraform - Code Generation by OPEA on Intel® Xeon®
6+
7+
© Copyright 2024, Intel Corporation
8+
9+
10+
## AWS c7i EC2 Instance with 4th Generation Intel® Xeon® Scalable Processor (Sapphire Rapids) & Open Platform for Enterprise AI (OPEA) Code Generation Example
11+
12+
## Overview
13+
14+
This Module deploys the a Code Generation tool using the Open Platform for Enterprise AI Code Generation example on a Intel® Xeon® c7i AWS Instance. This is optimized for Intel® Advanced Matrix Extensions (AMX).
15+
16+
17+
This demo will showcase Code Generation CPU inference using 4th Gen Xeon Scalable Processors on AWS using the OPEA Code Generation. For more information about OPEA, go [here](https://opea.dev/). For more information on this specific example, go [here](https://github.com/opea-project/GenAIExamples/tree/main/CodeGen).
18+
19+
## Usage
20+
21+
### variables.tf
22+
23+
Modify the region to target a specific AWS Region
24+
25+
```hcl
26+
variable "region" {
27+
description = "Target AWS region to deploy EC2 in."
28+
type = string
29+
default = "us-east-1"
30+
}
31+
```
32+
33+
Modify the Huggingface Token variable to your specific Huggingface Token, for information on creating a Huggingface token go [here](https://huggingface.co/docs/hub/en/security-tokens)
34+
35+
```hcl
36+
variable "huggingface_token" {
37+
description = "Huggingface Token"
38+
default = " <YOUR HUGGINGFACE TOKEN> "
39+
type = string
40+
}
41+
```
42+
43+
### main.tf
44+
45+
Modify settings in this file to choose your AMI as well as instance size and other details around the instance that will be created
46+
47+
```hcl
48+
## Get latest Ubuntu 22.04 AMI in AWS for x86
49+
data "aws_ami" "ubuntu-linux-2204" {
50+
most_recent = true
51+
owners = ["099720109477"] # Canonical
52+
filter {
53+
name = "name"
54+
values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"]
55+
}
56+
filter {
57+
name = "virtualization-type"
58+
values = ["hvm"]
59+
}
60+
}
61+
62+
module "ec2-vm" {
63+
source = "intel/aws-vm/intel"
64+
key_name = aws_key_pair.TF_key.key_name
65+
instance_type = "c7i.24xlarge"
66+
availability_zone = "us-east-1a"
67+
ami = data.aws_ami.ubuntu-linux-2204.id
68+
user_data = data.cloudinit_config.ansible.rendered
69+
70+
root_block_device = [{
71+
volume_size = "500"
72+
}]
73+
74+
tags = {
75+
Name = "my-test-vm-${random_id.rid.dec}"
76+
Owner = "OwnerName-${random_id.rid.dec}",
77+
Duration = "2"
78+
}
79+
}
80+
```
81+
82+
Run the Terraform Commands below to deploy the demos.
83+
84+
```Shell
85+
terraform init
86+
terraform plan
87+
terraform apply
88+
```
89+
90+
## Running the Demo using AWS CloudShell
91+
92+
Open your AWS account and click the Cloudshell prompt
93+
At the command prompt enter in in these command prompts to install Terraform into the AWS Cloudshell
94+
95+
```Shell
96+
git clone https://github.com/tfutils/tfenv.git ~/.tfenv
97+
mkdir ~/bin
98+
ln -s ~/.tfenv/bin/* ~/bin/
99+
tfenv install 1.3.0
100+
tfenv use 1.3.0
101+
```
102+
103+
Download and run the [OPEA ChatQnA on Xeon](https://github.com/intel/terraform-intel-aws-vm/tree/main/examples/gen-ai-xeon-opea-codegen) Terraform Module by typing this command
104+
105+
```Shell
106+
git clone https://github.com/intel/terraform-intel-aws-vm.git
107+
```
108+
109+
Change into the `examples/gen-ai-xeon-opea-codegen` example folder
110+
111+
```Shell
112+
cd terraform-intel-aws-vm/examples/gen-ai-xeon-opea-codegen
113+
```
114+
115+
Run the Terraform Commands below to deploy the demos.
116+
117+
```Shell
118+
terraform init
119+
terraform plan
120+
terraform apply
121+
```
122+
123+
After the Terraform module successfully creates the EC2 instance, **wait ~10 minutes** for the recipe to build and launch the containers before continuing.
124+
125+
## Accessing the Demo
126+
127+
You can access the demos using the following:
128+
129+
- OPEA ChatQnA: `http://yourpublicip:5174`
130+
- You can also integrate with IDEs like VScode. See documentation [HERE](https://github.com/opea-project/GenAIExamples/blob/main/CodeGen/docker_compose/intel/cpu/xeon/README.md#install-copilot-vscode-extension-from-plugin-marketplace-as-the-frontend)
131+
132+
- Note: This module is created using the c7i.24xlarge instance size, you can change your instance type by modifying the **instance_type = "c7i.24xlarge"** in the main.tf under the **ec2-vm module** section of the code. If you just change to an 16xlarge and then run **terraform apply** the module will destroy the old instance and rebuild with a larger instance size.
133+
134+
## Deleting the Demo
135+
136+
To delete the demo, run `terraform destroy` to delete all resources created.
137+
138+
## Considerations
139+
140+
- The AWS region where this example is run should have a default VPC
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#cloud-config
2+
package_update: true
3+
package_upgrade: true
4+
5+
package:
6+
- git
7+
8+
runcmd:
9+
- apt install ansible -y
10+
- git clone https://github.com/intel/optimized-cloud-recipes.git /tmp/optimized-cloud-recipes
11+
- cd /tmp/optimized-cloud-recipes/recipes/ai-opea-codegen-xeon
12+
- cp opea.sh /etc/profile.d/opea.sh
13+
- echo 'export HUGGINGFACEHUB_API_TOKEN=${HUGGINGFACEHUB_API_TOKEN}' | sudo tee -a /etc/profile.d/opea.sh
14+
- chmod +x /etc/profile.d/opea.sh
15+
- source /etc/profile.d/opea.sh
16+
- ansible-playbook recipe.yml
17+
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# Provision EC2 Instance on Icelake on Amazon Linux OS in default vpc. It is configured to create the EC2 in
2+
# US-East-1 region. The region is provided in variables.tf in this example folder.
3+
4+
# This example also create an EC2 key pair. Associate the public key with the EC2 instance. Create the private key
5+
# in the local system where terraform apply is done. Create a new scurity group to open up the SSH port
6+
# 22 to a specific IP CIDR block
7+
8+
data "cloudinit_config" "ansible" {
9+
gzip = true
10+
base64_encode = true
11+
12+
part {
13+
filename = "cloud_init"
14+
content_type = "text/cloud-config"
15+
content = templatefile(
16+
"cloud_init.yml",
17+
{
18+
HUGGINGFACEHUB_API_TOKEN = var.huggingface_token
19+
}
20+
)
21+
}
22+
}
23+
24+
data "aws_ami" "ubuntu-linux-2204" {
25+
most_recent = true
26+
owners = ["099720109477"] # Canonical
27+
filter {
28+
name = "name"
29+
values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"]
30+
}
31+
filter {
32+
name = "virtualization-type"
33+
values = ["hvm"]
34+
}
35+
}
36+
37+
resource "random_id" "rid" {
38+
byte_length = 5
39+
}
40+
41+
# RSA key of size 4096 bits
42+
resource "tls_private_key" "rsa" {
43+
algorithm = "RSA"
44+
rsa_bits = 4096
45+
}
46+
47+
resource "aws_key_pair" "TF_key" {
48+
key_name = "TF_key-${random_id.rid.dec}"
49+
public_key = tls_private_key.rsa.public_key_openssh
50+
}
51+
52+
resource "local_file" "TF_private_key" {
53+
content = tls_private_key.rsa.private_key_pem
54+
filename = "tfkey.private"
55+
}
56+
resource "aws_security_group" "ssh_security_group" {
57+
description = "security group to configure ports for ssh"
58+
name_prefix = "ssh_security_group"
59+
}
60+
61+
# Modify the `ingress_rules` variable in the variables.tf file to allow the required ports for your CIDR ranges
62+
resource "aws_security_group_rule" "ingress_rules" {
63+
count = length(var.ingress_rules)
64+
type = "ingress"
65+
security_group_id = aws_security_group.ssh_security_group.id
66+
from_port = var.ingress_rules[count.index].from_port
67+
to_port = var.ingress_rules[count.index].to_port
68+
protocol = var.ingress_rules[count.index].protocol
69+
cidr_blocks = [var.ingress_rules[count.index].cidr_blocks]
70+
}
71+
72+
resource "aws_network_interface_sg_attachment" "sg_attachment" {
73+
count = length(module.ec2-vm)
74+
security_group_id = aws_security_group.ssh_security_group.id
75+
network_interface_id = module.ec2-vm[count.index].primary_network_interface_id
76+
}
77+
78+
# Modify the `vm_count` variable in the variables.tf file to create the required number of EC2 instances
79+
module "ec2-vm" {
80+
count = var.vm_count
81+
source = "intel/aws-vm/intel"
82+
key_name = aws_key_pair.TF_key.key_name
83+
instance_type = "c7i.24xlarge"
84+
availability_zone = "us-east-1d"
85+
ami = data.aws_ami.ubuntu-linux-2204.id
86+
user_data = data.cloudinit_config.ansible.rendered
87+
88+
root_block_device = [{
89+
volume_size = "500"
90+
}]
91+
92+
tags = {
93+
Name = "codegen-vm-${count.index}-${random_id.rid.dec}"
94+
Owner = "codegen-${random_id.rid.dec}",
95+
Duration = "1"
96+
}
97+
}
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
output "id" {
2+
description = "The ID of the instance"
3+
value = try(module.ec2-vm.*.id, module.ec2-vm.*.id, "")
4+
}
5+
6+
output "arn" {
7+
description = "The ARN of the instance"
8+
value = try(module.ec2-vm.*.arn, "")
9+
}
10+
11+
output "capacity_reservation_specification" {
12+
description = "Capacity reservation specification of the instance"
13+
value = try(module.ec2-vm.*.capacity_reservation_specification, "")
14+
}
15+
16+
output "instance_state" {
17+
description = "The state of the instance. One of: `pending`, `running`, `shutting-down`, `terminated`, `stopping`, `stopped`"
18+
value = try(module.ec2-vm.*.instance_state, "")
19+
}
20+
21+
output "outpost_arn" {
22+
description = "The ARN of the Outpost the instance is assigned to"
23+
value = try(module.ec2-vm.*.outpost_arn, "")
24+
}
25+
26+
output "password_data" {
27+
description = "Base-64 encoded encrypted password data for the instance. Useful for getting the administrator password for instances running Microsoft Windows. This attribute is only exported if `get_password_data` is true"
28+
value = try(module.ec2-vm.*.password_data, "")
29+
}
30+
31+
output "primary_network_interface_id" {
32+
description = "The ID of the instance's primary network interface"
33+
value = try(module.ec2-vm.*.primary_network_interface_id, "")
34+
}
35+
36+
output "private_dns" {
37+
description = "The private DNS name assigned to the instance. Can only be used inside the Amazon EC2, and only available if you've enabled DNS hostnames for your VPC"
38+
value = try(module.ec2-vm.*.private_dns, "")
39+
}
40+
41+
output "public_dns" {
42+
description = "The public DNS name assigned to the instance. For EC2-VPC, this is only available if you've enabled DNS hostnames for your VPC"
43+
value = try(module.ec2-vm.*.public_dns, "")
44+
}
45+
46+
output "public_ip" {
47+
description = "The public IP address assigned to the instance, if applicable. NOTE: If you are using an aws_eip with your instance, you should refer to the EIP's address directly and not use `public_ip` as this field will change after the EIP is attached"
48+
value = try(module.ec2-vm.*.public_ip, "")
49+
}
50+
51+
output "private_ip" {
52+
description = "The private IP address assigned to the instance."
53+
value = try(module.ec2-vm.*.private_ip, "")
54+
}
55+
56+
output "ipv6_addresses" {
57+
description = "The IPv6 address assigned to the instance, if applicable."
58+
value = try(module.ec2-vm.*.ipv6_addresses, [])
59+
}
60+
61+
output "tags_all" {
62+
description = "A map of tags assigned to the resource, including those inherited from the provider default_tags configuration block"
63+
value = try(module.ec2-vm.*.tags_all, {})
64+
}
65+
66+
output "spot_bid_status" {
67+
description = "The current bid status of the Spot Instance Request"
68+
value = try(module.ec2-vm.*.spot_bid_status, "")
69+
}
70+
71+
output "spot_request_state" {
72+
description = "The current request state of the Spot Instance Request"
73+
value = try(module.ec2-vm.*.spot_request_state, "")
74+
}
75+
76+
output "spot_instance_id" {
77+
description = "The Instance ID (if any) that is currently fulfilling the Spot Instance request"
78+
value = try(module.ec2-vm.*.spot_instance_id, "")
79+
}
80+
81+
################################################################################
82+
# IAM Role / Instance Profile
83+
################################################################################
84+
85+
output "iam_role_name" {
86+
description = "The name of the IAM role"
87+
value = try(module.ec2-vm.*.aws_iam_role.name, null)
88+
}
89+
90+
output "iam_role_arn" {
91+
description = "The Amazon Resource Name (ARN) specifying the IAM role"
92+
value = try(module.ec2-vm.*.aws_iam_role.arn, null)
93+
}
94+
95+
output "iam_role_unique_id" {
96+
description = "Stable and unique string identifying the IAM role"
97+
value = try(module.ec2-vm.*.aws_iam_role.unique_id, null)
98+
}
99+
100+
output "iam_instance_profile_arn" {
101+
description = "ARN assigned by AWS to the instance profile"
102+
value = try(module.ec2-vm.*.aws_iam_instance_profile.arn, null)
103+
}
104+
105+
output "iam_instance_profile_id" {
106+
description = "Instance profile's ID"
107+
value = try(module.ec2-vm.*.aws_iam_instance_profile.id, null)
108+
}
109+
110+
output "iam_instance_profile_unique" {
111+
description = "Stable and unique string identifying the IAM instance profile"
112+
value = try(module.ec2-vm.*.aws_iam_instance_profile.unique_id, null)
113+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
provider "aws" {
2+
# Environment Variables used for Authentication
3+
region = var.region
4+
}

0 commit comments

Comments
 (0)