main.tf 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. # Minimal Amazon SageMaker Terraform configuration for Llama deployment
  2. # This creates only the essential resources for SageMaker model deployment
  3. terraform {
  4. required_version = ">= 1.0"
  5. required_providers {
  6. aws = {
  7. source = "hashicorp/aws"
  8. version = "~> 5.0"
  9. }
  10. }
  11. }
  12. provider "aws" {
  13. region = var.aws_region
  14. }
  15. # Data sources
  16. data "aws_caller_identity" "current" {}
  17. data "aws_region" "current" {}
  18. # Local values
  19. locals {
  20. account_id = data.aws_caller_identity.current.account_id
  21. region = data.aws_region.current.name
  22. name_prefix = "${var.project_name}-${var.environment}"
  23. }
  24. # S3 bucket for model artifacts (required for SageMaker)
  25. resource "aws_s3_bucket" "model_artifacts" {
  26. bucket = "${local.name_prefix}-model-artifacts-${random_id.bucket_suffix.hex}"
  27. tags = {
  28. Name = "${local.name_prefix}-model-artifacts"
  29. Environment = var.environment
  30. ManagedBy = "Terraform"
  31. }
  32. }
  33. resource "random_id" "bucket_suffix" {
  34. byte_length = 4
  35. }
  36. resource "aws_s3_bucket_public_access_block" "model_artifacts" {
  37. bucket = aws_s3_bucket.model_artifacts.id
  38. block_public_acls = true
  39. block_public_policy = true
  40. ignore_public_acls = true
  41. restrict_public_buckets = true
  42. }
  43. # IAM role for SageMaker execution
  44. resource "aws_iam_role" "sagemaker_execution_role" {
  45. name = "${local.name_prefix}-sagemaker-role"
  46. assume_role_policy = jsonencode({
  47. Version = "2012-10-17"
  48. Statement = [
  49. {
  50. Action = "sts:AssumeRole"
  51. Effect = "Allow"
  52. Principal = {
  53. Service = "sagemaker.amazonaws.com"
  54. }
  55. }
  56. ]
  57. })
  58. tags = {
  59. Name = "${local.name_prefix}-sagemaker-role"
  60. Environment = var.environment
  61. ManagedBy = "Terraform"
  62. }
  63. }
  64. # IAM policy for SageMaker execution (minimal permissions)
  65. resource "aws_iam_role_policy" "sagemaker_policy" {
  66. name = "${local.name_prefix}-sagemaker-policy"
  67. role = aws_iam_role.sagemaker_execution_role.id
  68. policy = jsonencode({
  69. Version = "2012-10-17"
  70. Statement = [
  71. {
  72. Effect = "Allow"
  73. Action = [
  74. "s3:GetObject",
  75. "s3:ListBucket"
  76. ]
  77. Resource = [
  78. aws_s3_bucket.model_artifacts.arn,
  79. "${aws_s3_bucket.model_artifacts.arn}/*",
  80. "arn:aws:s3:::llama-model-demo-bucket",
  81. "arn:aws:s3:::llama-model-demo-bucket/*"
  82. ]
  83. },
  84. {
  85. Effect = "Allow"
  86. Action = [
  87. "ecr:GetAuthorizationToken",
  88. "ecr:BatchCheckLayerAvailability",
  89. "ecr:GetDownloadUrlForLayer",
  90. "ecr:BatchGetImage"
  91. ]
  92. Resource = "*"
  93. },
  94. {
  95. Effect = "Allow"
  96. Action = [
  97. "logs:CreateLogGroup",
  98. "logs:CreateLogStream",
  99. "logs:PutLogEvents"
  100. ]
  101. Resource = "arn:aws:logs:${local.region}:${local.account_id}:*"
  102. }
  103. ]
  104. })
  105. }
  106. # SageMaker model
  107. resource "aws_sagemaker_model" "llama_model" {
  108. name = "${local.name_prefix}-llama-model"
  109. execution_role_arn = aws_iam_role.sagemaker_execution_role.arn
  110. primary_container {
  111. image = var.model_image_uri
  112. model_data_url = var.model_data_s3_path
  113. environment = {
  114. SAGEMAKER_PROGRAM = "inference.py"
  115. SAGEMAKER_SUBMIT_DIRECTORY = "/opt/ml/code"
  116. MODEL_NAME = var.model_name
  117. HF_TASK = "text-generation"
  118. }
  119. }
  120. tags = {
  121. Name = "${local.name_prefix}-llama-model"
  122. Environment = var.environment
  123. ManagedBy = "Terraform"
  124. }
  125. }
  126. # SageMaker endpoint configuration
  127. resource "aws_sagemaker_endpoint_configuration" "llama_config" {
  128. name = "${local.name_prefix}-llama-config-${random_id.config_suffix.hex}"
  129. production_variants {
  130. variant_name = "primary"
  131. model_name = aws_sagemaker_model.llama_model.name
  132. initial_instance_count = var.initial_instance_count
  133. instance_type = var.instance_type
  134. initial_variant_weight = 1
  135. }
  136. tags = {
  137. Name = "${local.name_prefix}-llama-config"
  138. Environment = var.environment
  139. ManagedBy = "Terraform"
  140. }
  141. lifecycle {
  142. create_before_destroy = true
  143. }
  144. }
  145. resource "random_id" "config_suffix" {
  146. byte_length = 4
  147. }
  148. # SageMaker endpoint
  149. resource "aws_sagemaker_endpoint" "llama_endpoint" {
  150. name = "${local.name_prefix}-llama-endpoint"
  151. endpoint_config_name = aws_sagemaker_endpoint_configuration.llama_config.name
  152. tags = {
  153. Name = "${local.name_prefix}-llama-endpoint"
  154. Environment = var.environment
  155. ManagedBy = "Terraform"
  156. }
  157. }