AWS Lambda, SAM 및 Rust의 개인 노트
하고 싶은 게 이런 느낌이야.
Lightsail에 왜 데이터베이스 서버를 만들었는지는 돈의 문제입니다(´.ω・‘)
이번에 개인용 노트가 절반 정도밖에 남지 않아 내용을 이해하기 어렵다고 생각한다.양해해 주십시오
Rust 쪽은...
DB 연결 대상은 환경 변수에서 가져옵니다.또 이 프로그램은 무의미한 느낌을 준다.
Cargo.toml
필요 없는 기중기가 있을 수도 있어요.DB에 접근할 때 sqlx를 사용합니다.
[package]
name = "test-lambda"
version = "0.1.0"
authors = ["XXXXXXXX <[email protected]>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
aws_lambda_events = "0.4.0"
config = "0.11.0"
dotenv = "0.15.0"
http = "0.2.3"
lambda_http = "0.3.0"
lambda_runtime = "0.3.0"
lazy_static = "1.4.0"
log = "0.4.14"
serde = "1.0.124"
serde_derive = "1.0.124"
serde_json = "1.0.64"
simple_logger = "1.11.0"
sqlx = { version="0.5.1", features = ["runtime-tokio-rustls", "any", "postgres", "sqlite", "macros", "migrate", "chrono"] }
tokio = { version = "1.4.0", features = ["full"] }
[[bin]]
name = "bootstrap"
path = "src/main.rs"
config.rs
환경 변수에서 가져올 설정 정보(데이터베이스 연결 정보) 만들기
그러니까 완전 복사하고 붙이는 것도 지나치지 않아요.이것은 매우 얻기 어려운 보도다.
use serde::Deserialize;
use config::ConfigError;
use dotenv::dotenv;
use lazy_static::lazy_static;
#[derive(Deserialize, Debug)]
pub struct Config {
pub database_url: String,
}
impl Config {
/// 環境変数からデータを読み込む
pub fn from_env() -> Result<Self, ConfigError> {
let mut cfg = config::Config::new();
cfg.merge(config::Environment::new())?;
cfg.try_into()
}
}
lazy_static! {
pub static ref CONFIG: Config = {
dotenv().ok();
Config::from_env().unwrap()
};
}
main.rs
지난번과 달리'aws lambda 이벤트'를 사용했습니다.
APIGateway의 데이터 요청 및 응답에 대한 데이터 유형을 정의합니다.편리합니다!
사실 lambda.http라는 것도 있지만, 이쪽은 잘 움직이지 않아서 이 형식으로 변했다.
프로그램의 내용은 ApiGateway가 접근한 경로와 DB의 표 일람표를 되돌려주는 것입니다.
mod config;
use http::HeaderMap;
use lambda_runtime::{handler_fn, Context, Error};
use log::LevelFilter;
use serde_derive::Serialize;
use simple_logger::SimpleLogger;
use sqlx::{Any, AnyPool, Pool};
use crate::config::CONFIG;
use aws_lambda_events::event::apigw::{ApiGatewayProxyResponse, ApiGatewayProxyRequest };
#[derive(Serialize, Clone)]
struct CustomOutput {
path: String,
result: Vec<String>
}
#[tokio::main]
async fn main() -> Result<(), Error> {
SimpleLogger::new()
.with_level(LevelFilter::Info)
.init()
.unwrap();
let db_pool = AnyPool::connect(&CONFIG.database_url).await.unwrap();
let func = handler_fn(move |e, c| {
log::info!("lambda start---!!!");
my_handler(e, c, db_pool.clone())
});
lambda_runtime::run(func).await?;
Ok(())
}
async fn my_handler(req: ApiGatewayProxyRequest, _: Context, db_pool: Pool<Any>) -> Result<ApiGatewayProxyResponse, Error> {
let tables = db_access(&db_pool).await;
let x = CustomOutput {path: req.path.unwrap_or("".to_string()), result: tables};
let x = serde_json::to_string(&x).unwrap();
Ok(
ApiGatewayProxyResponse {
status_code: 200,
body: Some(x.into()),
is_base64_encoded: None,
headers: HeaderMap::new(),
multi_value_headers: HeaderMap::new()
}
)
}
async fn db_access(db_pool: &Pool<Any>) -> Vec<String> {
let sql = if CONFIG.database_url.starts_with("sqlite:") {
"select tbl_name from sqlite_master;"
} else {
"select table_name from information_schema.tables;"
};
sqlx::query_as::<_, (String,)>(sql)
.fetch_all(db_pool)
.await
.unwrap().into_iter().map(|i| i.0 ).collect()
}
스크립트 작성
나는 아래의 물건을 만들었다.
cross build --release --target x86_64-unknown-linux-musl
zip -j bootstrap.zip target/x86_64-unknown-linux-musl/release/bootstrap
AWS SAM에 대한 이야기
이번 구축은 구축 스크립트를 사용하기 때문에sam build 명령을 사용하지 않습니다.sambuild로 구축할 수 있는 방법도 있지만 처리에 오랜 시간이 걸렸고 제 환경에서도 불안정해서 사용을 포기했습니다.
template.yml
또한 Rust를 Lambda로 설계할 때 가장 중요한 것은
CodeUri: ./bootstrap.zip
Handler: bootstrap.is.real.handler
Runtime: provided.al2
의 부분.CodeUri에 작성된 zip 파일의 경로를 쓰고 Runtime에서provided를 사용합니다.AL2를 지정합니다.핸들러는 뭐든 될 것 같아서요.AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
sam-app
Sample SAM Template for sam-app
Parameters:
DataBaseURL:
Type: String
SecurityGroupIds:
Type: CommaDelimitedList
SubnetIds:
Type: CommaDelimitedList
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 3
Environment:
Variables:
DATABASE_URL: !Ref DataBaseURL
VpcConfig:
SecurityGroupIds: !Ref SecurityGroupIds
SubnetIds: !Ref SubnetIds
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
FunctionName: HelloRust
CodeUri: ./bootstrap.zip
Handler: bootstrap.is.real.handler
Runtime: provided.al2
Role: !GetAtt LambdaRole.Arn
Events:
ProxyApi:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /test/{proxy+}
Method: ANY
HelloWorldFunctionLogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Sub /aws/lambda/${HelloWorldFunction}
RetentionInDays: 30
LambdaRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: "sts:AssumeRole"
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
samconfig.toml
처음에sam deploy-guided 명령으로 적절하게 디버깅한 내용을 약간 수정하고 있습니다.
parameter_오버라이드에 실제 설정을 기록합니다.(이번에는 VPC 설정 및 데이터베이스 연결 정보)
version = 0.1
[default]
[default.deploy]
[default.deploy.parameters]
stack_name = "sam-app"
s3_bucket = "[みせられないよ!!]"
s3_prefix = "sam-app"
region = "ap-northeast-1"
capabilities = "CAPABILITY_IAM"
parameter_overrides = "DataBaseURL=postgresql://xxxxx:[email protected]/postgres SecurityGroupIds=sg-xxxxxxxx SubnetIds=subnet-xxxxxa,subnet-xxxxxb,subnet-xxxxxc"
프로그램 정보
일반적으로 Rust의 구축을 하고sam deploy로 설계를 한다.겨우 스파로 만들어져서 처음 했을 때 감동적이었어요.
기타
저는 Serverless Framework에도 관심이 많아서 한번 써보려고 했는데 Serverless Rust 쓰고 갔지만 빌딩에서 실패할 수가 없어서 전진할 수가 없었어요...
Reference
이 문제에 관하여(AWS Lambda, SAM 및 Rust의 개인 노트), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/upopon/articles/1ac382bbd3e217텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)